[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: Create a report to help us improve\ntitle: \"[BUG] - Issue Title\"\nlabels: bug\n\nbody:\n  - type: markdown\n    attributes:\n      value: \"## Describe the bug\\nA clear and concise description of what the bug is.\"\n\n  - type: textarea\n    attributes:\n      label: Steps to Reproduce\n      description: \"List the steps to reproduce the bug.\"\n      placeholder: \"1. Go to '...'\\n2. Click on '...'\\n3. See error\"\n\n  - type: textarea\n    attributes:\n      label: Expected Behavior\n      description: \"Describe the behavior you expected to see.\"\n      placeholder: \"A clear and concise description of what you expected to happen.\"\n\n  - type: input\n    attributes:\n      label: Servicecomb Version\n      description: \"Please provide your Servicecomb version\"\n      placeholder: \"3.2.4\"\n\n  - type: textarea\n    attributes:\n      label: Additional Context\n      description: \"Add any other context about the problem here.\"\n      placeholder: \"Any additional information that might help us debug the issue.\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: \"Contact Support\"\n    url: \"mailto:dev@servicecomb.apache.org\"\n    about: \"If you need help, please contact us.\"\ntemplates:\n  - name: \"Bug Report\"\n    description: \"Report a bug or issue.\"\n    filename: \"bug_report.yml\"\n  - name: \"Feature Request\"\n    description: \"Request a new feature or improvement.\"\n    filename: \"feature_request.yml\"\n  - name: \"Documentation Issue\"\n    description: \"Report an issue with documentation.\"\n    filename: \"documentation_issue.yml\"\n  - name: \"Question\"\n    description: \"Ask a question or seek help.\"\n    filename: \"question.yml\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation_issue.yml",
    "content": "name: Documentation Issue\ndescription: Report an issue with the documentation\ntitle: \"[DOCUMENTATION] - Documentation Issue Title\"\nlabels: documentation\n\nbody:\n  - type: markdown\n    attributes:\n      value: \"## Describe the documentation issue\\nA clear and concise description of the issue with the documentation.\"\n\n  - type: textarea\n    attributes:\n      label: Location in documentation\n      description: \"Please provide the URL or section where the issue appears.\"\n      placeholder: \"e.g. https://docs.example.com/section\"\n\n  - type: textarea\n    attributes:\n      label: What should be changed?\n      description: \"Please describe what changes or improvements should be made to the documentation.\"\n      placeholder: \"Explain how we can improve the content.\"\n\n  - type: textarea\n    attributes:\n      label: Additional Context\n      description: \"Provide any other context or examples here.\"\n      placeholder: \"Additional comments or suggestions for the documentation.\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "content": "name: Feature Request\ndescription: Suggest an idea or feature for this project\ntitle: \"[FEATURE] - Feature Title\"\nlabels: enhancement\n\nbody:\n  - type: markdown\n    attributes:\n      value: \"## Describe the feature request\\nA clear and concise description of what you want to be added to the project.\"\n\n  - type: textarea\n    attributes:\n      label: Problem this feature would solve\n      description: \"Please describe the problem or challenge you're facing.\"\n      placeholder: \"Explain why this feature would be helpful.\"\n\n  - type: textarea\n    attributes:\n      label: Describe the solution\n      description: \"How do you envision this feature working?\"\n      placeholder: \"Provide a description of how the feature would solve the problem.\"\n\n  - type: textarea\n    attributes:\n      label: Alternatives considered\n      description: \"Have you considered other solutions or alternatives? If yes, describe them.\"\n      placeholder: \"Provide any alternative solutions you've thought about.\"\n\n  - type: textarea\n    attributes:\n      label: Additional Context\n      description: \"Any other context or information that might help us implement this feature.\"\n      placeholder: \"Include any links, mockups, or additional details.\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.yml",
    "content": "name: General Question\ndescription: Ask a general question related to the project\ntitle: \"[QUESTION] - Question Title\"\nlabels: question\n\nbody:\n  - type: markdown\n    attributes:\n      value: \"## What is your question?\\nDescribe the question or issue you are facing. Be as specific as possible.\"\n\n  - type: textarea\n    attributes:\n      label: Steps to reproduce (if applicable)\n      description: \"If your question is about a specific problem or bug, please include steps to reproduce it.\"\n      placeholder: \"Provide steps, if applicable.\"\n\n  - type: textarea\n    attributes:\n      label: What have you tried so far?\n      description: \"Please explain what you have already tried to resolve the issue or answer the question.\"\n      placeholder: \"Describe the steps you've taken.\"\n\n  - type: textarea\n    attributes:\n      label: Additional context\n      description: \"Provide any other context or information related to the question.\"\n      placeholder: \"Include any relevant links or background information.\"\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Follow this checklist to help us incorporate your contribution quickly and easily:\n\n - [ ] Make sure there is a [JIRA issue](https://issues.apache.org/jira/browse/SCB) filed for the change (usually before you start working on it).  Trivial changes like typos do not require a JIRA issue.  Your pull request should address just this issue, without pulling in other changes.\n - [ ] Each commit in the pull request should have a meaningful subject line and body.\n - [ ] Format the pull request title like `[SCB-XXX] Fixes bug in ApproximateQuantiles`, where you replace `SCB-XXX` with the appropriate JIRA issue.\n - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.\n - [ ] Run `mvn clean install -Pit` to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.\n - [ ] If this contribution is large, please file an Apache [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).\n\n---\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\nversion: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n  - package-ecosystem: \"maven\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n    open-pull-requests-limit: 20\n"
  },
  {
    "path": ".github/workflows/checkstyle.yml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\nname: checkstyle\non:\n  pull_request:\n    branches:\n      - master\n\njobs:\n  checkstyle:\n    timeout-minutes: 60\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Set up jdk\n        uses: actions/setup-java@v5\n        with:\n          java-version: '17'\n          distribution: 'temurin'\n      - name: checkstyle\n        run: mvn checkstyle:check -B -Pit\n"
  },
  {
    "path": ".github/workflows/linelint.yml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\nname: line lint\non:\n  pull_request:\n    branches:\n      - master\n\njobs:\n  linelint:\n    timeout-minutes: 60\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: install linelint\n        run: cargo install linelint-cli\n      - name: Run linelint check\n        run: linelint check\n"
  },
  {
    "path": ".github/workflows/maven.yml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\nname: Java CI with Maven\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n\n    timeout-minutes: 60\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v6\n    - name: Set up jdk\n      uses: actions/setup-java@v5\n      with:\n       java-version: '17.0.8'\n       distribution: 'temurin'\n    - name: Set up Maven\n      uses: stCarolas/setup-maven@v5\n      with:\n        maven-version: 3.9.9\n    - uses: actions/cache@v5\n      with:\n        path: ~/.m2/repository\n        key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}\n        restore-keys: |\n          ${{ runner.os }}-maven-\n    - name: Compilation and Installation\n      run: mvn clean verify -Dcheckstyle.skip=true -B -Pdocker -Pjacoco -Pit -Pcoverage\n"
  },
  {
    "path": ".github/workflows/rat_check.yml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\nname: rat check\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n\njobs:\n  rat_check:\n    timeout-minutes: 60\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Set up jdk\n        uses: actions/setup-java@v5\n        with:\n          java-version: '17'\n          distribution: 'temurin'\n      - name: rat check\n        run: mvn apache-rat:check -B -Pit,release\n"
  },
  {
    "path": ".github/workflows/typo_check.yml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\nname: typo check\non:\n  pull_request:\n    branches:\n      - master\n\njobs:\n  typo-check:\n    timeout-minutes: 60\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n        # To run the typo check locally, you can follow these steps:\n        # 1. Install typos locally using cargo:\n        #    cargo install typos-cli\n        # 2. Run the typo check with the following command:\n        #    typos\n      - name: Check typos\n        uses: crate-ci/typos@v1.38.1\n"
  },
  {
    "path": ".gitignore",
    "content": "# Output Directory\ntarget/\n\n# C pre-compile\n*.gch\n*.pch\n\n# C compile\n*.a\n*.o\n*.ko\n*.la\n*.lo\n*.obj\n*.elf\n*.so\n*.so.*\n*.dylib\n*.exe\n*.lib\n*.dll\n*.out\n*.app\n*.hex\n\n# Debug files\n*.dSYM/\n\n# Java\n*.class\n\n# Java Package Files\n*.jar\n*.war\n*.ear\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n# Zip Files\n*.rar\n*.zip\n*.7z\n*.tar\n*.gz\n\n# Ant\nbuild/\n\n# Compiled Python\n__pycache__/\n*.py[cod]\n*py.class\n\n# Eclipse\n.settings/\n.classpath\n.project\n\n# IntelliJ, based on http://devnet.jetbrains.net/docs/DOC-1186\n.idea/\n*.iml\n*.ipr\n*.iws\n\n# logs and trace\n*.log\n*.trace\n*.dat\n\n# vi swap\n*.swp\n\n# Backup Files\n*.bak\n*.old\n\n# SVN metadata\n.svn/\n\n# Mac\n.DS_Store\n\n# gradle\n.gradle\n"
  },
  {
    "path": ".typos.toml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n\n[default.extend-words]\n\"fo\" = \"fo\"\n\"VERTX\" = \"VERTX\"\n\"Vertx\" = \"Vertx\"\n\"vertx\" = \"vertx\"\n\n[files]\nextend-exclude = [\n    \"**/cobertura.ser\"\n]\n[default]\nextend-ignore-words-re = [\n    \"Verticle\",\n    \"verticle\",\n    \"VERTICLE\",\n    \"Prelease\",\n    \"cobertura\",\n    \"ser\",\n]\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n=======================================================================\nApache ServiceComb Java Chassis Subcomponents:\n\nThe Apache ServiceComb Java Chassis project contains subcomponents with\nseparate copyright notices and license terms. Your use of the source\nfor these subcomponents is subject to the terms and conditions of the\nfollowing licenses.\n\n\n================================================================\nFor foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/MimeTypesUtils.java\n    transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java\n================================================================\nThis product bundles files from vertx which is licensed under the Apache License v2.\nFor details, see https://github.com/vert-x3/vertx-web\n\n================================================================\nFor swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/AbstractBaseIntegerProperty.java\n================================================================\nThis product bundles files from swagger which is licensed under the Apache License v2.\nFor details, see https://github.com/swagger-api/swagger-core\n\n================================================================\nFor foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/ArrayFieldMapEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldMapEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldSchema.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldTypeUtils.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/HashFieldMapEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/ByteArrayInputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/InputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/OutputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/package-info.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaReader.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaWriter.java\n================================================================\nThis product bundles files from protostuff which is licensed under the Apache License v2.\nFor details, see  https://github.com/protostuff/protostuff\n\n================================================================\nFor foundations/foundation-protobuf/src/main/resources/google/protobuf/any.proto\nFor foundations/foundation-protobuf/src/main/resources/google/protobuf/empty.proto\n================================================================\nThis product bundles files from swagger which is licensed under the BSD-3-Clause.\nFor details, see https://github.com/protocolbuffers/protobuf\n"
  },
  {
    "path": "NOTICE",
    "content": "Apache ServiceComb Java Chassis\nCopyright 2017-2025 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "README.md",
    "content": "# Java Chassis [中文](README_ZH.md) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.servicecomb/java-chassis-core/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Corg.apache.servicecomb) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\nApache ServiceComb Java Chassis is a Software Development Kit (SDK) for rapid development of microservices in Java, providing service registration, service discovery, dynamic routing, and service management features.\n\n> If you find this project helpful, please don't forget to `star` it.\n\n# releases\n\n| Release Train  | Latest Version | Compiled JDK Version | Tested JDK Version | Open API | Notes                    |\n|----------------|----------------|----------------------|--------------------|----------|--------------------------|\n| Java Chassis 3 | 3.3.0          | OpenJDK 17           | OpenJDK 17         | 3.0.x    | Depends on Spring Boot 3 |\n| Java Chassis 2 | 2.8.24         | OpenJDK 8            | OpenJDK 8, 11, 17  | 2.0.x    | Depends on Spring 5      |\n| Java Chassis 1 | 1.3.11         | OpenJDK 8            | OpenJDK 8          | 2.0.x    | End of Support           |\n\nJava Chassis core dependencies\n\n| Java Chassis | Spring Boot | Vert.x | Swagger | Jackson |\n|--------------|-------------|--------|---------|---------|\n| 3.3.x        | 3.4.x       | 4.5.x  | 2.2.x   | 2.18.x  |\n| 3.2.x        | 3.3.x       | 4.5.x  | 2.2.x   | 2.18.x  |\n\n> NOTICE: Since Open API 3.0.x is not compatible with 2.0.x, Java Chassis 2 and Java Chassis 1 can not\n> work together with Java Chassis 3. All related consumers, providers and edge service need use Java Chassis 3 when upgrading.\n\n> NOTICE: Java Chassis 1 reached its end of support now after it's first release from 2018.\n\n# Quick Start\n\n* Define API\n```java\n@RequestMapping(path = \"/provider\")\npublic interface ProviderService {\n  @GetMapping(\"/sayHello\")\n  String sayHello(@RequestParam(\"name\") String name);\n}\n```\n\n* Provider service\n```java\n@RestSchema(schemaId = \"ProviderController\", schemaInterface = ProviderService.class)\npublic class ProviderController implements ProviderService {\n  @Override\n  public String sayHello(String name) {\n    return \"Hello \" + name;\n  }\n}\n```\n\n* Consumer service\n```java\n@Configuration\npublic class ProviderServiceConfiguration {\n  @Bean\n  public ProviderService providerService() {\n    return Invoker.createProxy(\"provider\", \"ProviderController\", ProviderService.class);\n  }\n}\n```\n\nInvoke Provider service with RPC\n```java\n@RestSchema(schemaId = \"ConsumerController\", schemaInterface = ConsumerService.class)\npublic class ConsumerController implements ConsumerService {\n  private ProviderService providerService;\n\n  @Autowired\n  public void setProviderService(ProviderService providerService) {\n    this.providerService = providerService;\n  }\n\n  @Override\n  public String sayHello(String name) {\n    return providerService.sayHello(name);\n  }\n}\n```\n\nTry out this example [here](https://servicecomb.apache.org/references/java-chassis/zh_CN/start/first-sample.html) .\n\n# Documentation\n\nProject documentation is available on the [ServiceComb Java Chassis Developer Guide][java-chassis-developer-guide].\n\n[java-chassis-developer-guide]: https://servicecomb.apache.org/references/java-chassis/zh_CN/\n\n# Building\n\n  You don’t need to build from source to use Java Chassis (binaries in apache nexus ), but if you want to try out the latest and greatest, Java Chassis can be easily built with the maven.  You also need JDK 17.\n\n      mvn clean install\n\nThe first build may take a longer than expected as Maven downloads all the dependencies.\n\n# Automated Testing\n\n  To build the docker image and run the integration tests with docker, you can use maven docker profile\n\n      mvn clean install -Pdocker -Pit\n\n  If you are using docker machine, please use the following command\n\n      mvn clean install -Pdocker -Pit -Pdocker-machine\n\n# Contact\n\nBugs: [issues](https://issues.apache.org/jira/browse/SCB)\n\nmailing list: [subscribe](mailto:dev-subscribe@servicecomb.apache.org)  [dev](https://lists.apache.org/list.html?dev@servicecomb.apache.org)\n\n\n# Contributing\n\nSee [CONTRIBUTING](http://servicecomb.apache.org/developers/contributing) for details on submitting patches and the contribution workflow.\n\n# License\nLicensed under an [Apache 2.0 license](LICENSE).\n"
  },
  {
    "path": "README_ZH.md",
    "content": "# Java Chassis | [English](README.md) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.servicecomb/java-chassis-core/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Corg.apache.servicecomb) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\nApache ServiceComb Java Chassis 给开发者提供一个快速构建微服务的JAVA SDK。它包含如下特性：\n\n* 基于Open API的契约优先(API First)开发模式，满足开发过程可管理、开发规范可验证要求。\n* 多种开发风格，REST(JAX-RS、Spring MVC）和RPC等，高效支持遗留系统迁移和新系统开发场景。\n* 多种通信协议, HTTP over Vert.x、Http Over Servlet、Highway等，满足不同场景对于性能、韧性的需求。\n* 统一一致的服务提供者、服务消费者处理链，易于扩展新功能。\n* 提供服务发现、配置管理、熔断、限流、灰度发布等开箱即用的服务治理能力。\n\n可以通过[设计选型参考](https://servicecomb.apache.org/references/java-chassis/zh_CN/start/design.html) 了解更多特性和设计原理。\n\n> 如果发现项目能帮助到您，别忘了点击右上角`star`表示鼓励。\n\n# 发布版本\n\n| 版本火车           | 最新版本   | 编译的JDK版本   | 支持的JDK版本          | Open API | 备注              |\n|----------------|--------|------------|-------------------|----------|-----------------|\n| Java Chassis 3 | 3.3.0  | OpenJDK 17 | OpenJDK 17        | 3.0.x    | 依赖Spring Boot 3 |\n| Java Chassis 2 | 2.8.24 | OpenJDK 8  | OpenJDK 8, 11, 17 | 2.0.x    | 依赖Spring 5      |\n| Java Chassis 1 | 1.3.11 | OpenJDK 8  | OpenJDK 8         | 2.0.x    | 停止更新            |\n\nJava Chassis 的核心依赖\n\n| Java Chassis | Spring Boot | Vert.x | Swagger | Jackson |\n|--------------|-------------|--------|---------|---------|\n| 3.3.x        | 3.4.x       | 4.5.x  | 2.2.x   | 2.18.x  |\n| 3.2.x        | 3.3.x       | 4.5.x  | 2.2.x   | 2.18.x  |\n\n> NOTICE: Open API 3.0.x 不兼容 2.0.x， 因此Java Chassis 2、Java Chassis 1不能与Java Chassis 3共存互访. 升级Java Chassis 3, 需要将相关的消费者、提供者和边缘服务同时升级.\n\n> NOTICE: Java Chassis 1 第一个版本于2018发布，已经停止更新.\n\n# 快速开始\n\n* 定义服务契约\n\n```java\n@RequestMapping(path = \"/provider\")\npublic interface ProviderService {\n  @GetMapping(\"/sayHello\")\n  String sayHello(@RequestParam(\"name\") String name);\n}\n```\n\n* 定义提供者\n\n```java\n@RestSchema(schemaId = \"ProviderController\", schemaInterface = ProviderService.class)\npublic class ProviderController implements ProviderService {\n  @Override\n  public String sayHello(String name) {\n    return \"Hello \" + name;\n  }\n}\n```\n\n* 定义消费者\n\n```java\n@Configuration\npublic class ProviderServiceConfiguration {\n  @Bean\n  public ProviderService providerService() {\n    return Invoker.createProxy(\"provider\", \"ProviderController\", ProviderService.class);\n  }\n}\n```\n\n使用RPC方式访问提供者。\n\n```java\n@RestSchema(schemaId = \"ConsumerController\", schemaInterface = ConsumerService.class)\npublic class ConsumerController implements ConsumerService {\n  private ProviderService providerService;\n\n  @Autowired\n  public void setProviderService(ProviderService providerService) {\n    this.providerService = providerService;\n  }\n\n  @Override\n  public String sayHello(String name) {\n    return providerService.sayHello(name);\n  }\n}\n```\n\n下载并体验上述[示例项目](https://servicecomb.apache.org/references/java-chassis/zh_CN/start/first-sample.html) .\n\n# 用户文档\n\n请访问 [ServiceComb Java Chassis 开发指南][java-chassis-developer-guide].\n\n[java-chassis-developer-guide]:  https://servicecomb.apache.org/references/java-chassis/zh_CN/\n\n# 编译 Java Chassis\n\n开发者可以通过MAVEN仓库使用Java Chassis。 如果需要构建项目，需要使用JDK 17版本，并预先安装maven。\n\n      mvn clean install\n\n# 运行测试用例\n\n开发者需要预先安装docker。\n\n      mvn clean install -Pdocker -Pit\n\n使用docker machine。\n\n      mvn clean install -Pdocker -Pit -Pdocker-machine\n\n# 联系我们\n\n报告缺陷: [issues](https://issues.apache.org/jira/browse/SCB)\n\n邮件列表: [subscribe](mailto:dev-subscribe@servicecomb.apache.org)  [dev](https://lists.apache.org/list.html?dev@servicecomb.apache.org)\n\n# 参与代码提交\n\n参考 [如何做贡献](http://servicecomb.apache.org/cn/developers/contributing).\n\n# License\nLicensed under an [Apache 2.0 license](LICENSE).\n"
  },
  {
    "path": "ci/README.md",
    "content": "# Java Chassis Code Checks\n\n* Compilation and Installation\n\n   see .github/workflows/maven.yml\n\n* Checkstyle\n\n  see .github/workflows/checkstyle.yml\n\n* Rat Check\n\n  see .github/workflows/rat_check.yml\n\n* Spot Bugs\n\n  see .github/workflows/spotbugs.yml\n\n* OWASP Dependency Check\n\n  `mvn verify  -Powasp-dependency-check` . Very Slow, run manually.\n\n* Distribution\n\n  `mvn clean deploy -Dcheckstyle.skip -Dspotbugs.skip=true -Dmaven.javadoc.skip=true -DskipTests -Prelease -Pdistribution` . Run manually when preparing a release.\n"
  },
  {
    "path": "ci/checkstyle/checkstyle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!DOCTYPE module PUBLIC \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\" \"http://www.puppycrawl.com/dtds/configuration_1_3.dtd\">\n\n<!--\n    This configuration file was written by the eclipse-cs plugin configuration editor\n-->\n<!--\n    Checkstyle-Configuration: paas\n    Description: none\n-->\n<module name=\"Checker\">\n  <module name=\"FileTabCharacter\">\n    <!-- Checks that there are no tab characters in the file. -->\n  </module>\n  <module name=\"NewlineAtEndOfFile\">\n  </module>\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"Throwables.propagate\\(\"/>\n    <property name=\"message\" value=\"Throwables.propagate is deprecated\"/>\n    <property name=\"severity\" value=\"error\"/>\n  </module>\n  <module name=\"RegexpSingleline\">\n    <property name=\"format\" value=\"\\s+$\"/>\n    <property name=\"message\" value=\"Trailing whitespace\"/>\n    <property name=\"severity\" value=\"error\"/>\n  </module>\n  <module name=\"SuppressWithPlainTextCommentFilter\">\n    <property name=\"offCommentFormat\" value=\"CHECKSTYLE.OFF\"/>\n    <property name=\"onCommentFormat\" value=\"CHECKSTYLE.ON\"/>\n  </module>\n  <module name=\"TreeWalker\">\n    <module name=\"AvoidStarImport\"/>\n    <module name=\"EmptyStatement\"/>\n    <module name=\"LeftCurly\">\n      <!-- Checks for placement of the left curly brace ('{'). -->\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <module name=\"LocalFinalVariableName\">\n      <!-- Validates identifiers for local final variables against the\n        expression \"^[a-z][a-zA-Z0-9]*$\". -->\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <module name=\"LocalVariableName\">\n      <!-- Validates identifiers for local variables against the\n        expression \"^[a-z][a-zA-Z0-9]*$\". -->\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <module name=\"ModifierOrder\"/>\n\n    <!--　check if a switch statement has a default clause -->\n    <module name=\"MissingSwitchDefault\"/>\n\n    <module name=\"NoWhitespaceAfter\">\n      <!-- Checks that there is no whitespace after various unary operators.\n           Linebreaks are allowed.\n      -->\n      <property name=\"tokens\" value=\"BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,\n        UNARY_PLUS\"/>\n      <property name=\"allowLineBreaks\" value=\"true\"/>\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <!-- Checks for braces around if and else blocks -->\n    <module name=\"NeedBraces\">\n      <property name=\"severity\" value=\"error\"/>\n      <property name=\"tokens\" value=\"LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO\"/>\n    </module>\n    <module name=\"NoWhitespaceBefore\">\n      <!-- Checks that there is no whitespace before various unary operators.\n           Linebreaks are allowed.\n      -->\n      <property name=\"tokens\" value=\"SEMI, DOT, POST_DEC, POST_INC\"/>\n      <property name=\"allowLineBreaks\" value=\"true\"/>\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <module name=\"ParenPad\">\n      <!-- Checks that there is no whitespace before close parens or after\n           open parens.\n      -->\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <!-- Checks for over-complicated boolean expressions. -->\n    <module name=\"SimplifyBooleanExpression\"/>\n    <module name=\"RedundantImport\"/>\n    <module name=\"RedundantModifier\">\n      <property name=\"tokens\" value=\"METHOD_DEF, VARIABLE_DEF, ANNOTATION_FIELD_DEF, INTERFACE_DEF, CLASS_DEF, ENUM_DEF\"/>\n    </module>\n    <module name=\"RightCurly\">\n      <!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on\n      the same line. e.g., the following example is fine:\n      <pre>\n        if {\n          ...\n        } else\n      </pre>\n      -->\n      <!-- This next example is not fine:\n      <pre>\n        if {\n          ...\n        }\n        else\n      </pre>\n      -->\n      <property name=\"option\" value=\"same\"/>\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <module name=\"UnusedImports\">\n      <property name=\"processJavadoc\" value=\"true\"/>\n    </module>\n    <module name=\"UpperEll\">\n      <!-- Checks that long constants are defined with an upper ell.-->\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n    <module name=\"WhitespaceAfter\">\n      <!-- Checks that commas, semicolons and typecasts are followed by\n           whitespace.\n      -->\n      <property name=\"tokens\" value=\"COMMA, SEMI, TYPECAST\"/>\n    </module>\n    <module name=\"WhitespaceAround\">\n      <!-- Checks that various tokens are surrounded by whitespace.\n           This includes most binary operators and keywords followed\n           by regular or curly braces.\n      -->\n      <property name=\"tokens\" value=\"ASSIGN, BAND, BAND_ASSIGN, BOR,\n        BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,\n        EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,\n        LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,\n        LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,\n        MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,\n        SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN\"/>\n      <property name=\"severity\" value=\"error\"/>\n    </module>\n  </module>\n</module>\n"
  },
  {
    "path": "ci/checkstyle/suppressions.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!DOCTYPE suppressions PUBLIC\n        \"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN\"\n        \"https://checkstyle.org/dtds/suppressions_1_2.dtd\">\n\n<suppressions>\n    <suppress files=\"[/\\\\]target[/\\\\]\" checks=\".*\" />\n</suppressions>\n"
  },
  {
    "path": "ci/spotbugs/exclude.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n\n-->\n<FindBugsFilter\n        xmlns=\"https://github.com/spotbugs/filter/3.0.0\"\n        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n        xsi:schemaLocation=\"https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd\">\n\n\n    <!-- pattern sort by alpha -->\n\n    <Match>\n        <Bug pattern=\"BC_UNCONFIRMED_CAST\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"BC_VACUOUS_INSTANCEOF\"/>\n    </Match>\n\n    <Match>\n        <!-- only for JDK 8 -->\n        <Bug pattern=\"CT_CONSTRUCTOR_THROW\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DC_DOUBLECHECK\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DC_PARTIALLY_CONSTRUCTED\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DM_DEFAULT_ENCODING\"/>\n        <Class name=\"org.apache.servicecomb.demo.jaxrs.server.beanParam.BeanParamTestService\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DM_DEFAULT_ENCODING\"/>\n        <Class name=\"org.apache.servicecomb.it.deploy.Deploys\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DM_DEFAULT_ENCODING\"/>\n        <Class name=\"org.apache.servicecomb.it.testcase.TestParamCodecEdge\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DM_DEFAULT_ENCODING\"/>\n        <Class name=\"org.apache.servicecomb.it.testcase.TestRestServerConfigEdge\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"DM_EXIT\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EC_UNRELATED_TYPES\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EI_EXPOSE_REP\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EI_EXPOSE_REP2\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EI_EXPOSE_STATIC_REP2\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EQ_COMPARETO_USE_OBJECT_EQUALS\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EQ_DOESNT_OVERRIDE_EQUALS\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"ICAST_IDIV_CAST_TO_DOUBLE\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"ICAST_INTEGER_MULTIPLY_CAST_TO_LONG\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"IS2_INCONSISTENT_SYNC\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MF_CLASS_MASKS_FIELD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_CANNOT_BE_FINAL\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_EXPOSE_REP\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_MUTABLE_ARRAY\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_MUTABLE_COLLECTION_PKGPROTECT\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_OOI_PKGPROTECT\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_SHOULD_BE_FINAL\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"MS_PKGPROTECT\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NM_CLASS_NOT_EXCEPTION\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NM_METHOD_NAMING_CONVENTION\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NM_SAME_SIMPLE_NAME_AS_SUPERCLASS\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_NONNULL_PARAM_VIOLATION\"/>\n        <Class name=\"org.apache.servicecomb.it.testcase.objectparams.TestJAXRSObjectParamType\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_NONNULL_PARAM_VIOLATION\"/>\n        <Class name=\"org.apache.servicecomb.it.testcase.objectparams.TestRPCObjectParamType\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_NONNULL_PARAM_VIOLATION\"/>\n        <Class name=\"org.apache.servicecomb.it.testcase.objectparams.TestSpringMVCObjectParamType\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_NONNULL_RETURN_VIOLATION\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_NULL_ON_SOME_PATH\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"OBL_UNSATISFIED_OBLIGATION\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.localRegistryServer.SelfServiceInvoker\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.mapnull.ParseRequest\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.mapnull.ParseResponse\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.pojo.client.PojoClient\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.registry.SelfServiceInvoker\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.zeroconfig.server.SelfServiceInvoker\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"PA_PUBLIC_PRIMITIVE_ATTRIBUTE\"/>\n        <Class name=\"org.apache.servicecomb.demo.zeroconfig.edge.SelfServiceInvoker\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"RC_REF_COMPARISON\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"REC_CATCH_EXCEPTION\"/>\n        <Class name=\"org.apache.servicecomb.demo.springmvc.SpringmvcClient\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"REFLC_REFLECTION_MAY_INCREASE_ACCESSIBILITY_OF_CLASS\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"RV_NEGATING_RESULT_OF_COMPARETO\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"RV_RETURN_VALUE_IGNORED\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"SE_BAD_FIELD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"RV_RETURN_VALUE_IGNORED_BAD_PRACTICE\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"SSD_DO_NOT_USE_INSTANCE_LOCK_ON_SHARED_STATIC_DATA\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"THROWS_METHOD_THROWS_CLAUSE_THROWABLE\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"THROWS_METHOD_THROWS_RUNTIMEEXCEPTION\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD\"/>\n    </Match>\n\n    <Match>\n        <Bug pattern=\"VA_FORMAT_STRING_USES_NEWLINE\"/>\n    </Match>\n\n</FindBugsFilter>\n"
  },
  {
    "path": "clients/README.md",
    "content": "# About\n\nThis module implements common http clients for servicecomb-service-center, servicecomb-kie and other\n3rd-party services.\n\nThis module is independent on servicecomb-java-chassis, and can be used in many other projects like\nSpring Cloud, Dubbo, etc.\n\n# 关于\n\n这个模块给 servicecomb-service-center, servicecomb-kie 以及其他第三方服务实现通用的 Http Client。\n\n这个模块独立于 servicecomb-java-chassis， 可以用于 Spring Cloud, Dubbo 等项目。\n"
  },
  {
    "path": "clients/config-center-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>clients</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>config-center-client</artifactId>\n  <name>ServiceComb::Clients::Config Center Client</name>\n\n  <dependencies>\n    <!-- Make this client simple and portable to many frameworks.\n       Do not import other dependencies if really need. -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>http-client-common</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-clients-common</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.http.client.common.AbstractAddressManager;\nimport org.apache.servicecomb.http.client.common.URLEndPoint;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class ConfigCenterAddressManager extends AbstractAddressManager {\n\n  public ConfigCenterAddressManager(String projectName, List<String> addresses, EventBus eventBus, String region,\n      String availableZone) {\n    super(projectName, addresses, region, availableZone);\n    eventBus.register(this);\n  }\n\n  @Override\n  protected String normalizeUri(String endpoint) {\n    String address = new URLEndPoint(endpoint).toString();\n    return formatAddress(address);\n  }\n\n  @Subscribe\n  public void onRefreshEndpointEvent(RefreshEndpointEvent event) {\n    refreshEndpoint(event, RefreshEndpointEvent.CONFIG_CENTER_NAME);\n  }\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.config.common.exception.OperationException;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsRequest;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsResponse;\nimport org.apache.servicecomb.http.client.common.HttpRequest;\nimport org.apache.servicecomb.http.client.common.HttpResponse;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpUtils;\nimport org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;\nimport org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.google.common.eventbus.EventBus;\n\npublic class ConfigCenterClient implements ConfigCenterOperation {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConfigCenterClient.class);\n\n  public static final String DEFAULT_APP_SEPARATOR = \"@\";\n\n  public static final String DEFAULT_SERVICE_SEPARATOR = \"#\";\n\n  public static final String REVISION = \"revision\";\n\n  public static final String APPLICATION_CONFIG = \"application\";\n\n  public static final String DARK_LAUNCH = \"darklaunch@\";\n\n  private static final String ADDRESS_CHECK_PATH = \"/v3/default/configuration/health?mode=readiness\";\n\n  private final HttpTransport httpTransport;\n\n  private final ConfigCenterAddressManager addressManager;\n\n  private final Map<String, List<String>> dimensionConfigNames = new HashMap<>();\n\n  private EventBus eventBus;\n\n  public ConfigCenterClient(ConfigCenterAddressManager addressManager, HttpTransport httpTransport) {\n    this.addressManager = addressManager;\n    this.httpTransport = httpTransport;\n  }\n\n  public void setEventBus(EventBus eventBus) {\n    this.eventBus = eventBus;\n    addressManager.setEventBus(eventBus);\n  }\n\n  @Override\n  public QueryConfigurationsResponse queryConfigurations(QueryConfigurationsRequest request, String address) {\n    String dimensionsInfo = buildDimensionsInfo(request, true);\n    QueryConfigurationsResponse queryConfigurationsResponse = new QueryConfigurationsResponse();\n\n    Map<String, Object> configurations = new HashMap<>();\n\n    String uri = null;\n    try {\n      uri = address + \"/configuration/items?dimensionsInfo=\"\n          + HttpUtils.encodeURLParam(dimensionsInfo) + \"&revision=\" + request.getRevision();\n\n      Map<String, String> headers = new HashMap<>();\n      headers.put(\"x-environment\", request.getEnvironment());\n      HttpRequest httpRequest = new HttpRequest(uri, headers, null,\n          HttpRequest.GET);\n\n      HttpResponse httpResponse = httpTransport.doRequest(httpRequest);\n      recordAndSendUnAuthorizedEvent(httpResponse, address);\n      if (httpResponse.getStatusCode() == HttpStatus.SC_OK) {\n        Map<String, Map<String, Object>> allConfigMap = HttpUtils.deserialize(\n            httpResponse.getContent(),\n            new TypeReference<Map<String, Map<String, Object>>>() {\n            });\n\n        if (allConfigMap.get(REVISION) != null) {\n          queryConfigurationsResponse.setRevision((String) allConfigMap.get(REVISION).get(\"version\"));\n        }\n\n        if (allConfigMap.get(APPLICATION_CONFIG) != null) {\n          configurations.putAll(allConfigMap.get(APPLICATION_CONFIG));\n          logConfigurationNames(APPLICATION_CONFIG, allConfigMap.get(APPLICATION_CONFIG));\n        }\n\n        if (allConfigMap.get(buildDimensionsInfo(request, false)) != null) {\n          configurations.putAll(allConfigMap.get(buildDimensionsInfo(request, false)));\n          logConfigurationNames(buildDimensionsInfo(request, false),\n              allConfigMap.get(buildDimensionsInfo(request, false)));\n        }\n\n        if (allConfigMap.get(buildDarkLaunchDimensionsInfo(request)) != null) {\n          configurations.putAll(allConfigMap.get(buildDarkLaunchDimensionsInfo(request)));\n          logConfigurationNames(buildDarkLaunchDimensionsInfo(request),\n              allConfigMap.get(buildDarkLaunchDimensionsInfo(request)));\n        }\n\n        if (allConfigMap.get(dimensionsInfo) != null) {\n          configurations.putAll(allConfigMap.get(dimensionsInfo));\n          logConfigurationNames(dimensionsInfo, allConfigMap.get(dimensionsInfo));\n        }\n        queryConfigurationsResponse.setConfigurations(configurations);\n        queryConfigurationsResponse.setChanged(true);\n        return queryConfigurationsResponse;\n      } else if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {\n        queryConfigurationsResponse.setChanged(false);\n        return queryConfigurationsResponse;\n      } else if (httpResponse.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) {\n        LOGGER.warn(\"rate limited, keep the local dimension [{}] configs unchanged.\", dimensionsInfo);\n        queryConfigurationsResponse.setChanged(false);\n        return queryConfigurationsResponse;\n      } else if (httpResponse.getStatusCode() == HttpStatus.SC_BAD_REQUEST) {\n        throw new OperationException(\"Bad request for query configurations.\");\n      } else {\n        throw new OperationException(\n            \"read response failed. status:\"\n                + httpResponse.getStatusCode()\n                + \"; message:\"\n                + httpResponse.getMessage()\n                + \"; content:\"\n                + httpResponse.getContent());\n      }\n    } catch (IOException e) {\n      addressManager.recordFailState(address);\n      LOGGER.error(\"query configuration from {} failed, message={}\", uri, e.getMessage());\n      throw new OperationException(\"\", e);\n    }\n  }\n\n  private void recordAndSendUnAuthorizedEvent(HttpResponse response, String address) {\n    if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {\n      LOGGER.warn(\"query configuration unauthorized from server [{}], message [{}]\", address, response.getMessage());\n      addressManager.recordFailState(address);\n      this.eventBus.post(new UnAuthorizedOperationEvent(address));\n    } else {\n      addressManager.recordSuccessState(address);\n    }\n  }\n\n  /**\n   * Only the name of the new configuration item is printed.\n   * No log is printed when the configuration content is updated.\n   *\n   * @param dimension dimension\n   * @param configs configs\n   */\n  private void logConfigurationNames(String dimension, Map<String, Object> configs) {\n    if (CollectionUtils.isEmpty(configs)) {\n      return;\n    }\n    List<String> configNames = dimensionConfigNames.get(dimension);\n    if (configNames == null) {\n      configNames = new ArrayList<>();\n    }\n    StringBuilder names = new StringBuilder();\n    for (String key : configs.keySet()) {\n      if (configNames.contains(key)) {\n        continue;\n      }\n      names.append(key).append(\",\");\n      configNames.add(key);\n    }\n    if (names.isEmpty()) {\n      return;\n    }\n    dimensionConfigNames.put(dimension, configNames);\n    String fileNames = names.substring(0, names.length() - 1);\n    LOGGER.info(\"pulling dimension [{}] configurations success, get config names: [{}].\",\n        dimension, fileNames);\n  }\n\n  @Override\n  public void checkAddressAvailable(String address) {\n    ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH);\n  }\n\n  private String buildDimensionsInfo(QueryConfigurationsRequest request, boolean withVersion) {\n    String result =\n        request.getServiceName() + DEFAULT_APP_SEPARATOR\n            + request.getApplication();\n    if (withVersion && !StringUtils.isEmpty(request.getVersion())) {\n      result = result + DEFAULT_SERVICE_SEPARATOR + request\n          .getVersion();\n    }\n    return result;\n  }\n\n  private String buildDarkLaunchDimensionsInfo(QueryConfigurationsRequest request) {\n    return DARK_LAUNCH + request.getApplication();\n  }\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterConfigurationChangedEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\n\n/**\n * This event is fired when configuration changed of config center.\n */\npublic class ConfigCenterConfigurationChangedEvent {\n  private final Map<String, Object> added;\n\n  private final Map<String, Object> deleted;\n\n  private final Map<String, Object> updated;\n\n  private Set<String> changed;\n\n  private ConfigCenterConfigurationChangedEvent(Map<String, Object> added, Map<String, Object> updated,\n      Map<String, Object> deleted) {\n    this.added = added;\n    this.deleted = deleted;\n    this.updated = updated;\n    this.changed = new HashSet<>();\n    this.changed.addAll(added.keySet());\n    this.changed.addAll(updated.keySet());\n    this.changed.addAll(deleted.keySet());\n  }\n\n  public static ConfigCenterConfigurationChangedEvent createIncremental(Map<String, Object> latest,\n      Map<String, Object> last) {\n    Map<String, Object> itemsCreated = new HashMap<>();\n    Map<String, Object> itemsDeleted = new HashMap<>();\n    Map<String, Object> itemsModified = new HashMap<>();\n\n    for (Map.Entry<String, Object> entry : latest.entrySet()) {\n      String itemKey = entry.getKey();\n      if (!last.containsKey(itemKey)) {\n        itemsCreated.put(itemKey, entry.getValue());\n      } else if (!Objects.equals(last.get(itemKey), latest.get(itemKey))) {\n        itemsModified.put(itemKey, entry.getValue());\n      }\n    }\n    for (String itemKey : last.keySet()) {\n      if (!latest.containsKey(itemKey)) {\n        itemsDeleted.put(itemKey, null);\n      }\n    }\n    ConfigCenterConfigurationChangedEvent event = ConfigCenterConfigurationChangedEvent\n        .createIncremental(itemsCreated, itemsModified, itemsDeleted);\n    return event;\n  }\n\n  public static ConfigCenterConfigurationChangedEvent createIncremental(Map<String, Object> added,\n      Map<String, Object> updated,\n      Map<String, Object> deleted) {\n    return new ConfigCenterConfigurationChangedEvent(added, updated, deleted);\n  }\n\n  public static ConfigCenterConfigurationChangedEvent createIncremental(Map<String, Object> updated) {\n    return new ConfigCenterConfigurationChangedEvent(new HashMap<>(), updated, new HashMap<>());\n  }\n\n  public final Map<String, Object> getAdded() {\n    return added;\n  }\n\n\n  public final Map<String, Object> getUpdated() {\n    return updated;\n  }\n\n\n  public final Map<String, Object> getDeleted() {\n    return deleted;\n  }\n\n  public final Set<String> getChanged() {\n    return changed;\n  }\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.center.client.model.ConfigCenterConfiguration;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsRequest;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsResponse;\nimport org.apache.servicecomb.config.common.ConfigConverter;\nimport org.apache.servicecomb.http.client.task.AbstractTask;\nimport org.apache.servicecomb.http.client.task.Task;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.EventBus;\n\npublic class ConfigCenterManager extends AbstractTask {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConfigCenterManager.class);\n\n  private final ConfigCenterClient configCenterClient;\n\n  private final EventBus eventBus;\n\n  private QueryConfigurationsRequest queryConfigurationsRequest;\n\n  private final ConfigConverter configConverter;\n\n  private final ConfigCenterConfiguration configCenterConfiguration;\n\n  private final ConfigCenterAddressManager configCenterAddressManager;\n\n  public ConfigCenterManager(ConfigCenterClient configCenterClient, EventBus eventBus, ConfigConverter configConverter,\n      ConfigCenterConfiguration configCenterConfiguration, ConfigCenterAddressManager configCenterAddressManager) {\n    super(\"config-center-configuration-task\");\n    this.configCenterClient = configCenterClient;\n    this.eventBus = eventBus;\n    this.configConverter = configConverter;\n    this.configCenterConfiguration = configCenterConfiguration;\n    this.configCenterAddressManager = configCenterAddressManager;\n  }\n\n  public void setQueryConfigurationsRequest(QueryConfigurationsRequest queryConfigurationsRequest) {\n    this.queryConfigurationsRequest = queryConfigurationsRequest;\n  }\n\n  public void startConfigCenterManager() {\n    this.startTask(new PollConfigurationTask(0));\n    schedulerCheckAddressAvailable(\"cc-addr-check\", new CheckConfigCenterAddressTask(),\n        configCenterConfiguration.getRefreshIntervalInMillis());\n  }\n\n  class PollConfigurationTask implements Task {\n    int failCount;\n\n    public PollConfigurationTask(int failCount) {\n      this.failCount = failCount;\n    }\n\n    @Override\n    public void execute() {\n      try {\n        QueryConfigurationsResponse response = configCenterClient.queryConfigurations(queryConfigurationsRequest,\n            configCenterAddressManager.address());\n        if (response.isChanged()) {\n          queryConfigurationsRequest.setRevision(response.getRevision());\n          Map<String, Object> lastData = configConverter.updateData(response.getConfigurations());\n          ConfigCenterConfigurationChangedEvent event = ConfigCenterConfigurationChangedEvent\n              .createIncremental(configConverter.getCurrentData(), lastData);\n          if (!event.getChanged().isEmpty()) {\n            eventBus.post(event);\n          }\n        }\n        startTask(\n            new BackOffSleepTask(configCenterConfiguration.getRefreshIntervalInMillis(), new PollConfigurationTask(0)));\n      } catch (Exception e) {\n        LOGGER.warn(\"get configurations from ConfigCenter failed, and will try again, cause message: {}. current \"\n            + \"fail does not affect the obtained historical configuration.\", e.getCause().getMessage());\n        startTask(new BackOffSleepTask(failCount + 1, new PollConfigurationTask(failCount + 1)));\n      }\n    }\n  }\n\n  class CheckConfigCenterAddressTask implements Runnable {\n    @Override\n    public void run() {\n      List<String> isolationAddresses = configCenterAddressManager.getIsolationAddresses();\n      if (isolationAddresses.isEmpty()) {\n        return;\n      }\n      for (String address : isolationAddresses) {\n        configCenterClient.checkAddressAvailable(address);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client;\n\nimport org.apache.servicecomb.config.common.exception.OperationException;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsRequest;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsResponse;\n\npublic interface ConfigCenterOperation {\n  /**\n   * 根据查询条件查询配置项。\n   * @param request 查询的维度(project, application, serviceName, version) 和 revision 信息。\n   * @param address 查询的配置中心地址。\n   * @return 如果存在配置变更，返回全量的配置项, changed = true。 如果没有变更， 返回 null, changed = false，\n   *  @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  QueryConfigurationsResponse queryConfigurations(QueryConfigurationsRequest request, String address);\n\n  /**\n   * Check config center isolation address available\n   *\n   * @param address isolation address\n   */\n  void checkAddressAvailable(String address);\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/model/ConfigCenterConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client.model;\n\npublic class ConfigCenterConfiguration {\n\n    private long refreshIntervalInMillis = 15000;\n\n    public long getRefreshIntervalInMillis() {\n        return refreshIntervalInMillis;\n    }\n\n    public ConfigCenterConfiguration setRefreshIntervalInMillis(long refreshIntervalInMillis) {\n        this.refreshIntervalInMillis = refreshIntervalInMillis;\n        return this;\n    }\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/model/QueryConfigurationsRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client.model;\n\npublic class QueryConfigurationsRequest {\n  private String environment;\n\n  private String application;\n\n  private String serviceName;\n\n  private String version;\n\n  private String revision;\n\n  public String getEnvironment() {\n    return environment;\n  }\n\n  public QueryConfigurationsRequest setEnvironment(String environment) {\n    this.environment = environment;\n    return this;\n  }\n\n  public String getApplication() {\n    return application;\n  }\n\n  public QueryConfigurationsRequest setApplication(String application) {\n    this.application = application;\n    return this;\n  }\n\n  public String getServiceName() {\n    return serviceName;\n  }\n\n  public QueryConfigurationsRequest setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n    return this;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public QueryConfigurationsRequest setVersion(String version) {\n    this.version = version;\n    return this;\n  }\n\n  public String getRevision() {\n    return revision;\n  }\n\n  public QueryConfigurationsRequest setRevision(String revision) {\n    this.revision = revision;\n    return this;\n  }\n}\n"
  },
  {
    "path": "clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/model/QueryConfigurationsResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.center.client.model;\n\nimport java.util.Map;\n\npublic class QueryConfigurationsResponse {\n  private String revision;\n\n  private boolean changed;\n\n  private Map<String, Object> configurations;\n\n  public String getRevision() {\n    return revision;\n  }\n\n  public QueryConfigurationsResponse setRevision(String revision) {\n    this.revision = revision;\n    return this;\n  }\n\n  public boolean isChanged() {\n    return changed;\n  }\n\n  public QueryConfigurationsResponse setChanged(boolean changed) {\n    this.changed = changed;\n    return this;\n  }\n\n  public Map<String, Object> getConfigurations() {\n    return configurations;\n  }\n\n  public QueryConfigurationsResponse setConfigurations(\n      Map<String, Object> configurations) {\n    this.configurations = configurations;\n    return this;\n  }\n}\n"
  },
  {
    "path": "clients/config-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>clients</artifactId>\n        <groupId>org.apache.servicecomb</groupId>\n        <version>3.4.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>config-clients-common</artifactId>\n    <name>ServiceComb::Clients::Config Common</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>http-client-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-beans</artifactId>\n        </dependency>\n    </dependencies>\n\n\n</project>\n"
  },
  {
    "path": "clients/config-common/src/main/java/org/apache/servicecomb/config/common/ConfigConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.common;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.springframework.beans.factory.config.YamlPropertiesFactoryBean;\nimport org.springframework.core.io.ByteArrayResource;\nimport org.springframework.util.CollectionUtils;\n\npublic class ConfigConverter {\n  private Map<String, Object> currentData = Collections.emptyMap();\n\n  private Map<String, Object> lastRawData;\n\n  private final List<String> fileSources;\n\n  public ConfigConverter(List<String> fileSources) {\n    this.fileSources = fileSources;\n  }\n\n  public Map<String, Object> getLastRawData() {\n    return this.lastRawData;\n  }\n\n  public Map<String, Object> getCurrentData() {\n    return this.currentData;\n  }\n\n  public Map<String, Object> updateData(Map<String, Object> rawData) {\n    Map<String, Object> lastData = this.currentData;\n\n    this.lastRawData = rawData;\n\n    if (CollectionUtils.isEmpty(fileSources)) {\n      this.currentData = rawData;\n      return lastData;\n    }\n\n    Map<String, Object> fileProperties = new HashMap<>();\n    fileSources.forEach(source -> {\n      if (rawData.get(source) != null) {\n        fileProperties.put(source, rawData.get(source));\n      }\n    });\n\n    Map<String, Object> result = new HashMap<>(rawData.size());\n    result.putAll(rawData);\n    fileProperties.forEach((k, v) -> result.putAll(createFileSource(v)));\n    this.currentData = result;\n    return lastData;\n  }\n\n  private Map<String, Object> createFileSource(Object v) {\n    YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();\n    yamlFactory.setResources(new ByteArrayResource(v.toString().getBytes(StandardCharsets.UTF_8)));\n    return propertiesToMap(yamlFactory.getObject());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private Map<String, Object> propertiesToMap(Properties properties) {\n    if (properties == null) {\n      return Collections.emptyMap();\n    }\n    Map<String, Object> result = new HashMap<>();\n    Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();\n    while (keys.hasMoreElements()) {\n      String key = keys.nextElement();\n      Object value = properties.getProperty(key);\n      result.put(key, value);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "clients/config-common/src/main/java/org/apache/servicecomb/config/common/exception/OperationException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.common.exception;\n\npublic class OperationException extends RuntimeException {\n  private static final long serialVersionUID = 1L;\n\n  public OperationException(String message) {\n    super(message);\n  }\n\n  public OperationException(String message, Throwable cause) {\n    super(message, cause);\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>clients</artifactId>\n        <groupId>org.apache.servicecomb</groupId>\n        <version>3.4.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>config-kie-client</artifactId>\n    <name>ServiceComb::Clients::Kie Client</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>http-client-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>config-clients-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-beans</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>failureaccess</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n\n</project>\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client;\n\nimport com.google.common.eventbus.EventBus;\n\nimport java.io.StringReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.stream.Collectors;\n\nimport org.apache.http.HttpStatus;\n\nimport org.apache.servicecomb.config.common.exception.OperationException;\nimport org.apache.servicecomb.config.kie.client.model.ConfigConstants;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsRequest;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsResponse;\nimport org.apache.servicecomb.config.kie.client.model.KVDoc;\nimport org.apache.servicecomb.config.kie.client.model.KVResponse;\nimport org.apache.servicecomb.config.kie.client.model.KieAddressManager;\nimport org.apache.servicecomb.config.kie.client.model.KieConfiguration;\nimport org.apache.servicecomb.config.kie.client.model.ValueType;\nimport org.apache.servicecomb.http.client.common.HttpRequest;\nimport org.apache.servicecomb.http.client.common.HttpResponse;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpUtils;\nimport org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;\nimport org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.config.YamlPropertiesFactoryBean;\nimport org.springframework.core.io.ByteArrayResource;\nimport org.springframework.util.CollectionUtils;\n\npublic class KieClient implements KieConfigOperation {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(KieClient.class);\n\n  private static final String ADDRESS_CHECK_PATH = \"/v1/health\";\n\n  protected HttpTransport httpTransport;\n\n  protected String revision = \"0\";\n\n  private final KieAddressManager addressManager;\n\n  private final KieConfiguration kieConfiguration;\n\n  public static final String DEFAULT_KIE_API_VERSION = \"v1\";\n\n  private final Map<String, List<String>> dimensionConfigNames = new HashMap<>();\n\n  private EventBus eventBus;\n\n  public KieClient(KieAddressManager addressManager, HttpTransport httpTransport, KieConfiguration kieConfiguration) {\n    this.httpTransport = httpTransport;\n    this.addressManager = addressManager;\n    this.kieConfiguration = kieConfiguration;\n  }\n\n  public void setEventBus(EventBus eventBus) {\n    this.eventBus = eventBus;\n    addressManager.setEventBus(eventBus);\n  }\n\n  @Override\n  public ConfigurationsResponse queryConfigurations(ConfigurationsRequest request, String address) {\n    String url = buildUrl(request, address);\n    try {\n      if (kieConfiguration.isEnableLongPolling()) {\n        url += \"&wait=\" + kieConfiguration.getPollingWaitInSeconds() + \"s\";\n      }\n\n      HttpRequest httpRequest = new HttpRequest(url, null, null, HttpRequest.GET);\n      HttpResponse httpResponse = httpTransport.doRequest(httpRequest);\n      recordAndSendUnAuthorizedEvent(httpResponse, address);\n      ConfigurationsResponse configurationsResponse = new ConfigurationsResponse();\n      if (httpResponse.getStatusCode() == HttpStatus.SC_OK) {\n        revision = httpResponse.getHeader(\"X-Kie-Revision\");\n        KVResponse allConfigList = HttpUtils.deserialize(httpResponse.getContent(), KVResponse.class);\n        logConfigurationNames(request.getLabelsQuery(), allConfigList.getData());\n        Map<String, Object> configurations = getConfigByLabel(allConfigList);\n        configurationsResponse.setConfigurations(configurations);\n        configurationsResponse.setChanged(true);\n        configurationsResponse.setRevision(revision);\n        return configurationsResponse;\n      }\n      if (httpResponse.getStatusCode() == HttpStatus.SC_BAD_REQUEST) {\n        throw new OperationException(\"Bad request for query configurations.\");\n      }\n      if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {\n        configurationsResponse.setChanged(false);\n        return configurationsResponse;\n      }\n      if (httpResponse.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) {\n        LOGGER.warn(\"rate limited, keep the local dimension [{}] configs unchanged.\", request.getLabelsQuery());\n        configurationsResponse.setChanged(false);\n        return configurationsResponse;\n      }\n      throw new OperationException(\n          \"read response failed. status:\" + httpResponse.getStatusCode() + \"; message:\" +\n              httpResponse.getMessage() + \"; content:\" + httpResponse.getContent());\n    } catch (Exception e) {\n      addressManager.recordFailState(address);\n      LOGGER.error(\"query configuration from {} failed, message={}\", url, e.getMessage());\n      throw new OperationException(\"read response failed. \", e);\n    }\n  }\n\n  private void recordAndSendUnAuthorizedEvent(HttpResponse response, String address) {\n    if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {\n      LOGGER.warn(\"query configuration unauthorized from server [{}], message [{}]\", address, response.getMessage());\n      addressManager.recordFailState(address);\n      this.eventBus.post(new UnAuthorizedOperationEvent(address));\n    } else {\n      addressManager.recordSuccessState(address);\n    }\n  }\n\n  /**\n   * Only the name of the new configuration item is printed.\n   * No log is printed when the configuration content is updated.\n   *\n   * @param dimension dimension\n   * @param data configs-data\n   */\n  private void logConfigurationNames(String dimension, List<KVDoc> data) {\n    if (CollectionUtils.isEmpty(data)) {\n      return;\n    }\n    List<String> configNames = dimensionConfigNames.get(dimension);\n    if (configNames == null) {\n      configNames = new ArrayList<>();\n    }\n    StringBuilder names = new StringBuilder();\n    for (KVDoc doc : data) {\n      if (configNames.contains(doc.getKey())) {\n        continue;\n      }\n      names.append(doc.getKey()).append(\",\");\n      configNames.add(doc.getKey());\n    }\n    if (names.isEmpty()) {\n      return;\n    }\n    dimensionConfigNames.put(dimension, configNames);\n    String fileNames = names.substring(0, names.length() - 1);\n    LOGGER.info(\"pulling dimension [{}] configurations success, get config names: [{}].\",\n        dimension, fileNames);\n  }\n\n  @Override\n  public void checkAddressAvailable(String address) {\n    ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH);\n  }\n\n  private String buildUrl(ConfigurationsRequest request, String currentAddress) {\n    StringBuilder sb = new StringBuilder();\n    sb.append(currentAddress);\n    sb.append(\"/\");\n    sb.append(DEFAULT_KIE_API_VERSION);\n    sb.append(\"/\");\n    sb.append(kieConfiguration.getProject());\n    sb.append(\"/kie/kv?\");\n    sb.append(request.getLabelsQuery());\n    sb.append(\"&revision=\");\n    sb.append(request.getRevision());\n    if (request.isWithExact()) {\n      sb.append(\"&match=exact\");\n    }\n    return sb.toString();\n  }\n\n  private Map<String, Object> getConfigByLabel(KVResponse resp) {\n    Map<String, Object> resultMap = new HashMap<>();\n    resp.getData().stream()\n        .sorted(Comparator.comparing(KVDoc::getUpdateTime, Comparator.nullsFirst(Comparator.naturalOrder())))\n        .filter(doc -> doc.getStatus() == null || ConfigConstants.STATUS_ENABLED.equalsIgnoreCase(doc.getStatus()))\n        .map(this::processValueType)\n        .collect(Collectors.toList())\n        .forEach(resultMap::putAll);\n    return resultMap;\n  }\n\n  private Map<String, Object> processValueType(KVDoc kvDoc) {\n    ValueType valueType;\n    try {\n      valueType = ValueType.valueOf(kvDoc.getValueType());\n    } catch (IllegalArgumentException e) {\n      throw new OperationException(\"value type not support [\" + kvDoc.getValue() + \"]\");\n    }\n    Properties properties = new Properties();\n    Map<String, Object> kvMap = new HashMap<>();\n    try {\n      switch (valueType) {\n        case yml:\n        case yaml:\n          YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();\n          yamlFactory.setResources(new ByteArrayResource(kvDoc.getValue().getBytes(StandardCharsets.UTF_8)));\n          return toMap(yamlFactory.getObject());\n        case properties:\n          properties.load(new StringReader(kvDoc.getValue()));\n          return toMap(properties);\n        case text:\n        case string:\n        default:\n          kvMap.put(kvDoc.getKey(), kvDoc.getValue());\n          return kvMap;\n      }\n    } catch (Exception e) {\n      LOGGER.error(\"read config failed\", e);\n    }\n    return Collections.emptyMap();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private Map<String, Object> toMap(Properties properties) {\n    if (properties == null) {\n      return Collections.emptyMap();\n    }\n    Map<String, Object> result = new HashMap<>();\n    Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();\n    while (keys.hasMoreElements()) {\n      String key = keys.nextElement();\n      Object value = properties.getProperty(key);\n      result.put(key, value);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.Executors;\n\nimport org.apache.servicecomb.config.common.ConfigConverter;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsRequest;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsRequestFactory;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsResponse;\nimport org.apache.servicecomb.config.kie.client.model.KieAddressManager;\nimport org.apache.servicecomb.config.kie.client.model.KieConfiguration;\nimport org.apache.servicecomb.http.client.task.AbstractTask;\nimport org.apache.servicecomb.http.client.task.Task;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.EventBus;\n\npublic class KieConfigManager extends AbstractTask {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(KieConfigManager.class);\n\n  private static final long LONG_POLLING_INTERVAL = 1000;\n\n  private final KieConfigOperation configKieClient;\n\n  private final EventBus eventBus;\n\n  private final ConfigConverter configConverter;\n\n  private final List<ConfigurationsRequest> configurationsRequests;\n\n  private final KieConfiguration kieConfiguration;\n\n  private final KieAddressManager kieAddressManager;\n\n  public KieConfigManager(KieConfigOperation configKieClient, EventBus eventBus,\n      KieConfiguration kieConfiguration, ConfigConverter configConverter, KieAddressManager kieAddressManager) {\n    super(\"config-center-configuration-task\");\n    this.configurationsRequests = ConfigurationsRequestFactory.buildConfigurationRequests(kieConfiguration);\n    this.configurationsRequests.sort(ConfigurationsRequest::compareTo);\n    this.configKieClient = configKieClient;\n    this.eventBus = eventBus;\n    this.configConverter = configConverter;\n    this.kieConfiguration = kieConfiguration;\n    this.kieAddressManager = kieAddressManager;\n  }\n\n  public void firstPull() {\n    Map<String, Object> data = new HashMap<>();\n    try {\n      firstQueryConfigurations(data);\n    } catch (Exception e) {\n      if (this.kieConfiguration.isFirstPullRequired()) {\n        throw e;\n      } else {\n        LOGGER.warn(\"first pull failed!\");\n      }\n    }\n  }\n\n  private void firstQueryConfigurations(Map<String, Object> data) {\n    for (int i = 0; i < 3;) {\n      String address = kieAddressManager.address();\n      try {\n        this.configurationsRequests.forEach(r -> {\n          r.setRevision(ConfigurationsRequest.INITIAL_REVISION);\n          ConfigurationsResponse response = configKieClient.queryConfigurations(r, address);\n          if (response.isChanged()) {\n            r.setRevision(response.getRevision());\n            r.setLastRawData(response.getConfigurations());\n            data.putAll(response.getConfigurations());\n          }\n        });\n        this.configConverter.updateData(data);\n        break;\n      } catch (Exception e) {\n        if (i == 2) {\n          throw e;\n        }\n        LOGGER.warn(\"firstQueryConfigurations failed, config address {} and ignore {}\", address, e.getMessage());\n      }\n      i++;\n    }\n  }\n\n  private void onDataChanged() {\n    Map<String, Object> latestData = new HashMap<>();\n    this.configurationsRequests.forEach(r -> latestData.putAll(r.getLastRawData()));\n\n    Map<String, Object> lastData = configConverter.updateData(latestData);\n    KieConfigurationChangedEvent event = KieConfigurationChangedEvent\n        .createIncremental(configConverter.getCurrentData(), lastData);\n    if (!event.getChanged().isEmpty()) {\n      eventBus.post(event);\n    }\n  }\n\n  @Override\n  protected void initTaskPool(String taskName) {\n    this.taskPool = Executors.newFixedThreadPool(3, (task) ->\n        new Thread(task, taskName));\n  }\n\n  public void startConfigKieManager() {\n    this.configurationsRequests.forEach((t) ->\n        this.startTask(new PollConfigurationTask(0, t)));\n    schedulerCheckAddressAvailable(\"kie-addr-check\", new CheckKieAddressTask(),\n        kieConfiguration.getRefreshIntervalInMillis());\n  }\n\n  class PollConfigurationTask implements Task {\n    final int failCount;\n\n    ConfigurationsRequest configurationsRequest;\n\n    public PollConfigurationTask(int failCount, ConfigurationsRequest configurationsRequest) {\n      this.failCount = failCount;\n      this.configurationsRequest = configurationsRequest;\n    }\n\n    @Override\n    public void execute() {\n      try {\n        ConfigurationsResponse response = configKieClient.queryConfigurations(configurationsRequest,\n            kieAddressManager.address());\n        if (response.isChanged()) {\n          configurationsRequest.setRevision(response.getRevision());\n          configurationsRequest.setLastRawData(response.getConfigurations());\n          onDataChanged();\n        }\n        if (KieConfigManager.this.kieConfiguration.isEnableLongPolling()) {\n          startTask(\n              new BackOffSleepTask(LONG_POLLING_INTERVAL, new PollConfigurationTask(0, this.configurationsRequest)));\n        } else {\n          startTask(new BackOffSleepTask(kieConfiguration.getRefreshIntervalInMillis(),\n              new PollConfigurationTask(0, this.configurationsRequest)));\n        }\n      } catch (Exception e) {\n        LOGGER.warn(\"get configurations from KieConfigCenter failed, and will try again, cause message: {}. current \"\n            + \"fail does not affect the obtained historical configuration.\", e.getCause().getMessage());\n        startTask(\n            new BackOffSleepTask(failCount + 1, new PollConfigurationTask(failCount + 1, this.configurationsRequest)));\n      }\n    }\n  }\n\n  class CheckKieAddressTask implements Runnable {\n    @Override\n    public void run() {\n      List<String> isolationAddresses = kieAddressManager.getIsolationAddresses();\n      if (isolationAddresses.isEmpty()) {\n        return;\n      }\n      for (String address : isolationAddresses) {\n        configKieClient.checkAddressAvailable(address);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client;\n\nimport org.apache.servicecomb.config.common.exception.OperationException;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsRequest;\nimport org.apache.servicecomb.config.kie.client.model.ConfigurationsResponse;\n\n//此处支持配置中心扩展\npublic interface KieConfigOperation {\n  /**\n   * 根据查询条件查询配置项。\n   * @param request 查询的维度(project, application, serviceName, version) 和 revision 信息。\n   * @param address 查询的配置中心地址。\n   * @return 如果存在配置变更，返回全量的配置项, changed = true。 如果没有变更， 返回 null, changed = false，\n   *  @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  ConfigurationsResponse queryConfigurations(ConfigurationsRequest request, String address);\n\n  /**\n   * Check kie isolation address available\n   *\n   * @param address isolation address\n   */\n  void checkAddressAvailable(String address);\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigurationChangedEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\n\n/**\n * This event is fired when configuration changed of kie.\n */\npublic class KieConfigurationChangedEvent {\n  private final Map<String, Object> added;\n\n  private final Map<String, Object> deleted;\n\n  private final Map<String, Object> updated;\n\n  private Set<String> changed;\n\n  private KieConfigurationChangedEvent(Map<String, Object> added, Map<String, Object> updated,\n      Map<String, Object> deleted) {\n    this.added = added;\n    this.deleted = deleted;\n    this.updated = updated;\n    this.changed = new HashSet<>();\n    this.changed.addAll(added.keySet());\n    this.changed.addAll(updated.keySet());\n    this.changed.addAll(deleted.keySet());\n  }\n\n  public static KieConfigurationChangedEvent createIncremental(Map<String, Object> latest, Map<String, Object> last) {\n    Map<String, Object> itemsCreated = new HashMap<>();\n    Map<String, Object> itemsDeleted = new HashMap<>();\n    Map<String, Object> itemsModified = new HashMap<>();\n\n    for (Map.Entry<String, Object> entry : latest.entrySet()) {\n      String itemKey = entry.getKey();\n      if (!last.containsKey(itemKey)) {\n        itemsCreated.put(itemKey, entry.getValue());\n      } else if (!Objects.equals(last.get(itemKey), latest.get(itemKey))) {\n        itemsModified.put(itemKey, entry.getValue());\n      }\n    }\n    for (String itemKey : last.keySet()) {\n      if (!latest.containsKey(itemKey)) {\n        itemsDeleted.put(itemKey, null);\n      }\n    }\n    KieConfigurationChangedEvent event = KieConfigurationChangedEvent\n        .createIncremental(itemsCreated, itemsModified, itemsDeleted);\n    return event;\n  }\n\n  public static KieConfigurationChangedEvent createIncremental(Map<String, Object> added, Map<String, Object> updated,\n      Map<String, Object> deleted) {\n    return new KieConfigurationChangedEvent(added, updated, deleted);\n  }\n\n  public static KieConfigurationChangedEvent createIncremental(Map<String, Object> updated) {\n    return new KieConfigurationChangedEvent(new HashMap<>(), updated, new HashMap<>());\n  }\n\n  public final Map<String, Object> getAdded() {\n    return added;\n  }\n\n\n  public final Map<String, Object> getUpdated() {\n    return updated;\n  }\n\n\n  public final Map<String, Object> getDeleted() {\n    return deleted;\n  }\n\n  public final Set<String> getChanged() {\n    return changed;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigConstants.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\n\npublic class ConfigConstants {\n\n  public static final String LABEL_ENV = \"environment\";\n\n  public static final String LABEL_APP = \"app\";\n\n  public static final String LABEL_SERVICE = \"service\";\n\n  public static final String LABEL_VERSION = \"version\";\n\n  public static final String STATUS_ENABLED = \"enabled\";\n\n  public static final String KEY_PROJECT = \"project\";\n\n  // ###### kie config center polling configuration############### //\n  public static final String KEY_ENABLELONGPOLLING = \"enableLongPolling\";\n\n  public static final String KEY_POLLINGWAITSEC = \"pollingWaitInSeconds\";\n\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ConfigurationsRequest implements Comparable<ConfigurationsRequest> {\n  public static final String INITIAL_REVISION = \"-1\";\n\n  private int order;\n\n  private String revision = INITIAL_REVISION;\n\n  private boolean withExact;\n\n  private String labelsQuery;\n\n  private Map<String, Object> lastRawData = new HashMap<>();\n\n  public int getOrder() {\n    return order;\n  }\n\n  public ConfigurationsRequest setOrder(int order) {\n    this.order = order;\n    return this;\n  }\n\n  public String getRevision() {\n    return revision;\n  }\n\n  public ConfigurationsRequest setRevision(String revision) {\n    this.revision = revision;\n    return this;\n  }\n\n  public boolean isWithExact() {\n    return withExact;\n  }\n\n  public ConfigurationsRequest setWithExact(boolean withExact) {\n    this.withExact = withExact;\n    return this;\n  }\n\n  public String getLabelsQuery() {\n    return labelsQuery;\n  }\n\n  public ConfigurationsRequest setLabelsQuery(String labelsQuery) {\n    this.labelsQuery = labelsQuery;\n    return this;\n  }\n\n  public Map<String, Object> getLastRawData() {\n    return lastRawData;\n  }\n\n  public ConfigurationsRequest setLastRawData(Map<String, Object> lastRawData) {\n    this.lastRawData = lastRawData;\n    return this;\n  }\n\n  @Override\n  public int compareTo(ConfigurationsRequest o) {\n    // Higher priority, query the last\n    return o.getOrder() - this.order;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.http.client.common.HttpUtils;\n\npublic class ConfigurationsRequestFactory {\n  private static final String KEY_APP = \"app\";\n\n  private static final String KEY_ENVIRONMENT = \"environment\";\n\n  private static final String KEY_SERVICE = \"service\";\n\n  private static final String KEY_VERSION = \"version\";\n\n  private static final int CUSTOM_ORDER = 100;\n\n  private static final int VERSION_ORDER = 200;\n\n  private static final int SERVICE_ORDER = 300;\n\n  private static final int APP_ORDER = 400;\n\n  public static List<ConfigurationsRequest> buildConfigurationRequests(KieConfiguration configuration) {\n    List<ConfigurationsRequest> result = new ArrayList<>();\n    if (configuration.isEnableAppConfig()) {\n      result.add(createAppConfigurationsRequest(configuration));\n    }\n    if (configuration.isEnableServiceConfig()) {\n      result.add(createServiceConfigurationsRequest(configuration));\n    }\n    if (configuration.isEnableVersionConfig()) {\n      result.add(createVersionConfigurationsRequest(configuration));\n    }\n    if (configuration.isEnableCustomConfig()) {\n      result.add(createCustomConfigurationsRequest(configuration));\n    }\n    return result;\n  }\n\n  private static ConfigurationsRequest createAppConfigurationsRequest(KieConfiguration configuration) {\n    return new ConfigurationsRequest()\n        .setOrder(APP_ORDER)\n        .setWithExact(true)\n        .setLabelsQuery(buildLabelQuery(buildLabelQueryItem(KEY_APP, configuration.getAppName()),\n            buildLabelQueryItem(KEY_ENVIRONMENT, configuration.getEnvironment())));\n  }\n\n  private static ConfigurationsRequest createServiceConfigurationsRequest(KieConfiguration configuration) {\n    return new ConfigurationsRequest()\n        .setOrder(SERVICE_ORDER)\n        .setWithExact(true)\n        .setLabelsQuery(buildLabelQuery(buildLabelQueryItem(KEY_APP, configuration.getAppName()),\n            buildLabelQueryItem(KEY_SERVICE, configuration.getServiceName()),\n            buildLabelQueryItem(KEY_ENVIRONMENT, configuration.getEnvironment())));\n  }\n\n  private static ConfigurationsRequest createVersionConfigurationsRequest(KieConfiguration configuration) {\n    return new ConfigurationsRequest()\n        .setOrder(VERSION_ORDER)\n        .setWithExact(true)\n        .setLabelsQuery(buildLabelQuery(buildLabelQueryItem(KEY_APP, configuration.getAppName()),\n            buildLabelQueryItem(KEY_SERVICE, configuration.getServiceName()),\n            buildLabelQueryItem(KEY_ENVIRONMENT, configuration.getEnvironment()),\n            buildLabelQueryItem(KEY_VERSION, configuration.getVersion())));\n  }\n\n  private static ConfigurationsRequest createCustomConfigurationsRequest(KieConfiguration configuration) {\n    return new ConfigurationsRequest()\n        .setOrder(CUSTOM_ORDER)\n        .setWithExact(false)\n        .setLabelsQuery(\n            buildLabelQuery(buildLabelQueryItem(configuration.getCustomLabel(), configuration.getCustomLabelValue())));\n  }\n\n  private static String buildLabelQuery(String... labels) {\n    StringBuilder result = new StringBuilder();\n    for (String label : labels) {\n      result.append(label);\n      result.append(\"&\");\n    }\n    return result.toString();\n  }\n\n  private static String buildLabelQueryItem(String key, String value) {\n    try {\n      return \"label=\" + HttpUtils.encodeURLParam(key + \":\" + value);\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\"unexpected param\", e);\n    }\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport java.util.Map;\n\npublic class ConfigurationsResponse {\n  private String revision;\n\n  private boolean changed;\n\n  private Map<String, Object> configurations;\n\n  public String getRevision() {\n    return revision;\n  }\n\n  public ConfigurationsResponse setRevision(String revision) {\n    this.revision = revision;\n    return this;\n  }\n\n  public boolean isChanged() {\n    return changed;\n  }\n\n  public ConfigurationsResponse setChanged(boolean changed) {\n    this.changed = changed;\n    return this;\n  }\n\n  public Map<String, Object> getConfigurations() {\n    return configurations;\n  }\n\n  public ConfigurationsResponse setConfigurations(\n      Map<String, Object> configurations) {\n    this.configurations = configurations;\n    return this;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KVDoc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport com.fasterxml.jackson.annotation.JsonAlias;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class KVDoc {\n\n  private String id;\n\n  private String check;\n\n  private String domain;\n\n  private String key;\n\n  @JsonAlias(\"label_id\")\n  private String labelId;\n\n  private Map<String, String> labels = new HashMap<>();\n\n  private String value;\n\n  @JsonAlias(\"value_type\")\n  private String valueType;\n\n  private String status;\n\n  @JsonAlias(\"update_time\")\n  private long updateTime;\n\n  public String getStatus() {\n    return status;\n  }\n\n  public void setStatus(String status) {\n    this.status = status;\n  }\n\n  public String getId() {\n    return id;\n  }\n\n  public void setId(String id) {\n    this.id = id;\n  }\n\n  public String getKey() {\n    return key;\n  }\n\n  public void setKey(String key) {\n    this.key = key;\n  }\n\n  public String getCheck() {\n    return check;\n  }\n\n  public String getDomain() {\n    return domain;\n  }\n\n  public String getLabelId() {\n    return labelId;\n  }\n\n  public Map<String, String> getLabels() {\n    return labels;\n  }\n\n  public String getValue() {\n    return value;\n  }\n\n  public void setCheck(String check) {\n    this.check = check;\n  }\n\n  public void setDomain(String domain) {\n    this.domain = domain;\n  }\n\n  public void setLabelId(String labelId) {\n    this.labelId = labelId;\n  }\n\n  public void setLabels(Map<String, String> labels) {\n    this.labels = labels;\n  }\n\n  public void setValueType(String valueType) {\n    this.valueType = valueType;\n  }\n\n  public void setValue(String value) {\n    this.value = value;\n  }\n\n  public String getValueType() {\n    return valueType;\n  }\n\n  public long getUpdateTime() {\n    return updateTime;\n  }\n\n  public void setUpdateTime(long updateTime) {\n    this.updateTime = updateTime;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KVResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport java.util.List;\n\npublic class KVResponse {\n\n  private List<KVDoc> data;\n\n  private LabelDocResponse label;\n\n  private Integer total;\n\n  public Integer getTotal() {\n    return total;\n  }\n\n  public void setTotal(Integer total) {\n    this.total = total;\n  }\n\n  public List<KVDoc> getData() {\n    return data;\n  }\n\n  public LabelDocResponse getLabel() {\n    return label;\n  }\n\n  public void setData(List<KVDoc> data) {\n    this.data = data;\n  }\n\n  public void setLabel(LabelDocResponse label) {\n    this.label = label;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.http.client.common.AbstractAddressManager;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class KieAddressManager extends AbstractAddressManager {\n\n  public KieAddressManager(List<String> addresses, EventBus eventBus, String region, String availableZone) {\n    super(addresses, region, availableZone);\n    eventBus.register(this);\n  }\n\n  @Subscribe\n  public void onRefreshEndpointEvent(RefreshEndpointEvent event) {\n    refreshEndpoint(event, RefreshEndpointEvent.KIE_NAME);\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\npublic class KieConfiguration {\n  private boolean enableLongPolling;\n\n  private int pollingWaitInSeconds;\n\n  private int refreshIntervalInMillis = 15000;\n\n  private String project;\n\n  private String appName;\n\n  private String serviceName;\n\n  private String environment;\n\n  private String version;\n\n  private boolean enableAppConfig;\n\n  private boolean enableServiceConfig;\n\n  private boolean enableVersionConfig;\n\n  private boolean enableCustomConfig;\n\n  private String customLabelValue;\n\n  private String customLabel;\n\n  private boolean firstPullRequired;\n\n  public String getAppName() {\n    return appName;\n  }\n\n  public KieConfiguration setAppName(String appName) {\n    this.appName = appName;\n    return this;\n  }\n\n  public String getServiceName() {\n    return serviceName;\n  }\n\n  public KieConfiguration setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n    return this;\n  }\n\n  public String getEnvironment() {\n    return environment;\n  }\n\n  public KieConfiguration setEnvironment(String environment) {\n    this.environment = environment;\n    return this;\n  }\n\n  public String getCustomLabelValue() {\n    return customLabelValue;\n  }\n\n  public KieConfiguration setCustomLabelValue(String customLabelValue) {\n    this.customLabelValue = customLabelValue;\n    return this;\n  }\n\n  public boolean isEnableAppConfig() {\n    return enableAppConfig;\n  }\n\n  public KieConfiguration setEnableAppConfig(boolean enableAppConfig) {\n    this.enableAppConfig = enableAppConfig;\n    return this;\n  }\n\n  public boolean isEnableServiceConfig() {\n    return enableServiceConfig;\n  }\n\n  public KieConfiguration setEnableServiceConfig(boolean enableServiceConfig) {\n    this.enableServiceConfig = enableServiceConfig;\n    return this;\n  }\n\n  public boolean isEnableCustomConfig() {\n    return enableCustomConfig;\n  }\n\n  public KieConfiguration setEnableCustomConfig(boolean enableCustomConfig) {\n    this.enableCustomConfig = enableCustomConfig;\n    return this;\n  }\n\n  public String getCustomLabel() {\n    return customLabel;\n  }\n\n  public KieConfiguration setCustomLabel(String customLabel) {\n    this.customLabel = customLabel;\n    return this;\n  }\n\n  public boolean isEnableLongPolling() {\n    return enableLongPolling;\n  }\n\n  public KieConfiguration setEnableLongPolling(boolean enableLongPolling) {\n    this.enableLongPolling = enableLongPolling;\n    return this;\n  }\n\n  public boolean isEnableVersionConfig() {\n    return enableVersionConfig;\n  }\n\n  public KieConfiguration setEnableVersionConfig(boolean enableVersionConfig) {\n    this.enableVersionConfig = enableVersionConfig;\n    return this;\n  }\n\n  public int getPollingWaitInSeconds() {\n    return pollingWaitInSeconds;\n  }\n\n  public KieConfiguration setPollingWaitInSeconds(int pollingWaitInSeconds) {\n    this.pollingWaitInSeconds = pollingWaitInSeconds;\n    return this;\n  }\n\n  public String getProject() {\n    return project;\n  }\n\n  public KieConfiguration setProject(String project) {\n    this.project = project;\n    return this;\n  }\n\n  public boolean isFirstPullRequired() {\n    return firstPullRequired;\n  }\n\n  public KieConfiguration setFirstPullRequired(boolean firstPullRequired) {\n    this.firstPullRequired = firstPullRequired;\n    return this;\n  }\n\n  public int getRefreshIntervalInMillis() {\n    return refreshIntervalInMillis;\n  }\n\n  public KieConfiguration setRefreshIntervalInMillis(int refreshIntervallnMillis) {\n    this.refreshIntervalInMillis = refreshIntervallnMillis;\n    return this;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public KieConfiguration setVersion(String version) {\n    this.version = version;\n    return this;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/LabelDocResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport com.fasterxml.jackson.annotation.JsonAlias;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class LabelDocResponse {\n\n  @JsonAlias(\"label_id\")\n  private String labelId;\n\n  private Map<String, String> labels = new HashMap<>();\n\n  public String getLabelId() {\n    return labelId;\n  }\n\n  public Map<String, String> getLabels() {\n    return labels;\n  }\n\n  public void setLabelId(String labelId) {\n    this.labelId = labelId;\n  }\n\n  public void setLabels(Map<String, String> labels) {\n    this.labels = labels;\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/ValueType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\npublic enum ValueType {\n  yml,\n  yaml,\n  ini,\n  string,\n  text,\n  json,\n  properties,\n  xml\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/ConfigurationsRequestTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport java.util.Map;\n\nclass ConfigurationsRequestTest {\n\n  @Test\n  void getLastRawData() {\n    ConfigurationsRequest configurationsRequest = new ConfigurationsRequest();\n    Map<String, Object> lastRawData = configurationsRequest.getLastRawData();\n    Assertions.assertEquals(lastRawData.size(), 0);\n  }\n}\n"
  },
  {
    "path": "clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.client.model;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\n\nimport com.google.common.eventbus.EventBus;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nclass KieAddressManagerTest {\n\n  private static final List<String> addresses = new ArrayList<>();\n\n  private static KieAddressManager addressManager1;\n\n  @Test\n  public void kieAddressManagerTest() throws NoSuchFieldException, IllegalAccessException {\n    addresses.add(\"http://127.0.0.1:30103\");\n    addresses.add(\"https://127.0.0.2:30103\");\n    addressManager1 = new KieAddressManager(addresses, new EventBus(), \"\", \"\");\n    Field addressManagerField = addressManager1.getClass().getSuperclass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager1, 0);\n\n    Assertions.assertNotNull(addressManager1);\n\n    List<String> addresses = addressManager1.getAddresses();\n    Assertions.assertEquals(2, addresses.size());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addresses.get(0));\n\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n  }\n\n  @Test\n  public void onRefreshEndpointEvent() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"http://127.0.0.3:30100\");\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"http://127.0.0.4:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    addressManager1 = new KieAddressManager(addresses, new EventBus(), \"\", \"\");\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"KIE\");\n    addressManager1.refreshEndpoint(event, \"KIE\");\n\n    List<String> availableZone = addressManager1.getAvailableZone();\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", availableZone.get(0));\n\n    List<String> availableRegion = addressManager1.getAvailableRegion();\n    Assertions.assertEquals(\"http://127.0.0.4:30100\", availableRegion.get(0));\n  }\n}\n"
  },
  {
    "path": "clients/dashboard-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>clients</artifactId>\n        <groupId>org.apache.servicecomb</groupId>\n        <version>3.4.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>dashboard-client</artifactId>\n    <name>ServiceComb::Clients::Dashboard Client</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>http-client-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-beans</artifactId>\n        </dependency>\n\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>failureaccess</artifactId>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n\n</project>\n"
  },
  {
    "path": "clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.dashboard.client;\n\n\nimport java.util.List;\n\nimport org.apache.servicecomb.http.client.common.AbstractAddressManager;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\n\npublic class DashboardAddressManager extends AbstractAddressManager {\n\n  public DashboardAddressManager(List<String> addresses, EventBus eventBus, String region, String availableZone) {\n    super(addresses, region, availableZone);\n    eventBus.register(this);\n  }\n\n  @Subscribe\n  public void onRefreshEndpointEvent(RefreshEndpointEvent event) {\n    refreshEndpoint(event, RefreshEndpointEvent.CSE_MONITORING_NAME);\n  }\n}\n"
  },
  {
    "path": "clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.dashboard.client;\n\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.dashboard.client.model.MonitorData;\nimport org.apache.servicecomb.http.client.common.HttpRequest;\nimport org.apache.servicecomb.http.client.common.HttpResponse;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class DashboardClient implements DashboardOperation {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DashboardClient.class);\n\n  protected HttpTransport httpTransport;\n\n  private final DashboardAddressManager addressManager;\n\n  public DashboardClient(DashboardAddressManager addressManager, HttpTransport httpTransport) {\n    this.httpTransport = httpTransport;\n    this.addressManager = addressManager;\n  }\n\n  @Override\n  public void sendData(String url, MonitorData data) {\n    String address = addressManager.address();\n    try {\n      HttpRequest httpRequest = new HttpRequest(address + url, null, HttpUtils.serialize(data), HttpRequest.POST);\n      HttpResponse httpResponse = httpTransport.doRequest(httpRequest);\n      if (httpResponse.getStatusCode() != HttpStatus.SC_OK) {\n        LOGGER.error(\"send data to [{}] failed, status code [{}], message [{}]\", url, httpResponse.getStatusCode()\n            , httpResponse.getContent());\n      }\n    } catch (Exception e) {\n      LOGGER.error(\"send data to [{}] failed\", url, e);\n    }\n  }\n}\n"
  },
  {
    "path": "clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.dashboard.client;\n\nimport org.apache.servicecomb.dashboard.client.model.MonitorData;\n\npublic interface DashboardOperation {\n  void sendData(String url, MonitorData monitorData);\n}\n"
  },
  {
    "path": "clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/model/InterfaceInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.dashboard.client.model;\n\npublic class InterfaceInfo {\n  private String name;\n\n  private String desc;\n\n  private double qps;\n\n  private int latency;\n\n  private int l995;\n\n  private int l99;\n\n  private int l90;\n\n  private int l75;\n\n  private int l50;\n\n  private int l25;\n\n  private int l5;\n\n  private double rate;\n\n  private double failureRate;\n\n  private long total;\n\n  private boolean isCircuitBreakerOpen;\n\n  private long failure;\n\n  private long shortCircuited;\n\n  private long semaphoreRejected;\n\n  private long threadPoolRejected;\n\n  private long countTimeout;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getDesc() {\n    return desc;\n  }\n\n  public void setDesc(String desc) {\n    this.desc = desc;\n  }\n\n  public double getQps() {\n    return qps;\n  }\n\n  public void setQps(double qps) {\n    this.qps = qps;\n  }\n\n  public int getLatency() {\n    return latency;\n  }\n\n  public void setLatency(int latency) {\n    this.latency = latency;\n  }\n\n  public int getL995() {\n    return l995;\n  }\n\n  public void setL995(int l995) {\n    this.l995 = l995;\n  }\n\n  public int getL99() {\n    return l99;\n  }\n\n  public void setL99(int l99) {\n    this.l99 = l99;\n  }\n\n  public int getL90() {\n    return l90;\n  }\n\n  public void setL90(int l90) {\n    this.l90 = l90;\n  }\n\n  public int getL75() {\n    return l75;\n  }\n\n  public void setL75(int l75) {\n    this.l75 = l75;\n  }\n\n  public int getL50() {\n    return l50;\n  }\n\n  public void setL50(int l50) {\n    this.l50 = l50;\n  }\n\n  public int getL25() {\n    return l25;\n  }\n\n  public void setL25(int l25) {\n    this.l25 = l25;\n  }\n\n  public int getL5() {\n    return l5;\n  }\n\n  public void setL5(int l5) {\n    this.l5 = l5;\n  }\n\n  public double getRate() {\n    return rate;\n  }\n\n  public void setRate(double rate) {\n    this.rate = rate;\n  }\n\n  public double getFailureRate() {\n    return failureRate;\n  }\n\n  public void setFailureRate(double failureRate) {\n    this.failureRate = failureRate;\n  }\n\n  public long getTotal() {\n    return total;\n  }\n\n  public void setTotal(long total) {\n    this.total = total;\n  }\n\n  public boolean isCircuitBreakerOpen() {\n    return isCircuitBreakerOpen;\n  }\n\n  public void setCircuitBreakerOpen(boolean circuitBreakerOpen) {\n    isCircuitBreakerOpen = circuitBreakerOpen;\n  }\n\n  public long getFailure() {\n    return failure;\n  }\n\n  public void setFailure(long failure) {\n    this.failure = failure;\n  }\n\n  public long getShortCircuited() {\n    return shortCircuited;\n  }\n\n  public void setShortCircuited(long shortCircuited) {\n    this.shortCircuited = shortCircuited;\n  }\n\n  public long getSemaphoreRejected() {\n    return semaphoreRejected;\n  }\n\n  public void setSemaphoreRejected(long semaphoreRejected) {\n    this.semaphoreRejected = semaphoreRejected;\n  }\n\n  public long getThreadPoolRejected() {\n    return threadPoolRejected;\n  }\n\n  public void setThreadPoolRejected(long threadPoolRejected) {\n    this.threadPoolRejected = threadPoolRejected;\n  }\n\n  public long getCountTimeout() {\n    return countTimeout;\n  }\n\n  public void setCountTimeout(long countTimeout) {\n    this.countTimeout = countTimeout;\n  }\n}\n"
  },
  {
    "path": "clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/model/MonitorData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.dashboard.client.model;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\npublic class MonitorData {\n  public static final double PERCENTAGE_995 = 99.5;\n\n  public static final double PERCENTAGE_99 = 99;\n\n  public static final double PERCENTAGE_90 = 90;\n\n  public static final double PERCENTAGE_75 = 75;\n\n  public static final double PERCENTAGE_50 = 50;\n\n  public static final double PERCENTAGE_25 = 25;\n\n  public static final double PERCENTAGE_5 = 5;\n\n  public static final int SCALE_VAL = 1;\n\n  public static final double DEFAULT_SUCCESS_RATE = 1.0d;\n\n  public static final int CONVERSION = 1000;\n\n  private String appId;\n\n  private String version;\n\n  private String name;\n\n  private String serviceId;\n\n  private String environment;\n\n  private String instance;\n\n  private String instanceId;\n\n  private int thread;\n\n  private double cpu;\n\n  private double loadAverage;\n\n  private long uptime;\n\n  private Map<String, Long> memory;\n\n  private List<InterfaceInfo> interfaces = new ArrayList<>();\n\n  private Map<String, Object> customs;\n\n  public void addInterfaceInfo(InterfaceInfo interfaceInfo) {\n    interfaces.add(interfaceInfo);\n  }\n\n  public String getAppId() {\n    return appId;\n  }\n\n  public void setAppId(String appId) {\n    this.appId = appId;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public String getInstance() {\n    return instance;\n  }\n\n  public void setInstance(String instance) {\n    this.instance = instance;\n  }\n\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  public int getThreadCount() {\n    return thread;\n  }\n\n  public void setThreadCount(int threadCount) {\n    this.thread = threadCount;\n  }\n\n  public double getCpu() {\n    return cpu;\n  }\n\n  public void setCpu(double cpu) {\n    this.cpu = cpu;\n  }\n\n  public double getLoadAverage() {\n    return loadAverage;\n  }\n\n  public void setLoadAverage(double loadAverage) {\n    this.loadAverage = loadAverage;\n  }\n\n  public long getUptime() {\n    return uptime;\n  }\n\n  public void setUptime(long uptime) {\n    this.uptime = uptime;\n  }\n\n  public Map<String, Long> getMemory() {\n    return memory;\n  }\n\n  public void setMemory(Map<String, Long> memory) {\n    this.memory = memory;\n  }\n\n  public List<InterfaceInfo> getInterfaces() {\n    return interfaces;\n  }\n\n  public void setInterfaces(List<InterfaceInfo> interfaces) {\n    this.interfaces = interfaces;\n  }\n\n  public Map<String, Object> getCustoms() {\n    return customs;\n  }\n\n  public void setCustoms(Map<String, Object> customs) {\n    this.customs = customs;\n  }\n\n  public String getEnvironment() {\n    return environment;\n  }\n\n  public void setEnvironment(String environment) {\n    this.environment = environment;\n  }\n}\n"
  },
  {
    "path": "clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.dashboard.client;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport com.google.common.eventbus.EventBus;\n\nclass AddressManagerTest {\n\n  private static final List<String> addresses = new ArrayList<>();\n\n  private static DashboardAddressManager addressManager1;\n\n  @Test\n  public void kieAddressManagerTest() throws IllegalAccessException, NoSuchFieldException {\n    addresses.add(\"http://127.0.0.1:30103\");\n    addresses.add(\"https://127.0.0.2:30103\");\n    addressManager1 = new DashboardAddressManager(addresses, new EventBus(), \"\", \"\");\n    Field addressManagerField = addressManager1.getClass().getSuperclass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager1, 0);\n\n    Assertions.assertNotNull(addressManager1);\n\n    List<String> addresses = addressManager1.getAddresses();\n    Assertions.assertEquals(2, addresses.size());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addresses.get(0));\n\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n  }\n\n  @Test\n  public void onRefreshEndpointEvent() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"http://127.0.0.3:30100\");\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"http://127.0.0.4:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    addressManager1 = new DashboardAddressManager(addresses, new EventBus(), \"\", \"\");\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"CseMonitoring\");\n    addressManager1.refreshEndpoint(event, \"CseMonitoring\");\n\n    List<String> availableZone = addressManager1.getAvailableZone();\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", availableZone.get(0));\n\n    List<String> availableRegion = addressManager1.getAvailableRegion();\n    Assertions.assertEquals(\"http://127.0.0.4:30100\", availableRegion.get(0));\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>clients</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>http-client-common</artifactId>\n  <name>ServiceComb::Clients::HTTP Client Common</name>\n\n  <dependencies>\n    <!-- Make this client simple and portable to many frameworks.\n       Do not import other dependencies if really need. -->\n    <dependency>\n      <groupId>org.apache.httpcomponents</groupId>\n      <artifactId>httpclient</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>slf4j-api</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-databind</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-ssl</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-spi</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.java-websocket</groupId>\n      <artifactId>Java-WebSocket</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/DefaultRequestAuthHeaderProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.auth;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.auth.SignRequest;\n\npublic class DefaultRequestAuthHeaderProvider implements RequestAuthHeaderProvider {\n  @Override\n  public Map<String, String> loadAuthHeader(SignRequest signRequest) {\n    return new HashMap<>(0);\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/auth/RequestAuthHeaderProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.auth;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.auth.SignRequest;\n\npublic interface RequestAuthHeaderProvider {\n  Map<String, String> loadAuthHeader(SignRequest signRequest);\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Random;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.http.client.event.EngineConnectChangedEvent;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.eventbus.EventBus;\n\npublic class AbstractAddressManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAddressManager.class);\n\n  public static final String DEFAULT_PROJECT = \"default\";\n\n  public static final String V4_PREFIX = \"/v4/\";\n\n  private static final String V3_PREFIX = \"/v3/\";\n\n  private static final String ZONE = \"availableZone\";\n\n  private static final String REGION = \"region\";\n\n  private static final int ISOLATION_THRESHOLD = 3;\n\n  private volatile List<String> addresses = new ArrayList<>();\n\n  // when all addresses are isolation, it will use this for polling.\n  private final List<String> defaultAddress = new ArrayList<>();\n\n  private final List<String> defaultIsolationAddress = new ArrayList<>();\n\n  private int index;\n\n  private String projectName;\n\n  // recording continuous times of failure of an address.\n  private final Map<String, Integer> addressFailureStatus = new ConcurrentHashMap<>();\n\n  private volatile List<String> availableZone = new ArrayList<>();\n\n  private final List<String> isolationZoneAddress = new ArrayList<>();\n\n  private volatile List<String> availableRegion = new ArrayList<>();\n\n  private final List<String> isolationRegionAddress = new ArrayList<>();\n\n  private volatile boolean addressAutoRefreshed = false;\n\n  private final Object lock = new Object();\n\n  private final Random random = new Random();\n\n  private EventBus eventBus;\n\n  public AbstractAddressManager(List<String> addresses, String ownRegion, String ownAvailableZone) {\n    this.projectName = DEFAULT_PROJECT;\n    parseAndInitAddresses(addresses, ownRegion, ownAvailableZone, false);\n    this.index = !addresses.isEmpty() ? getRandomIndex() : 0;\n  }\n\n  /**\n   * address support config with region/availableZone info, to enable engine affinity calls during startup\n   * address may be like:\n   *   https://192.168.20.13:30110?region=region1&availableZone=az\n   *   https://192.168.20.13:30100?region=region1&availableZone=az\n   * When address have no datacenter information, roundRobin using address\n   *\n   * @param addresses engine addresses\n   * @param ownRegion microservice region\n   * @param ownAvailableZone microservice zone\n   * @param isFormat is need format\n   */\n  private void parseAndInitAddresses(List<String> addresses, String ownRegion, String ownAvailableZone,\n      boolean isFormat) {\n    if (CollectionUtils.isEmpty(addresses)) {\n      return;\n    }\n    List<String> tempList = new ArrayList<>();\n    addressAutoRefreshed = addresses.stream().anyMatch(addr -> addr.contains(ZONE) || addr.contains(REGION));\n    for (String address : addresses) {\n      // Compatible IpPortManager init address is 127.0.0.1:30100\n      if (!address.startsWith(\"http\")) {\n        tempList.add(address);\n        continue;\n      }\n      URLEndPoint endpoint = new URLEndPoint(address);\n      tempList.add(endpoint.toString());\n      buildAffinityAddress(endpoint, ownRegion, ownAvailableZone);\n    }\n    this.addresses.addAll(isFormat ? this.transformAddress(tempList) : tempList);\n    this.defaultAddress.addAll(isFormat ? this.transformAddress(tempList) : tempList);\n  }\n\n  private void buildAffinityAddress(URLEndPoint endpoint, String ownRegion, String ownAvailableZone) {\n    if (addressAutoRefreshed) {\n      if (regionAndAZMatch(ownRegion, ownAvailableZone, endpoint.getFirst(REGION), endpoint.getFirst(ZONE))) {\n        availableZone.add(endpoint.toString());\n      } else {\n        availableRegion.add(endpoint.toString());\n      }\n    }\n  }\n\n  private boolean regionAndAZMatch(String ownRegion, String ownAvailableZone, String engineRegion,\n      String engineAvailableZone) {\n    return ownRegion.equalsIgnoreCase(engineRegion) && ownAvailableZone.equals(engineAvailableZone);\n  }\n\n  public AbstractAddressManager(String projectName, List<String> addresses, String ownRegion, String ownAvailableZone) {\n    this.projectName = StringUtils.isEmpty(projectName) ? DEFAULT_PROJECT : projectName;\n    parseAndInitAddresses(addresses, ownRegion, ownAvailableZone, true);\n    this.index = !addresses.isEmpty() ? getRandomIndex() : 0;\n  }\n\n  private int getRandomIndex() {\n    return random.nextInt(addresses.size());\n  }\n\n  public void refreshEndpoint(RefreshEndpointEvent event, String key) {\n    if (null == event || !event.getName().equals(key)) {\n      return;\n    }\n\n    availableZone = event.getSameZone().stream().map(this::normalizeUri).collect(Collectors.toList());\n    availableRegion = event.getSameRegion().stream().map(this::normalizeUri).collect(Collectors.toList());\n    addressAutoRefreshed = true;\n  }\n\n  protected String normalizeUri(String endpoint) {\n    return new URLEndPoint(endpoint).toString();\n  }\n\n  @VisibleForTesting\n  Map<String, Integer> getAddressFailureStatus() {\n    return addressFailureStatus;\n  }\n\n  public List<String> getAddresses() {\n    return addresses;\n  }\n\n  public List<String> getAvailableZone() {\n    return availableZone;\n  }\n\n  public List<String> getAvailableRegion() {\n    return availableRegion;\n  }\n\n  public String formatUrl(String url, boolean absoluteUrl, String address) {\n    return absoluteUrl ? address + url : formatAddress(address) + url;\n  }\n\n  public boolean sslEnabled() {\n    return address().startsWith(\"https://\");\n  }\n\n  protected List<String> transformAddress(List<String> addresses) {\n    return addresses.stream().map(this::formatAddress).collect(Collectors.toList());\n  }\n\n  protected String formatAddress(String address) {\n    try {\n      return getUrlPrefix(address) + HttpUtils.encodeURLParam(this.projectName);\n    } catch (Exception e) {\n      throw new IllegalStateException(\"not possible\");\n    }\n  }\n\n  protected String getUrlPrefix(String address) {\n    return address + V3_PREFIX;\n  }\n\n  public String address() {\n    if (!addressAutoRefreshed) {\n      return getDefaultAddress();\n    } else {\n      return getAvailableZoneAddress();\n    }\n  }\n\n  private String getDefaultAddress() {\n    if (!addresses.isEmpty()) {\n      return getCurrentAddress(addresses);\n    }\n    LOGGER.warn(\"all addresses are isolation, please check server status.\");\n    // when all addresses are isolation, it will use all default address for polling.\n    return getCurrentAddress(defaultAddress);\n  }\n\n  private String getAvailableZoneAddress() {\n    List<String> zoneOrRegionAddress = getZoneOrRegionAddress();\n    if (!zoneOrRegionAddress.isEmpty()) {\n      return getCurrentAddress(zoneOrRegionAddress);\n    }\n    LOGGER.warn(\"all auto discovery addresses are isolation, please check server status.\");\n    // when all available address are isolation, it will use config addresses for polling.\n    return getCurrentAddress(addresses);\n  }\n\n  private String getCurrentAddress(List<String> addresses) {\n    synchronized (this) {\n      this.index++;\n      if (this.index >= addresses.size()) {\n        this.index = 0;\n      }\n      return addresses.get(index);\n    }\n  }\n\n  private List<String> getZoneOrRegionAddress() {\n    List<String> results = new ArrayList<>();\n    if (!availableZone.isEmpty()) {\n      results.addAll(availableZone);\n    } else {\n      results.addAll(availableRegion);\n    }\n    return results;\n  }\n\n  public void recordSuccessState(String address) {\n    resetFailureStatus(address);\n    if (addressAutoRefreshed) {\n      if (isolationZoneAddress.remove(address)) {\n        LOGGER.warn(\"restore same region address [{}]\", address);\n        if (eventBus != null && availableZone.isEmpty()) {\n          eventBus.post(new EngineConnectChangedEvent());\n        }\n        availableZone.add(address);\n        return;\n      }\n      if (isolationRegionAddress.remove(address)) {\n        LOGGER.warn(\"restore same zone address [{}]\", address);\n        availableRegion.add(address);\n      }\n      return;\n    }\n    if (defaultIsolationAddress.remove(address)) {\n      LOGGER.warn(\"restore default address [{}]\", address);\n      addresses.add(address);\n    }\n  }\n\n  public void resetFailureStatus(String address) {\n    addressFailureStatus.put(address, 0);\n  }\n\n  public void recordFailState(String address) {\n    synchronized (lock) {\n      if (!addressFailureStatus.containsKey(address)) {\n        addressFailureStatus.put(address, 1);\n        return;\n      }\n      int number = addressFailureStatus.get(address) + 1;\n      if (number < ISOLATION_THRESHOLD) {\n        addressFailureStatus.put(address, number);\n      } else {\n        removeAddress(address);\n      }\n    }\n  }\n\n  //Query whether the current address belongs to the same AZ or the same region through AZMap,\n  // and delete it from the record. At the same time, add records in history and cache\n  @VisibleForTesting\n  void removeAddress(String address) {\n    if (!addressAutoRefreshed) {\n      if (addresses.remove(address)) {\n        LOGGER.warn(\"isolation default address [{}]\", address);\n        defaultIsolationAddress.add(address);\n      }\n      return;\n    }\n    if (availableZone.remove(address)) {\n      LOGGER.warn(\"isolation same zone address [{}]\", address);\n      isolationZoneAddress.add(address);\n      if (eventBus != null && availableZone.isEmpty() && !availableRegion.isEmpty()) {\n        eventBus.post(new EngineConnectChangedEvent());\n      }\n      return;\n    }\n    if (availableRegion.remove(address)) {\n      LOGGER.warn(\"isolation same region address [{}]\", address);\n      isolationRegionAddress.add(address);\n    }\n  }\n\n  public void setEventBus(EventBus eventBus) {\n    this.eventBus = eventBus;\n  }\n\n  public List<String> getIsolationAddresses() {\n    List<String> isolationAddresses = new ArrayList<>(defaultIsolationAddress);\n    isolationAddresses.addAll(isolationZoneAddress);\n    isolationAddresses.addAll(isolationRegionAddress);\n    return isolationAddresses;\n  }\n\n  public String compareAndGetAddress(String host) {\n    for (String address : defaultAddress) {\n      if (isAddressHostSame(address, host)) {\n        return address;\n      }\n    }\n    return \"\";\n  }\n\n  private boolean isAddressHostSame(String address, String host) {\n    if (StringUtils.isEmpty(host)) {\n      return false;\n    }\n    try {\n      URI uri = new URI(address);\n      return host.equals(uri.getHost());\n    } catch (Exception e) {\n      LOGGER.warn(\"Exception occurred while constructing URI using the address [{}]\", address);\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\n\npublic interface HttpConfiguration {\n  class SSLProperties {\n    private boolean enabled;\n\n    private SSLOption sslOption;\n\n    private SSLCustom sslCustom;\n\n    public boolean isEnabled() {\n      return enabled;\n    }\n\n    public void setEnabled(boolean enabled) {\n      this.enabled = enabled;\n    }\n\n    public SSLOption getSslOption() {\n      return sslOption;\n    }\n\n    public void setSslOption(SSLOption sslOption) {\n      this.sslOption = sslOption;\n    }\n\n    public SSLCustom getSslCustom() {\n      return sslCustom;\n    }\n\n    public void setSslCustom(SSLCustom sslCustom) {\n      this.sslCustom = sslCustom;\n    }\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\n\nimport org.apache.http.client.methods.HttpDelete;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.client.methods.HttpPost;\nimport org.apache.http.client.methods.HttpPut;\nimport org.apache.http.client.methods.HttpUriRequest;\nimport org.apache.http.client.methods.RequestBuilder;\nimport org.apache.http.entity.StringEntity;\n\npublic class HttpRequest {\n\n  public static final String GET = \"GET\";\n\n  public static final String POST = \"POST\";\n\n  public static final String DELETE = \"DELETE\";\n\n  public static final String PUT = \"PUT\";\n\n  private String method;\n\n  private final String url;\n\n  private Map<String, String> headers;\n\n  private final String content;\n\n  public HttpRequest(String url, Map<String, String> headers, String content, String method) {\n    this.url = url;\n    this.headers = headers;\n    this.content = content;\n    this.method = method;\n  }\n\n  public String getUrl() {\n    return url;\n  }\n\n  public Map<String, String> getHeaders() {\n    return headers;\n  }\n\n  public void addHeader(String name, String value) {\n    if (headers == null) {\n      headers = new HashMap<>();\n    }\n    headers.put(name, value);\n  }\n\n  public String getContent() {\n    return content;\n  }\n\n  public String getMethod() {\n    return method;\n  }\n\n  public void setMethod(String method) {\n    this.method = method;\n  }\n\n  public HttpUriRequest getRealRequest() {\n\n    HttpUriRequest httpUriRequest = null;\n\n    switch (method) {\n      case GET: {\n        httpUriRequest = new HttpGet(url);\n        break;\n      }\n      case POST: {\n        httpUriRequest = new HttpPost(url);\n        if (content != null) {\n          ((HttpPost) httpUriRequest).setEntity(new StringEntity(content, \"UTF-8\"));\n        }\n        break;\n      }\n      case DELETE: {\n        httpUriRequest = new HttpDelete(url);\n        break;\n      }\n      case PUT: {\n        httpUriRequest = new HttpPut(url);\n        if (content != null) {\n          ((HttpPut) httpUriRequest).setEntity(new StringEntity(content, \"UTF-8\"));\n        }\n        break;\n      }\n      default: {\n        httpUriRequest = RequestBuilder.create(method).build();\n      }\n    }\n\n    Optional.ofNullable(httpUriRequest).ifPresent(request -> headers.forEach(request::addHeader));\n\n    return httpUriRequest;\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport org.apache.http.Header;\n\npublic class HttpResponse {\n\n  private int statusCode;\n\n  private String message;\n\n  private String content;\n\n  private Header[] headers;\n\n  public HttpResponse() {\n\n  }\n\n  HttpResponse(int statusCode, String message, String content, Header[] headers) {\n    this.statusCode = statusCode;\n    this.content = content;\n    this.message = message;\n    this.headers = headers;\n  }\n\n  public int getStatusCode() {\n    return statusCode;\n  }\n\n  public void setStatusCode(int statusCode) {\n    this.statusCode = statusCode;\n  }\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public String getContent() {\n    return content;\n  }\n\n  public void setContent(String content) {\n    this.content = content;\n  }\n\n  public String getHeader(String key) {\n    if (headers == null) {\n      return null;\n    }\n    for (Header header : headers) {\n      if (header.getName().equals(key)) {\n        return header.getValue();\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.io.IOException;\nimport java.util.Map;\n\n/**\n * Created by   on 2019/10/16.\n */\npublic interface HttpTransport {\n\n  HttpResponse get(HttpRequest request) throws IOException;\n\n  HttpResponse post(HttpRequest request) throws IOException;\n\n  HttpResponse put(HttpRequest request) throws IOException;\n\n  HttpResponse delete(HttpRequest request) throws IOException;\n\n  HttpResponse doRequest(HttpRequest request) throws IOException;\n\n  void addHeaders(Map<String, String> headers);\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.config.Registry;\nimport org.apache.http.config.RegistryBuilder;\nimport org.apache.http.conn.socket.ConnectionSocketFactory;\nimport org.apache.http.conn.socket.PlainConnectionSocketFactory;\nimport org.apache.http.conn.ssl.NoopHostnameVerifier;\nimport org.apache.http.conn.ssl.SSLConnectionSocketFactory;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.http.impl.conn.PoolingHttpClientConnectionManager;\nimport org.apache.servicecomb.foundation.ssl.SSLManager;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\n\npublic class HttpTransportFactory {\n  // All parameters set to 5 seconds now.\n  public static final int CONNECT_TIMEOUT = 5000;\n\n  public static final int CONNECTION_REQUEST_TIMEOUT = 5000;\n\n  public static final int SOCKET_TIMEOUT = 5000;\n\n  public static final int MAX_TOTAL = 100;\n\n  public static final int DEFAULT_MAX_PER_ROUTE = 10;\n\n  private HttpTransportFactory() {\n  }\n\n  public static HttpTransport createHttpTransport(HttpConfiguration.SSLProperties sslProperties,\n      RequestAuthHeaderProvider requestAuthHeaderProvider, HttpClientBuilder httpClientBuilder) {\n    PoolingHttpClientConnectionManager connectionManager = getPoolingHttpClientConnectionManager(sslProperties);\n    httpClientBuilder.setConnectionManager(connectionManager).disableCookieManagement();\n    return new HttpTransportImpl(httpClientBuilder.build(), requestAuthHeaderProvider);\n  }\n\n  public static HttpTransport createHttpTransport(HttpConfiguration.SSLProperties sslProperties,\n      RequestAuthHeaderProvider requestAuthHeaderProvider, RequestConfig config) {\n    PoolingHttpClientConnectionManager connectionManager = getPoolingHttpClientConnectionManager(sslProperties);\n\n    HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().\n        setDefaultRequestConfig(config).\n        setConnectionManager(connectionManager).\n        disableCookieManagement();\n\n    return new HttpTransportImpl(httpClientBuilder.build(), requestAuthHeaderProvider);\n  }\n\n  private static PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager(SSLProperties sslProperties) {\n    //register http/https socket factory\n    RegistryBuilder<ConnectionSocketFactory> builder = RegistryBuilder.<ConnectionSocketFactory>create();\n    builder.register(\"http\", PlainConnectionSocketFactory.INSTANCE);\n    if (sslProperties.isEnabled()) {\n      builder.register(\"https\",\n          new SSLConnectionSocketFactory(\n              SSLManager.createSSLContext(sslProperties.getSslOption(), sslProperties.getSslCustom()),\n              NoopHostnameVerifier.INSTANCE));\n    }\n    Registry<ConnectionSocketFactory> connectionSocketFactoryRegistry = builder.build();\n\n    //connection pool management\n    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(\n        connectionSocketFactoryRegistry);\n    connectionManager.setMaxTotal(MAX_TOTAL);\n    connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);\n    return connectionManager;\n  }\n\n  public static HttpTransport createHttpTransport(HttpConfiguration.SSLProperties sslProperties,\n      RequestAuthHeaderProvider requestAuthHeaderProvider) {\n    return createHttpTransport(sslProperties, requestAuthHeaderProvider, defaultRequestConfig().build());\n  }\n\n  public static RequestConfig.Builder defaultRequestConfig() {\n    return RequestConfig.custom()\n        .setConnectTimeout(CONNECT_TIMEOUT)\n        .setConnectionRequestTimeout(\n            CONNECTION_REQUEST_TIMEOUT)\n        .setSocketTimeout(SOCKET_TIMEOUT);\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.util.Map;\n\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.util.EntityUtils;\nimport org.apache.servicecomb.foundation.auth.SignRequest;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Created by   on 2019/10/16.\n */\npublic class HttpTransportImpl implements HttpTransport {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HttpTransportImpl.class);\n\n  private static final String HEADER_CONTENT_TYPE = \"Content-Type\";\n\n  private static final String HEADER_USER_AGENT = \"User-Agent\";\n\n  private HttpClient httpClient;\n\n  private Map<String, String> globalHeaders;\n\n  private final RequestAuthHeaderProvider requestAuthHeaderProvider;\n\n  public HttpTransportImpl(HttpClient httpClient, RequestAuthHeaderProvider requestAuthHeaderProvider) {\n    this.httpClient = httpClient;\n    this.requestAuthHeaderProvider = requestAuthHeaderProvider;\n  }\n\n  public HttpClient getHttpClient() {\n    return httpClient;\n  }\n\n  // for testing.\n  void setHttpClient(HttpClient httpClient) {\n    this.httpClient = httpClient;\n  }\n\n  @Override\n  public HttpResponse get(HttpRequest request) throws IOException {\n    request.setMethod(HttpRequest.GET);\n    return doRequest(request);\n  }\n\n  @Override\n  public HttpResponse post(HttpRequest request) throws IOException {\n    request.setMethod(HttpRequest.POST);\n    return doRequest(request);\n  }\n\n  @Override\n  public HttpResponse put(HttpRequest request) throws IOException {\n    request.setMethod(HttpRequest.PUT);\n    return doRequest(request);\n  }\n\n  @Override\n  public HttpResponse delete(HttpRequest request) throws IOException {\n    request.setMethod(HttpRequest.DELETE);\n    return doRequest(request);\n  }\n\n  public HttpResponse doRequest(HttpRequest httpRequest) throws IOException {\n    //add header\n    httpRequest.addHeader(HEADER_CONTENT_TYPE, \"application/json\");\n    httpRequest.addHeader(HEADER_USER_AGENT, \"microservice-client/1.0.0\");\n\n    if (globalHeaders != null) {\n      globalHeaders.forEach(httpRequest::addHeader);\n    }\n\n    httpRequest.getHeaders().putAll(requestAuthHeaderProvider.loadAuthHeader(createSignRequest(httpRequest.getUrl())));\n\n    //get Http response\n    org.apache.http.HttpResponse response = httpClient.execute(httpRequest.getRealRequest());\n\n    return new HttpResponse(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(),\n        response.getEntity() == null ? null :\n            EntityUtils.toString(response.getEntity(), \"UTF-8\"),\n        response.getAllHeaders());\n  }\n\n  private static SignRequest createSignRequest(String url) {\n    try {\n      URI uri = URI.create(url);\n      SignRequest signRequest = new SignRequest();\n      signRequest.setEndpoint(uri);\n      return signRequest;\n    } catch (Exception e) {\n      LOGGER.error(\"create signRequest failed!\", e);\n      return null;\n    }\n  }\n\n  @Override\n  public void addHeaders(Map<String, String> headers) {\n    this.globalHeaders = headers;\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.io.IOException;\nimport java.net.URLDecoder;\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\n\nimport javax.crypto.Mac;\nimport javax.crypto.spec.SecretKeySpec;\n\nimport org.apache.commons.codec.binary.Hex;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\npublic final class HttpUtils {\n  private static final String ALGORITHM_HMACSHA256 = \"HmacSHA256\";\n\n  private static final ObjectMapper MAPPER = new MessageObjectMapper();\n\n  public static <T> T deserialize(String content, Class<T> clazz) throws IOException {\n    return MAPPER.readValue(content, clazz);\n  }\n\n  public static <T> T deserialize(String content, TypeReference<T> clazz) throws IOException {\n    return MAPPER.readValue(content, clazz);\n  }\n\n  public static String serialize(Object value) throws IOException {\n    return MAPPER.writeValueAsString(value);\n  }\n\n  public static JsonNode readTree(String content) throws IOException {\n    return MAPPER.readTree(content);\n  }\n\n  public static String encodeURLParam(String value) throws IOException {\n    if (value == null) {\n      return \"\";\n    }\n    return URLEncoder.encode(value, StandardCharsets.UTF_8);\n  }\n\n  public static String decodeURLParam(String value) throws IOException {\n    if (value == null) {\n      return null;\n    }\n    return URLDecoder.decode(value, StandardCharsets.UTF_8);\n  }\n\n  public static String sha256Encode(String key, String data) throws Exception {\n    Mac mac = Mac.getInstance(ALGORITHM_HMACSHA256);\n    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8),\n        ALGORITHM_HMACSHA256);\n    mac.init(secretKey);\n    return Hex.encodeHexString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/MessageObjectMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport com.fasterxml.jackson.core.JsonParser.Feature;\nimport com.fasterxml.jackson.databind.DeserializationFeature;\nimport com.fasterxml.jackson.databind.MapperFeature;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.SerializationFeature;\n\npublic class MessageObjectMapper extends ObjectMapper {\n  private static final long serialVersionUID = 189026839992490564L;\n\n  public MessageObjectMapper() {\n    getFactory().disable(Feature.AUTO_CLOSE_SOURCE);\n    // Enable features that can tolerance errors and not enable those make more constraints for compatible reasons.\n    // Developers can use validation api to do more checks.\n    disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);\n    disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);\n    // no view annotations shouldn't be included in JSON\n    this._deserializationConfig = this._deserializationConfig.without(MapperFeature.DEFAULT_VIEW_INCLUSION);\n    this._serializationConfig = this._serializationConfig.without(MapperFeature.DEFAULT_VIEW_INCLUSION);\n    disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);\n    enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);\n    enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/SSLSocketFactoryExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport javax.net.ssl.SSLSocketFactory;\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\npublic class SSLSocketFactoryExt extends SSLSocketFactory {\n  private final SSLSocketFactory sslSocketFactory;\n\n  private final String host;\n\n  private final int port;\n\n  public SSLSocketFactoryExt(SSLSocketFactory factory, String host, int port) {\n    this.sslSocketFactory = factory;\n    this.host = host;\n    this.port = port;\n  }\n\n  @Override\n  public String[] getDefaultCipherSuites() {\n    return this.sslSocketFactory.getDefaultCipherSuites();\n  }\n\n  @Override\n  public String[] getSupportedCipherSuites() {\n    return this.sslSocketFactory.getSupportedCipherSuites();\n  }\n\n  @Override\n  public Socket createSocket() throws IOException {\n    return this.sslSocketFactory.createSocket(host, port);\n  }\n\n  @Override\n  public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {\n    return this.sslSocketFactory.createSocket(socket, host, port, autoClose);\n  }\n\n  @Override\n  public Socket createSocket(String host, int port) throws IOException, UnknownHostException {\n    return this.sslSocketFactory.createSocket(host, port);\n  }\n\n  @Override\n  public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException,\n      UnknownHostException {\n    return this.sslSocketFactory.createSocket(host, port, localHost, localPort);\n  }\n\n  @Override\n  public Socket createSocket(InetAddress localHost, int port) throws IOException {\n    return this.sslSocketFactory.createSocket(localHost, port);\n  }\n\n  @Override\n  public Socket createSocket(InetAddress localHost, int localPort, InetAddress localHost1, int localPort1)\n      throws IOException {\n    return this.sslSocketFactory.createSocket(localHost, localPort, localHost1, localPort1);\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/URLEndPoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.net.URI;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.NameValuePair;\nimport org.apache.http.client.utils.URLEncodedUtils;\n\npublic class URLEndPoint {\n  private static final String SSL_ENABLED_KEY = \"sslEnabled\";\n\n  private static final String HTTP_KEY = \"http://\";\n\n  private static final String HTTPS_KEY = \"https://\";\n\n  private final boolean sslEnabled;\n\n  private final Map<String, List<String>> queries;\n\n  private final String hostOrIp;\n\n  private final int port;\n\n  public URLEndPoint(String endpoint) {\n    URI uri = URI.create(endpoint);\n    hostOrIp = uri.getHost();\n    if (uri.getPort() < 0) {\n      throw new IllegalArgumentException(\"port not specified.\");\n    }\n    port = uri.getPort();\n    queries = splitQuery(uri);\n    if (endpoint.contains(HTTPS_KEY)) {\n      sslEnabled = true;\n    } else {\n      sslEnabled = Boolean.parseBoolean(getFirst(SSL_ENABLED_KEY));\n    }\n  }\n\n  public static Map<String, List<String>> splitQuery(URI uri) {\n    final Map<String, List<String>> queryPairs = new LinkedHashMap<>();\n    List<NameValuePair> pairs = URLEncodedUtils.parse(uri, StandardCharsets.UTF_8);\n    for (NameValuePair pair : pairs) {\n      List<String> list = queryPairs.computeIfAbsent(pair.getName(), name -> new ArrayList<>());\n      list.add(pair.getValue());\n    }\n    return queryPairs;\n  }\n\n  public String getFirst(String key) {\n    List<String> values = queries.get(key);\n    if (values == null) {\n      return null;\n    }\n    return values.get(0);\n  }\n\n  @Override\n  public String toString() {\n    if (sslEnabled) {\n      return HTTPS_KEY + hostOrIp + \":\" + port;\n    }\n    return HTTP_KEY + hostOrIp + \":\" + port;\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/WebSocketListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport org.java_websocket.handshake.ServerHandshake;\n\npublic interface WebSocketListener {\n  void onMessage(String s);\n\n  void onError(Exception e);\n\n  void onClose(int code, String reason, boolean remote);\n\n  void onOpen(ServerHandshake serverHandshake);\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/WebSocketTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.Map;\n\nimport javax.net.ssl.SSLSocketFactory;\n\nimport org.apache.servicecomb.foundation.ssl.SSLManager;\nimport org.java_websocket.client.WebSocketClient;\nimport org.java_websocket.drafts.Draft_6455;\nimport org.java_websocket.handshake.ServerHandshake;\n\npublic class WebSocketTransport extends WebSocketClient {\n  public static final int CONNECT_TIMEOUT = 5000;\n\n  private final WebSocketListener webSocketListener;\n\n  public WebSocketTransport(String serverUri, HttpConfiguration.SSLProperties sslProperties,\n      Map<String, String> headers, WebSocketListener webSocketListener)\n      throws URISyntaxException {\n    super(new URI(serverUri), new Draft_6455(), headers, CONNECT_TIMEOUT);\n\n    if (sslProperties.isEnabled()) {\n      SSLSocketFactory sslSocketFactory = SSLManager\n          .createSSLSocketFactory(sslProperties.getSslOption(), sslProperties.getSslCustom());\n      URI uri = new URI(serverUri);\n      setSocketFactory(new SSLSocketFactoryExt(sslSocketFactory, uri.getHost(), uri.getPort()));\n    }\n\n    this.webSocketListener = webSocketListener;\n  }\n\n  @Override\n  public void onOpen(ServerHandshake serverHandshake) {\n    this.webSocketListener.onOpen(serverHandshake);\n  }\n\n  @Override\n  public void onMessage(String s) {\n    this.webSocketListener.onMessage(s);\n  }\n\n  @Override\n  public void onClose(int code, String reason, boolean remote) {\n    this.webSocketListener.onClose(code, reason, remote);\n  }\n\n  @Override\n  public void onError(Exception e) {\n    this.webSocketListener.onError(e);\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/EngineConnectChangedEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.event;\n\npublic class EngineConnectChangedEvent {\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.event;\n\npublic abstract class OperationEvents {\n  public static class UnAuthorizedOperationEvent extends OperationEvents {\n    private final String address;\n\n    public UnAuthorizedOperationEvent(String address) {\n      this.address = address;\n    }\n\n    public String getAddress() {\n      return address;\n    }\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/RefreshEndpointEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.event;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class RefreshEndpointEvent {\n\n  public static final String SERVICE_CENTER_NAME = \"SERVICECENTER\";\n\n  public static final String KIE_NAME = \"KIE\";\n\n  public static final String CONFIG_CENTER_NAME = \"CseConfigCenter\";\n\n  public static final String CSE_MONITORING_NAME = \"CseMonitoring\";\n\n  private static final String SAME_ZONE = \"sameZone\";\n\n  private static final String SAME_REGION = \"sameRegion\";\n\n  private Map<String, List<String>> zoneAndRegion = new HashMap<>();\n\n  private String name;\n\n  public RefreshEndpointEvent(Map<String, List<String>> zoneAndRegion, String name) {\n    this.zoneAndRegion = zoneAndRegion;\n    this.name = name;\n  }\n\n  public List<String> getSameZone() {\n    if (zoneAndRegion.get(SAME_ZONE).isEmpty()) {\n      return new ArrayList<>();\n    }\n    return zoneAndRegion.get(SAME_ZONE);\n  }\n\n  public List<String> getSameRegion() {\n    if (zoneAndRegion.get(SAME_REGION).isEmpty()) {\n      return new ArrayList<>();\n    }\n    return zoneAndRegion.get(SAME_REGION);\n  }\n\n  public Map<String, List<String>> getZoneAndRegion() {\n    return zoneAndRegion;\n  }\n\n  public void setZoneAndRegion(Map<String, List<String>> zoneAndRegion) {\n    this.zoneAndRegion = zoneAndRegion;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.task;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.RejectedExecutionException;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class AbstractTask {\n  public class BackOffSleepTask implements Task {\n    private static final long BASE = 3000;\n\n    private static final long MAX = 10 * 60 * 1000;\n\n    long waitTime;\n\n    Task nextTask;\n\n    public BackOffSleepTask(int failedCount, Task nextTask) {\n      this.waitTime = failedCount * failedCount * BASE;\n      this.nextTask = nextTask;\n    }\n\n    public BackOffSleepTask(long waitTime, Task nextTask) {\n      this.waitTime = waitTime;\n      this.nextTask = nextTask;\n    }\n\n    @Override\n    public void execute() {\n      long time = Math.min(MAX, waitTime);\n      try {\n        Thread.sleep(time);\n      } catch (InterruptedException e) {\n        LOGGER.error(\"unexpected interrupt during sleep\", e);\n      }\n      startTask(nextTask);\n    }\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTask.class);\n\n  protected ExecutorService taskPool;\n\n  private volatile boolean running = true;\n\n  public static AtomicInteger taskCounter = new AtomicInteger(0);\n\n  private ScheduledExecutorService addrCheckExecutor;\n\n  protected AbstractTask(String taskName) {\n    initTaskPool(taskName);\n    Runtime.getRuntime().addShutdownHook(new Thread(AbstractTask.this::stop, taskName + \"-shutdown-hook\"));\n  }\n\n  protected void initTaskPool(String taskName) {\n    this.taskPool = Executors.newSingleThreadExecutor((task) ->\n        new Thread(task, taskName + \"-\" + taskCounter.getAndIncrement()));\n  }\n\n  protected void schedulerCheckAddressAvailable(String taskName, Runnable task, long delayTime) {\n    if (addrCheckExecutor == null) {\n      addrCheckExecutor = Executors.newScheduledThreadPool(1, (t) -> new Thread(t, taskName));\n    }\n    addrCheckExecutor.scheduleWithFixedDelay(task, delayTime, delayTime, TimeUnit.MILLISECONDS);\n  }\n\n  protected void startTask(Task task) {\n    if (!running) {\n      return;\n    }\n\n    try {\n      this.taskPool.execute(() -> {\n        try {\n          task.execute();\n        } catch (Throwable e) {\n          LOGGER.error(\"unexpected error execute task {}\", task.getClass().getName(), e);\n        }\n      });\n    } catch (RejectedExecutionException e) {\n      LOGGER.error(\"execute task rejected {}\", task.getClass().getName(), e);\n    }\n  }\n\n  public void stop() {\n    try {\n      running = false;\n      this.taskPool.shutdown();\n      this.taskPool.awaitTermination(10, TimeUnit.SECONDS);\n      if (addrCheckExecutor != null) {\n        this.addrCheckExecutor.shutdown();\n        this.addrCheckExecutor.awaitTermination(10, TimeUnit.SECONDS);\n      }\n    } catch (InterruptedException e) {\n      LOGGER.warn(\"tasks not shutdown in time {}\", e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/Task.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.task;\n\npublic interface Task {\n  void execute();\n}\n"
  },
  {
    "path": "clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/utils/ServiceCombServiceAvailableUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.utils;\n\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.http.client.common.AbstractAddressManager;\nimport org.apache.servicecomb.http.client.common.HttpRequest;\nimport org.apache.servicecomb.http.client.common.HttpResponse;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.net.Socket;\nimport java.net.URI;\nimport java.net.URISyntaxException;\n\npublic class ServiceCombServiceAvailableUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCombServiceAvailableUtils.class);\n\n  public static void checkAddressAvailable(AbstractAddressManager addressManager, String address,\n      HttpTransport httpTransport, String path) {\n    String formatUrl = addressManager.formatUrl(path, true, address);\n    HttpRequest httpRequest = new HttpRequest(formatUrl, null, null, HttpRequest.GET);\n    try {\n      HttpResponse response = httpTransport.doRequest(httpRequest);\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\n        addressManager.recordSuccessState(address);\n        return;\n      }\n\n      // old server does not provide the check api, using TCP checks whether the server is ready.\n      if (response.getStatusCode() == HttpStatus.SC_NOT_FOUND && telnetCheckAddress(address)) {\n        LOGGER.warn(\"[{}] path does not provide, tcp check address ready!\", path);\n        addressManager.recordSuccessState(address);\n      }\n    } catch (IOException e) {\n      LOGGER.error(\"check isolation address [{}] available error!\", address);\n    }\n  }\n\n  private static boolean telnetCheckAddress(String address) {\n    URI ipPort = parseIpPortFromURI(address);\n    if (ipPort == null) {\n      return false;\n    }\n    try (Socket s = new Socket()) {\n      s.connect(new InetSocketAddress(ipPort.getHost(), ipPort.getPort()), 3000);\n      return true;\n    } catch (IOException e) {\n      LOGGER.warn(\"ping endpoint {} failed, It will be quarantined again.\", address);\n    }\n    return false;\n  }\n\n  private static URI parseIpPortFromURI(String address) {\n    try {\n      return new URI(address);\n    } catch (URISyntaxException e) {\n      LOGGER.error(\"build uri error with address [{}].\", address);\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class AbstractAddressManagerTest {\n\n  private static final List<String> addresses = new ArrayList<>();\n\n  private static AbstractAddressManager addressManager1;\n\n  private static AbstractAddressManager addressManager2;\n\n  private static AbstractAddressManager addressManager3;\n\n  @BeforeEach\n  public void setUp() throws NoSuchFieldException, IllegalAccessException {\n    addresses.add(\"http://127.0.0.1:30103\");\n    addresses.add(\"https://127.0.0.2:30103\");\n    addressManager1 = new AbstractAddressManager(addresses, \"\", \"\");\n    addressManager2 = new AbstractAddressManager(\"project\", addresses, \"\", \"\");\n    addressManager3 = new AbstractAddressManager(null, addresses, \"\", \"\");\n    Field addressManagerField = addressManager1.getClass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager1, 0);\n    addressManagerField = addressManager2.getClass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager2, 0);\n    addressManagerField = addressManager3.getClass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager3, 0);\n  }\n\n  @AfterEach\n  public void tearDown() {\n    addresses.clear();\n    addressManager1 = null;\n    addressManager2 = null;\n    addressManager3 = null;\n  }\n\n  @Test\n  public void abstractAddressManagerTest() {\n    Assertions.assertNotNull(addressManager1);\n    Assertions.assertNotNull(addressManager2);\n    Assertions.assertNotNull(addressManager3);\n\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n  }\n\n  @Test\n  public void recordStateTest() throws ExecutionException {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"http://127.0.0.3:30100\");\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"http://127.0.0.4:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"TEST\");\n    AbstractAddressManager addressManager = new AbstractAddressManager(addresses, \"\", \"\") {};\n\n    addressManager.refreshEndpoint(event, \"TEST\");\n\n    String address = \"http://127.0.0.3:30100\";\n    addressManager.recordFailState(address);\n\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", addressManager.address());\n\n    addressManager.recordFailState(address);\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", addressManager.address());\n\n    // test fail 2 times ,it will not be isolated\n    addressManager.resetFailureStatus(address);\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", addressManager.address());\n\n    // test recodeStatus times\n    Map<String, Integer> recodeStatus = addressManager.getAddressFailureStatus();\n    Assertions.assertEquals(0, (int) recodeStatus.get(\"http://127.0.0.3:30100\"));\n\n    // test fail 3 times ,it will be isolated\n    addressManager.recordFailState(address);\n    addressManager.recordFailState(address);\n    addressManager.recordFailState(address);\n    Assertions.assertEquals(\"http://127.0.0.4:30100\", addressManager.address());\n\n    // test restore isolation\n    addressManager.recordSuccessState(\"http://127.0.0.3:30100\");\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", addressManager.address());\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", addressManager.address());\n  }\n\n\n  @Test\n  public void testMultipleThread() throws Exception {\n\n    AbstractAddressManager addressManager = new AbstractAddressManager(addresses, \"\", \"\");\n    String address = \"http://127.0.0.3:30100\";\n\n    CountDownLatch latch = new CountDownLatch(2);\n    for (int i = 0; i < 2; i++) {\n      new Thread(() -> {\n        addressManager.recordFailState(address);\n        latch.countDown();\n      }).start();\n    }\n    latch.await(30, TimeUnit.SECONDS);\n\n    Map<String, Integer> recodeStatus = addressManager.getAddressFailureStatus();\n    Assertions.assertEquals(2, (int) recodeStatus.get(\"http://127.0.0.3:30100\"));\n  }\n\n  @Test\n  public void addressForOnlyDefaultTest() {\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n\n    Assertions.assertEquals(\"https://127.0.0.2:30103/v3/project\", addressManager2.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v3/project\", addressManager2.address());\n\n    Assertions.assertEquals(\"https://127.0.0.2:30103/v3/default\", addressManager3.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v3/default\", addressManager3.address());\n  }\n\n  @Test\n  public void addressForOnlyAzTest() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"http://127.0.0.1:30100\");\n    addressAZ.add(\"https://127.0.0.2:30100\");\n    addressAZ.add(\"rest://127.0.0.1:30100?sslEnabled=true\");\n    addressAZ.add(\"rest://127.0.0.2:30100?sslEnabled=false\");\n\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", new ArrayList<>());\n    RefreshEndpointEvent event1 = new RefreshEndpointEvent(zoneAndRegion, \"TEST\");\n    addressManager1.refreshEndpoint(event1, \"TEST\");\n\n    Assertions.assertEquals(\"https://127.0.0.2:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.1:30100\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.2:30100\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.2:30100\", addressManager1.address());\n  }\n\n  @Test\n  public void addressForOnlyRegionTest() {\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"rest://127.0.0.5:30100?sslEnabled=true\");\n    addressRG.add(\"rest://127.0.0.6:30100\");\n    addressRG.add(\"http://127.0.0.7:30100\");\n    addressRG.add(\"https://127.0.0.8:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", new ArrayList<>());\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"TEST\");\n    addressManager1.refreshEndpoint(event, \"TEST\");\n\n    Assertions.assertEquals(\"http://127.0.0.6:30100\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.7:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.8:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.5:30100\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.6:30100\", addressManager1.address());\n  }\n\n  @Test\n  public void addressForAzAndRegionTest() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"rest://127.0.0.1:30100?sslEnabled=true\");\n    addressAZ.add(\"https://127.0.0.2:30100\");\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"rest://127.0.0.3:30100?sslEnabled=true\");\n    addressRG.add(\"https://127.0.0.4:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"TEST\");\n    addressManager1.refreshEndpoint(event, \"TEST\");\n\n    Assertions.assertEquals(\"https://127.0.0.2:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.1:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.2:30100\", addressManager1.address());\n\n    addressManager1.removeAddress(\"https://127.0.0.2:30100\");\n    addressManager1.removeAddress(\"https://127.0.0.1:30100\");\n    Assertions.assertEquals(\"https://127.0.0.3:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.4:30100\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.3:30100\", addressManager1.address());\n\n    addressManager1.removeAddress(\"https://127.0.0.4:30100\");\n    addressManager1.removeAddress(\"https://127.0.0.3:30100\");\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n  }\n\n  @Test\n  public void sslEnabledTest() {\n    Assertions.assertTrue(addressManager1.sslEnabled());\n    Assertions.assertFalse(addressManager1.sslEnabled());\n    Assertions.assertTrue(addressManager1.sslEnabled());\n\n    Assertions.assertTrue(addressManager2.sslEnabled());\n    Assertions.assertFalse(addressManager2.sslEnabled());\n    Assertions.assertTrue(addressManager2.sslEnabled());\n  }\n\n  @Test\n  public void transformAddressTest() {\n    List<String> address = new ArrayList<>();\n    address.add(\"rest://127.0.0.1:30100?sslEnabled=true\");\n    address.add(\"rest://127.0.0.2:30100\");\n    address.add(\"http://127.0.0.3:30100\");\n    address.add(\"https://127.0.0.4:30100\");\n\n    List<String> formAddress = addressManager2.transformAddress(address);\n\n    Assertions.assertEquals(\"rest://127.0.0.1:30100?sslEnabled=true/v3/project\", formAddress.get(0));\n    Assertions.assertEquals(\"rest://127.0.0.2:30100/v3/project\", formAddress.get(1));\n    Assertions.assertEquals(\"http://127.0.0.3:30100/v3/project\", formAddress.get(2));\n    Assertions.assertEquals(\"https://127.0.0.4:30100/v3/project\", formAddress.get(3));\n\n    formAddress = addressManager3.transformAddress(address);\n    Assertions.assertEquals(\"rest://127.0.0.1:30100?sslEnabled=true/v3/default\", formAddress.get(0));\n    Assertions.assertEquals(\"rest://127.0.0.2:30100/v3/default\", formAddress.get(1));\n    Assertions.assertEquals(\"http://127.0.0.3:30100/v3/default\", formAddress.get(2));\n    Assertions.assertEquals(\"https://127.0.0.4:30100/v3/default\", formAddress.get(3));\n  }\n\n  @Test\n  public void getUrlPrefixTest() {\n    Assertions.assertEquals(\"http://127.0.0.3:30100/v3/\", addressManager2.getUrlPrefix(\"http://127.0.0.3:30100\"));\n    Assertions.assertEquals(\"http://127.0.0.3:30100/v3/\", addressManager3.getUrlPrefix(\"http://127.0.0.3:30100\"));\n  }\n\n  @Test\n  public void refreshEndpointTest() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"rest://127.0.0.1:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", new ArrayList<>());\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"TEST\");\n\n    addressManager1.refreshEndpoint(event, \"KIE\");\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.2:30103\", addressManager1.address());\n\n    addressManager2.refreshEndpoint(event, \"TEST\");\n    Assertions.assertEquals(\"http://127.0.0.1:30100\", addressManager2.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30100\", addressManager2.address());\n  }\n\n  @Test\n  public void normalizeIPV4Test() {\n    String uri = addressManager1.normalizeUri(\"rest://127.0.0.1:30100?sslEnabled=true\");\n    Assertions.assertEquals(\"https://127.0.0.1:30100\", uri);\n\n    uri = addressManager1.normalizeUri(\"rest://127.0.0.1:30100?sslEnabled=false\");\n    Assertions.assertEquals(\"http://127.0.0.1:30100\", uri);\n\n    uri = addressManager1.normalizeUri(\"rest://127.0.0.1:30100\");\n    Assertions.assertEquals(\"http://127.0.0.1:30100\", uri);\n  }\n\n  @Test\n  public void normalizeIPV6Test() {\n    String uri = addressManager1.normalizeUri(\"rest://[2008::7:957f:b2d6:1af4:a1f8]:30100?sslEnabled=true\");\n    Assertions.assertEquals(\"https://[2008::7:957f:b2d6:1af4:a1f8]:30100\", uri);\n\n    uri = addressManager1.normalizeUri(\"rest://[2008::7:957f:b2d6:1af4:a1f8]:30100\");\n    Assertions.assertEquals(\"http://[2008::7:957f:b2d6:1af4:a1f8]:30100\", uri);\n  }\n\n  @Test\n  public void compareAndGetAddressTest() {\n    List<String> testAddr = new ArrayList<>();\n    testAddr.add(\"https://192.168.20.160:30100\");\n    testAddr.add(\"https://127.0.0.1:30100\");\n    testAddr.add(\"https://127.0.0.3:30100\");\n    AbstractAddressManager manager = new AbstractAddressManager(testAddr, \"\", \"\");\n    Assertions.assertTrue(manager.compareAndGetAddress(\"192.168.20.16\").isEmpty());\n    Assertions.assertEquals(\"https://192.168.20.160:30100\", manager.compareAndGetAddress(\"192.168.20.160\"));\n  }\n\n  @Test\n  public void AddressAffinityTest() {\n    List<String> testAddr = new ArrayList<>();\n    testAddr.add(\"https://192.168.20.160:30100?region=region1&availableZone=zone1\");\n    testAddr.add(\"https://127.0.0.1:30100\");\n    AbstractAddressManager manager = new AbstractAddressManager(testAddr, \"region1\", \"zone1\");\n    Assertions.assertEquals(\"https://192.168.20.160:30100\", manager.address());\n\n    AbstractAddressManager manager2 = new AbstractAddressManager(\"default\", testAddr, \"region1\", \"zone1\");\n    Assertions.assertEquals(\"https://192.168.20.160:30100\", manager2.address());\n  }\n}\n"
  },
  {
    "path": "clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/HttpTransportImplTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.http.client.common;\n\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.http.HttpVersion;\nimport org.apache.http.StatusLine;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.entity.ContentType;\nimport org.apache.http.entity.StringEntity;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class HttpTransportImplTest {\n\n  @Test\n  public void TestHttpTransport() throws IOException {\n    HttpClient httpClient = mock(HttpClient.class);\n    RequestAuthHeaderProvider requestAuthHeaderProvider = mock(RequestAuthHeaderProvider.class);\n    org.apache.http.HttpResponse httpResponse = mock(org.apache.http.HttpResponse.class);\n    StatusLine statusLine = mock(StatusLine.class);\n    when(statusLine.getStatusCode()).thenReturn(200);\n    when(statusLine.getProtocolVersion()).thenReturn(HttpVersion.HTTP_1_1);\n    when(statusLine.getReasonPhrase()).thenReturn(\"OK\");\n\n    when(httpResponse.getStatusLine()).thenReturn(statusLine);\n    when(httpResponse.getEntity()).thenReturn(new StringEntity(\"Test\", ContentType.APPLICATION_JSON));\n\n    when(httpClient.execute(Mockito.any())).thenReturn(httpResponse);\n\n    HttpTransportImpl httpTransport = new HttpTransportImpl(httpClient, requestAuthHeaderProvider);\n    Map<String, String> extraHeaders = new HashMap<>();\n    extraHeaders.put(\"test\", \"testContext\");\n    httpTransport.addHeaders(extraHeaders);\n\n    HttpRequest httpRequest = new HttpRequest(\"111\", null, null, HttpRequest.GET);\n    HttpResponse actualResponse = httpTransport.get(httpRequest);\n\n    Assertions.assertNotNull(actualResponse);\n    Assertions.assertEquals(200, actualResponse.getStatusCode());\n    Assertions.assertEquals(\"OK\", actualResponse.getMessage());\n    Assertions.assertEquals(\"Test\", actualResponse.getContent());\n  }\n}\n"
  },
  {
    "path": "clients/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>clients</artifactId>\n  <name>ServiceComb::Client</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>http-client-common</module>\n    <module>service-center-client</module>\n    <module>config-common</module>\n    <module>config-kie-client</module>\n    <module>config-center-client</module>\n    <module>dashboard-client</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "clients/service-center-client/README.md",
    "content": "## ServiceComb-Service-Center Client for Java\n\n   Sample Java client for ServiceComb-Service-Center HTTP API.\n   If you want more information about the ServiceComb-Service-Center HTTP API, go [here](https://github.com/apache/servicecomb-service-center/blob/master/docs/openapi/v4.yaml).\n\n### Build & Install\n\n   local Build from source :\n   ```\n    maven clean install\n   ```\n\n   add dependency to maven\n   ```\n    <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>service-center-client</artifactId>\n    </dependency>\n   ```\n\n\n### Basic Usage\n\n#### Case 1: Health check\n```Java\nServiceCenterClient client = new ServiceCenterClient();\n\n//get service-center instance\nMicroserviceInstancesResponse instances = client.getServiceCenterInstances();\n```\n\n#### Case 2: Register microservice\n```Java\nServiceCenterClient client = new ServiceCenterClient();\n\n// state Microservice object, and you have to set a serviceName\nMicroservice microservice = new Microservice();\nmicroservice.setServiceName(\"Test\");\nmicroservice.setServiceId(\"111111\");\n\n//register microservice\nString response = client.registerMicroservice(microservice);\n```\n\n#### Case 3: Get microservice list\n```Java\nServiceCenterClient client = new ServiceCenterClient();\n\n//get services lists\nMicroservicesResponse services = client.getMicroserviceList();\n```\n\n#### Case 4: Register service instance\n```Java\nServiceCenterClient client = new ServiceCenterClient();\n\n//state MicroserviceInstance object, you have to set existed serviceId\nMicroserviceInstance instance = new MicroserviceInstance();\ninstance.setServiceId(\"222222\");\n\n//register service instanceId, return instanceId\nString instanceId = client.registerMicroserviceInstance(instance, \"222222\");\n```\n\n#### Case 5: Get service instances list\n```Java\nServiceCenterClient client = new ServiceCenterClient();\n\n// get instances list with servcieId being \"222222\"\nMicroserviceInstancesResponse instances = client.getMicroserviceInstanceList(\"222222\");\n```\n\n#### Case 6: Heartbeats\n```Java\nServiceCenterClient client = new ServiceCenterClient();\n\n//all services and all instances send heartbeats\nMicroservicesResponse services = client.getMicroserviceList();\nfor(Microservice microservice : services.getServices())\n{\n  for (MicroserviceInstance instance: client.getMicroserviceInstanceList(microservice.getServiceId()).getInstances())\n  {\n    client.sendHeartBeats(new HeartbeatsRequest(microservice.getServiceId(),instance.getInstanceId()));\n  }\n}\n```\n\n#### Other API\nYou can see client API code and tests, go [here](https://github.com/apache/servicecomb-java-chassis/blob/master/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java)\n\n\n### More development\n\n- Support All Service-center HTTP API\n\n### Contact\nBugs/Feature : [issues](https://github.com/apache/servicecomb-java-chassis/issues)\n"
  },
  {
    "path": "clients/service-center-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>clients</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>service-center-client</artifactId>\n  <name>ServiceComb::Clients::Service Center Client</name>\n\n  <dependencies>\n    <!-- Make this client simple and portable to many frameworks.\n       Do not import other dependencies if really need. -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>http-client-common</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>failureaccess</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/CacheableServiceCenterOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\npublic interface CacheableServiceCenterOperation {\n\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/DiscoveryEvents.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\n\npublic abstract class DiscoveryEvents {\n  public static class InstanceChangedEvent extends DiscoveryEvents {\n    private final String appName;\n\n    private final String serviceName;\n\n    private final List<MicroserviceInstance> instances;\n\n    public InstanceChangedEvent(String appName, String serviceName, List<MicroserviceInstance> instances) {\n      this.appName = appName;\n      this.serviceName = serviceName;\n      this.instances = instances;\n    }\n\n    public String getAppName() {\n      return appName;\n    }\n\n    public String getServiceName() {\n      return serviceName;\n    }\n\n    public List<MicroserviceInstance> getInstances() {\n      return instances;\n    }\n  }\n\n  /**\n   * internal events to ask for a immediate instance pull\n   */\n  public static class PullInstanceEvent extends DiscoveryEvents {\n\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/RegistrationEvents.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\n\npublic abstract class RegistrationEvents {\n  protected final boolean success;\n\n  protected final Microservice microservice;\n\n  protected RegistrationEvents(boolean success, Microservice microservice) {\n    this.success = success;\n    this.microservice = microservice;\n  }\n\n  public boolean isSuccess() {\n    return this.success;\n  }\n\n  public Microservice getMicroservice() {\n    return microservice;\n  }\n\n  public static class MicroserviceRegistrationEvent extends RegistrationEvents {\n    public MicroserviceRegistrationEvent(boolean success, Microservice microservice) {\n      super(success, microservice);\n    }\n  }\n\n  public static class SchemaRegistrationEvent extends RegistrationEvents {\n    public SchemaRegistrationEvent(boolean success, Microservice microservice) {\n      super(success, microservice);\n    }\n  }\n\n  public static class MicroserviceInstanceRegistrationEvent extends RegistrationEvents {\n    protected final MicroserviceInstance microserviceInstance;\n\n    public MicroserviceInstanceRegistrationEvent(boolean success, Microservice microservice,\n        MicroserviceInstance microserviceInstance) {\n      super(success, microservice);\n      this.microserviceInstance = microserviceInstance;\n    }\n  }\n\n  public static class HeartBeatEvent extends RegistrationEvents {\n    protected final MicroserviceInstance microserviceInstance;\n\n    public HeartBeatEvent(boolean success, Microservice microservice,\n        MicroserviceInstance microserviceInstance) {\n      super(success, microservice);\n      this.microserviceInstance = microserviceInstance;\n    }\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.http.client.common.AbstractAddressManager;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class ServiceCenterAddressManager extends AbstractAddressManager {\n  public ServiceCenterAddressManager(String projectName, List<String> addresses, EventBus eventBus, String region,\n      String availableZone) {\n    super(projectName, addresses, region, availableZone);\n    eventBus.register(this);\n  }\n\n  @Override\n  protected List<String> transformAddress(List<String> addresses) {\n    return addresses;\n  }\n\n  @Override\n  protected String getUrlPrefix(String address) {\n    return address + V4_PREFIX;\n  }\n\n  @Subscribe\n  public void onRefreshEndpointEvent(RefreshEndpointEvent event) {\n    refreshEndpoint(event, RefreshEndpointEvent.SERVICE_CENTER_NAME);\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client;\r\n\r\nimport java.io.IOException;\r\nimport java.net.URISyntaxException;\r\nimport java.net.URLEncoder;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport org.apache.http.HttpStatus;\r\nimport org.apache.http.client.config.RequestConfig;\r\nimport org.apache.http.client.utils.URIBuilder;\r\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\r\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\r\nimport org.apache.servicecomb.http.client.common.HttpResponse;\r\nimport org.apache.servicecomb.http.client.common.HttpTransport;\r\nimport org.apache.servicecomb.http.client.common.HttpTransportFactory;\r\nimport org.apache.servicecomb.http.client.common.HttpUtils;\r\nimport org.apache.servicecomb.service.center.client.exception.OperationException;\r\nimport org.apache.servicecomb.service.center.client.model.CreateMicroserviceInstanceRequest;\r\nimport org.apache.servicecomb.service.center.client.model.CreateMicroserviceRequest;\r\nimport org.apache.servicecomb.service.center.client.model.CreateSchemaRequest;\r\nimport org.apache.servicecomb.service.center.client.model.ErrorMessage;\r\nimport org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse;\r\nimport org.apache.servicecomb.service.center.client.model.Framework;\r\nimport org.apache.servicecomb.service.center.client.model.GetSchemaListResponse;\r\nimport org.apache.servicecomb.service.center.client.model.GetSchemaResponse;\r\nimport org.apache.servicecomb.service.center.client.model.HeartbeatsRequest;\r\nimport org.apache.servicecomb.service.center.client.model.Microservice;\r\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\r\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstanceResponse;\r\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstanceStatus;\r\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstancesResponse;\r\nimport org.apache.servicecomb.service.center.client.model.MicroserviceResponse;\r\nimport org.apache.servicecomb.service.center.client.model.MicroservicesResponse;\r\nimport org.apache.servicecomb.service.center.client.model.ModifySchemasRequest;\r\nimport org.apache.servicecomb.service.center.client.model.RbacTokenRequest;\r\nimport org.apache.servicecomb.service.center.client.model.RbacTokenResponse;\r\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;\r\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;\r\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\r\nimport org.apache.servicecomb.service.center.client.model.UpdatePropertiesRequest;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.core.env.Environment;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\npublic class ServiceCenterClient implements ServiceCenterOperation {\r\n\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterClient.class);\r\n\r\n  private static final String CLIENT_CONNECT_TIMEOUT = \"servicecomb.registry.sc.client.timeout.connect\";\r\n\r\n  private static final String CLIENT_REQUEST_TIMEOUT = \"servicecomb.registry.sc.client.timeout.request\";\r\n\r\n  private static final String CLIENT_SOCKET_TIMEOUT = \"servicecomb.registry.sc.client.timeout.socket\";\r\n\r\n  private final ServiceCenterRawClient httpClient;\r\n\r\n  private final ServiceCenterAddressManager addressManager;\r\n\r\n  public ServiceCenterClient(ServiceCenterRawClient httpClient, ServiceCenterAddressManager addressManager) {\r\n    this.httpClient = httpClient;\r\n    this.addressManager = addressManager;\r\n  }\r\n\r\n  public ServiceCenterClient setEventBus(EventBus eventBus) {\r\n    addressManager.setEventBus(eventBus);\r\n    this.httpClient.setEventBus(eventBus);\r\n    return this;\r\n  }\r\n\r\n  public ServiceCenterClient(ServiceCenterAddressManager addressManager,\r\n      SSLProperties sslProperties,\r\n      RequestAuthHeaderProvider requestAuthHeaderProvider,\r\n      String tenantName,\r\n      Map<String, String> extraGlobalHeaders,\r\n      Environment environment) {\r\n    HttpTransport httpTransport = HttpTransportFactory.createHttpTransport(sslProperties, requestAuthHeaderProvider,\r\n        buildRequestConfig(environment));\r\n    httpTransport.addHeaders(extraGlobalHeaders);\r\n\r\n    this.httpClient = new ServiceCenterRawClient.Builder()\r\n        .setTenantName(tenantName)\r\n        .setAddressManager(addressManager)\r\n        .setHttpTransport(httpTransport).build();\r\n    this.addressManager = addressManager;\r\n  }\r\n\r\n  private RequestConfig buildRequestConfig(Environment environment) {\r\n    RequestConfig.Builder builder = HttpTransportFactory.defaultRequestConfig();\r\n    if (environment == null) {\r\n      return builder.build();\r\n    }\r\n    builder.setConnectTimeout(environment.getProperty(CLIENT_CONNECT_TIMEOUT, int.class, 5000));\r\n    builder.setConnectionRequestTimeout(environment.getProperty(CLIENT_REQUEST_TIMEOUT,  int.class, 5000));\r\n    builder.setSocketTimeout(environment.getProperty(CLIENT_SOCKET_TIMEOUT,  int.class, 5000));\r\n    return builder.build();\r\n  }\r\n\r\n  @Override\r\n  public MicroserviceInstancesResponse getServiceCenterInstances() {\r\n    try {\r\n      HttpResponse response = httpClient.getHttpRequest(\"/registry/health\", null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return HttpUtils.deserialize(response.getContent(), MicroserviceInstancesResponse.class);\r\n      }\r\n      throw new OperationException(\r\n          \"get service-center instances fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service-center instances fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public RegisteredMicroserviceResponse registerMicroservice(Microservice microservice) {\r\n    try {\r\n      CreateMicroserviceRequest request = new CreateMicroserviceRequest();\r\n      request.setService(microservice);\r\n      HttpResponse response = httpClient\r\n          .postHttpRequest(\"/registry/microservices\", null, HttpUtils.serialize(request));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return HttpUtils.deserialize(response.getContent(), RegisteredMicroserviceResponse.class);\r\n      }\r\n      throw new OperationException(\r\n          \"register service fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"register service fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public MicroservicesResponse getMicroserviceList() {\r\n    try {\r\n      HttpResponse response = httpClient.getHttpRequest(\"/registry/microservices\", null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return HttpUtils.deserialize(response.getContent(), MicroservicesResponse.class);\r\n      }\r\n      throw new OperationException(\r\n          \"get service List fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service List fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public RegisteredMicroserviceResponse queryServiceId(Microservice microservice) {\r\n    try {\r\n      URIBuilder uriBuilder = new URIBuilder(\"/registry/existence\");\r\n      uriBuilder.setParameter(\"type\", \"microservice\");\r\n      uriBuilder.setParameter(\"appId\", microservice.getAppId());\r\n      uriBuilder.setParameter(\"serviceName\", microservice.getServiceName());\r\n      uriBuilder.setParameter(\"version\", microservice.getVersion());\r\n      uriBuilder.setParameter(\"env\", microservice.getEnvironment());\r\n\r\n      HttpResponse response = httpClient.getHttpRequest(uriBuilder.build().toString(), null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return HttpUtils.deserialize(response.getContent(), RegisteredMicroserviceResponse.class);\r\n      }\r\n      LOGGER.info(\"Query serviceId fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n          .getMessage()\r\n          + \"; content = \" + response.getContent());\r\n      return null;\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"query serviceId fails\", e);\r\n    } catch (URISyntaxException e) {\r\n      throw new OperationException(\r\n          \"build url failed.\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public Microservice getMicroserviceByServiceId(String serviceId) {\r\n    try {\r\n      HttpResponse response = httpClient.getHttpRequest(\"/registry/microservices/\" + serviceId, null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        MicroserviceResponse microserviceResponse = HttpUtils\r\n            .deserialize(response.getContent(), MicroserviceResponse.class);\r\n        return microserviceResponse.getService();\r\n      }\r\n      throw new OperationException(\r\n          \"get service message fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service message fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public RegisteredMicroserviceInstanceResponse registerMicroserviceInstance(MicroserviceInstance instance) {\r\n    try {\r\n      CreateMicroserviceInstanceRequest request = new CreateMicroserviceInstanceRequest();\r\n      request.setInstance(instance);\r\n      HttpResponse response = httpClient\r\n          .postHttpRequest(\"/registry/microservices/\" + instance.getServiceId() + \"/instances\", null,\r\n              HttpUtils.serialize(request));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return HttpUtils.deserialize(response.getContent(), RegisteredMicroserviceInstanceResponse.class);\r\n      }\r\n      throw new OperationException(\r\n          \"register service instance fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"register service instance fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public FindMicroserviceInstancesResponse findMicroserviceInstance(String consumerId, String appId, String serviceName,\r\n      String versionRule,\r\n      String revision) {\r\n    try {\r\n      Map<String, String> headers = new HashMap<>();\r\n      headers.put(\"X-ConsumerId\", consumerId);\r\n      HttpResponse response = httpClient\r\n          .getHttpRequest(\"/registry/instances?appId=\" + URLEncoder.encode(appId, \"UTF-8\")\r\n                  + \"&serviceName=\" + HttpUtils.encodeURLParam(serviceName)\r\n                  + \"&version=\" + HttpUtils.encodeURLParam(versionRule)\r\n                  + \"&rev=\" + HttpUtils.encodeURLParam(revision)\r\n              , headers, null);\r\n      FindMicroserviceInstancesResponse result = new FindMicroserviceInstancesResponse();\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        result.setModified(true);\r\n        result.setRevision(response.getHeader(\"X-Resource-Revision\"));\r\n        result.setMicroserviceInstancesResponse(\r\n            HttpUtils.deserialize(response.getContent(), MicroserviceInstancesResponse.class));\r\n        return result;\r\n      }\r\n      if (response.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {\r\n        result.setModified(false);\r\n        return result;\r\n      }\r\n      if (response.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) {\r\n        LOGGER.warn(\"rate limited, keep the local service {}#{} instance cache unchanged.\", appId, serviceName);\r\n        result.setModified(false);\r\n        return result;\r\n      }\r\n      throw new OperationException(\r\n          \"get service instances list fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service instances list fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public MicroserviceInstancesResponse getMicroserviceInstanceList(String serviceId) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .getHttpRequest(\"/registry/microservices/\" + serviceId + \"/instances\", null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return HttpUtils.deserialize(response.getContent(), MicroserviceInstancesResponse.class);\r\n      }\r\n      throw new OperationException(\r\n          \"get service instances list fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service instances list fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public MicroserviceInstance getMicroserviceInstance(String serviceId, String instanceId) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .getHttpRequest(\"/registry/microservices/\" + serviceId + \"/instances/\" + instanceId, null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        MicroserviceInstanceResponse instanceResponse = HttpUtils\r\n            .deserialize(response.getContent(), MicroserviceInstanceResponse.class);\r\n        return instanceResponse.getInstance();\r\n      }\r\n      throw new OperationException(\r\n          \"get service instance message fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service instance message fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public void deleteMicroserviceInstance(String serviceId, String instanceId) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .deleteHttpRequest(\"/registry/microservices/\" + serviceId + \"/instances/\" + instanceId, null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        LOGGER.info(\"Delete service instance successfully.\");\r\n        return;\r\n      }\r\n      throw new OperationException(\r\n          \"delete service instance fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"delete service instance fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public boolean updateMicroserviceInstanceStatus(String serviceId, String instanceId,\r\n      MicroserviceInstanceStatus status) {\r\n    try {\r\n      HttpResponse response = httpClient.putHttpRequest(\r\n          \"/registry/microservices/\" + serviceId + \"/instances/\" + instanceId + \"/status?value=\" + status, null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return true;\r\n      }\r\n      throw new OperationException(\r\n          \"update service instance status fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"update service instance status fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public void sendHeartBeats(HeartbeatsRequest heartbeatsRequest) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .putHttpRequest(\"/registry/heartbeats\", null, HttpUtils.serialize(heartbeatsRequest));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return;\r\n      }\r\n      throw new OperationException(\r\n          \"heartbeats fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response.getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"heartbeats fails \", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public boolean sendHeartBeat(String serviceId, String instanceId) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .putHttpRequest(\"/registry/microservices/\" + serviceId + \"/instances/\" + instanceId + \"/heartbeat\",\r\n              null, null);\r\n\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return true;\r\n      }\r\n      throw new OperationException(\r\n          \"heartbeats fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response.getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"heartbeats fails \", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public List<SchemaInfo> getServiceSchemasList(String serviceId, boolean withContent) {\r\n    String url = \"/registry/microservices/\" + serviceId + \"/schemas\";\r\n    if (withContent) {\r\n      url = url + \"?withSchema=1\";\r\n    }\r\n\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .getHttpRequest(url, null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        GetSchemaListResponse getSchemaResponse = HttpUtils\r\n            .deserialize(response.getContent(), GetSchemaListResponse.class);\r\n        return getSchemaResponse.getSchemas();\r\n      }\r\n      throw new OperationException(\r\n          \"get service schemas list fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service schemas list fails\", e);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Get one schema context of service\r\n   *\r\n   * @param serviceId\r\n   * @param schemaId\r\n   * @return\r\n   * @throws OperationException\r\n   */\r\n  public String getServiceSchemaContext(String serviceId, String schemaId) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .getHttpRequest(\"/registry/microservices/\" + serviceId + \"/schemas/\" + schemaId, null, null);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        GetSchemaResponse getSchemaResponse = HttpUtils.deserialize(response.getContent(), GetSchemaResponse.class);\r\n        return getSchemaResponse.getSchema();\r\n      }\r\n      throw new OperationException(\r\n          \"get service schema context fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"get service schemas context fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public boolean registerSchema(String serviceId, String schemaId, CreateSchemaRequest schema) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .putHttpRequest(\"/registry/microservices/\" + serviceId + \"/schemas/\" + schemaId, null,\r\n              HttpUtils.serialize(schema));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return true;\r\n      }\r\n      throw new OperationException(\r\n          \"update service schema fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"update service schema fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public boolean updateServiceSchemaContext(String serviceId, SchemaInfo schemaInfo) {\r\n    try {\r\n      CreateSchemaRequest request = new CreateSchemaRequest();\r\n      request.setSchema(schemaInfo.getSchema());\r\n      request.setSummary(schemaInfo.getSummary());\r\n      HttpResponse response = httpClient\r\n          .putHttpRequest(\"/registry/microservices/\" + serviceId + \"/schemas/\" + schemaInfo.getSchemaId(), null,\r\n              HttpUtils.serialize(request));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return true;\r\n      }\r\n      throw new OperationException(\r\n          \"update service schema fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"update service schema fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public boolean batchUpdateServiceSchemaContext(String serviceId, ModifySchemasRequest modifySchemasRequest) {\r\n    try {\r\n      HttpResponse response = httpClient\r\n          .postHttpRequest(\"/registry/microservices/\" + serviceId + \"/schemas\", null,\r\n              HttpUtils.serialize(modifySchemasRequest));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return true;\r\n      }\r\n      throw new OperationException(\r\n          \"update service schema fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"update service schema fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public RbacTokenResponse queryToken(RbacTokenRequest request, String host) {\r\n    try {\r\n      String queryAddress = addressManager.compareAndGetAddress(host);\r\n      HttpResponse response = httpClient\r\n          .postHttpRequestAbsoluteUrl(\"/v4/token\", null, HttpUtils.serialize(request), queryAddress);\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        RbacTokenResponse result = HttpUtils.deserialize(response.getContent(), RbacTokenResponse.class);\r\n        result.setStatusCode(HttpStatus.SC_OK);\r\n        return result;\r\n      }\r\n      if (response.getStatusCode() == HttpStatus.SC_NOT_FOUND) {\r\n        RbacTokenResponse result = new RbacTokenResponse();\r\n        result.setStatusCode(response.getStatusCode());\r\n        return result;\r\n      }\r\n      if (response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED ||\r\n          response.getStatusCode() == HttpStatus.SC_FORBIDDEN) {\r\n        RbacTokenResponse result = new RbacTokenResponse();\r\n        result.setStatusCode(response.getStatusCode());\r\n        ErrorMessage errorMessage = HttpUtils.deserialize(response.getContent(), ErrorMessage.class);\r\n        result.setErrorCode(errorMessage.getErrorCode());\r\n        return result;\r\n      }\r\n      throw new OperationException(\r\n          \"query token failed, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n              .getMessage()\r\n              + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n          \"query token failed\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public boolean updateMicroserviceProperties(String serviceId, Map<String, String> serviceProperties,\r\n      Framework framework) {\r\n    try {\r\n      UpdatePropertiesRequest request = new UpdatePropertiesRequest();\r\n      request.setProperties(serviceProperties);\r\n      request.setFramework(framework);\r\n      HttpResponse response = httpClient.putHttpRequest(\r\n              \"/registry/microservices/\" + serviceId + \"/properties\", null, HttpUtils.serialize(request));\r\n      if (response.getStatusCode() == HttpStatus.SC_OK) {\r\n        return true;\r\n      }\r\n      throw new OperationException(\r\n              \"update service properties fails, statusCode = \" + response.getStatusCode() + \"; message = \" + response\r\n                      .getMessage()\r\n                      + \"; content = \" + response.getContent());\r\n    } catch (IOException e) {\r\n      throw new OperationException(\r\n              \"update service properties fails\", e);\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public void checkIsolationAddressAvailable() {\r\n    List<String> isolationAddresses = addressManager.getIsolationAddresses();\r\n    if (isolationAddresses.isEmpty()) {\r\n      return;\r\n    }\r\n    for (String address : isolationAddresses) {\r\n      httpClient.checkAddressAvailable(address);\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Random;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.servicecomb.http.client.task.AbstractTask;\nimport org.apache.servicecomb.http.client.task.Task;\nimport org.apache.servicecomb.service.center.client.DiscoveryEvents.InstanceChangedEvent;\nimport org.apache.servicecomb.service.center.client.DiscoveryEvents.PullInstanceEvent;\nimport org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class ServiceCenterDiscovery extends AbstractTask {\n\n  public static final int MAX_INTERVAL = 600000;\n\n  public static final int MIN_INTERVAL = 1000;\n\n  private static final String ALL_VERSION = \"0+\";\n\n  private static volatile boolean pullInstanceTaskOnceInProgress = false;\n\n  public static class SubscriptionKey {\n    final String appId;\n\n    final String serviceName;\n\n    public SubscriptionKey(String appId, String serviceName) {\n      this.appId = appId;\n      this.serviceName = serviceName;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n      if (this == o) {\n        return true;\n      }\n      if (o == null || getClass() != o.getClass()) {\n        return false;\n      }\n      SubscriptionKey that = (SubscriptionKey) o;\n      return appId.equals(that.appId) &&\n          serviceName.equals(that.serviceName);\n    }\n\n    @Override\n    public int hashCode() {\n      return Objects.hash(appId, serviceName);\n    }\n  }\n\n  public static class SubscriptionValue {\n    String revision;\n\n    List<MicroserviceInstance> instancesCache;\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterDiscovery.class);\n\n  private final ServiceCenterClient serviceCenterClient;\n\n  private final EventBus eventBus;\n\n  private String myselfServiceId;\n\n  private final Map<SubscriptionKey, SubscriptionValue> instancesCache = new ConcurrentHashMap<>();\n\n  private final Map<String, Microservice> microserviceCache = new ConcurrentHashMap<>();\n\n  private long pollInterval = 15000;\n\n  private boolean started = false;\n\n  private final Object lock = new Object();\n\n  private final Random random = new Random();\n\n  public ServiceCenterDiscovery(ServiceCenterClient serviceCenterClient, EventBus eventBus) {\n    super(\"service-center-discovery-task\");\n    this.serviceCenterClient = serviceCenterClient;\n    this.eventBus = eventBus;\n    this.eventBus.register(this);\n  }\n\n  public ServiceCenterDiscovery setPollInterval(long interval) {\n    if (interval > MAX_INTERVAL || interval < MIN_INTERVAL) {\n      return this;\n    }\n    this.pollInterval = interval;\n    return this;\n  }\n\n  public void updateMyselfServiceId(String myselfServiceId) {\n    this.myselfServiceId = myselfServiceId;\n  }\n\n  public void startDiscovery() {\n    if (!started) {\n      started = true;\n      startTask(new PullInstanceTask());\n    }\n  }\n\n  public void registerIfNotPresent(SubscriptionKey subscriptionKey) {\n    if (this.instancesCache.get(subscriptionKey) == null) {\n      synchronized (lock) {\n        if (this.instancesCache.get(subscriptionKey) == null) {\n          SubscriptionValue value = new SubscriptionValue();\n          pullInstance(subscriptionKey, value, false);\n          this.instancesCache.put(subscriptionKey, value);\n        }\n      }\n    }\n  }\n\n  public List<MicroserviceInstance> getInstanceCache(SubscriptionKey key) {\n    return this.instancesCache.get(key).instancesCache;\n  }\n\n  @Subscribe\n  public void onPullInstanceEvent(PullInstanceEvent event) {\n    // to avoid too many pulls queued.\n    if (pullInstanceTaskOnceInProgress) {\n      return;\n    }\n    pullInstanceTaskOnceInProgress = true;\n    startTask(new PullInstanceOnceTask());\n  }\n\n  private void pullInstance(SubscriptionKey k, SubscriptionValue v, boolean sendChangedEvent) {\n    if (myselfServiceId == null) {\n      // registration not ready\n      return;\n    }\n\n    try {\n      FindMicroserviceInstancesResponse instancesResponse = serviceCenterClient\n          .findMicroserviceInstance(myselfServiceId, k.appId, k.serviceName, ALL_VERSION, v.revision);\n      if (instancesResponse.isModified()) {\n        List<MicroserviceInstance> instances = instancesResponse.getMicroserviceInstancesResponse().getInstances()\n            == null ? Collections.emptyList() : instancesResponse.getMicroserviceInstancesResponse().getInstances();\n        setMicroserviceInfo(instances);\n        LOGGER.info(\"Instance changed event. \"\n                + \"Current: revision={}, instances={}. \"\n                + \"Origin: revision={}, instances={}. \"\n                + \"appId={}, serviceName={}.\",\n            instancesResponse.getRevision(),\n            instanceToString(instances),\n            v.revision,\n            instanceToString(v.instancesCache),\n            k.appId,\n            k.serviceName\n        );\n        v.instancesCache = instances;\n        v.revision = instancesResponse.getRevision();\n        if (sendChangedEvent) {\n          eventBus.post(new InstanceChangedEvent(k.appId, k.serviceName,\n              v.instancesCache));\n        }\n      }\n    } catch (Exception e) {\n      LOGGER.warn(\"find service {}#{} instance failed, remaining local instances cache [{}], cause message: {}\",\n          k.appId, k.serviceName, instanceToString(v.instancesCache), e.getMessage());\n    }\n  }\n\n  private void setMicroserviceInfo(List<MicroserviceInstance> instances) {\n    instances.forEach(instance -> {\n      Microservice microservice = microserviceCache\n          .computeIfAbsent(instance.getServiceId(), id -> {\n            try {\n              return serviceCenterClient.getMicroserviceByServiceId(id);\n            } catch (Exception e) {\n              LOGGER.error(\"Find microservice by id={} failed\", id, e);\n              throw e;\n            }\n          });\n      instance.setMicroservice(microservice);\n    });\n  }\n\n  class PullInstanceTask implements Task {\n    @Override\n    public void execute() {\n      pullAllInstance();\n\n      startTask(new BackOffSleepTask(buildPollIntervalWithSalt(), new PullInstanceTask()));\n    }\n  }\n\n  private long buildPollIntervalWithSalt() {\n    int positive = random.nextInt(5);\n    int sign = random.nextBoolean() ? 1 : -1;\n    long currentPollInterval = pollInterval + sign * positive * 1000;\n    return currentPollInterval > 0 ? currentPollInterval : pollInterval;\n  }\n\n  class PullInstanceOnceTask implements Task {\n    @Override\n    public void execute() {\n      try {\n        pullAllInstance();\n      } finally {\n        pullInstanceTaskOnceInProgress = false;\n      }\n    }\n  }\n\n  private synchronized void pullAllInstance() {\n    instancesCache.forEach((k, v) -> {\n      pullInstance(k, v, true);\n    });\n  }\n\n  private static String instanceToString(List<MicroserviceInstance> instances) {\n    if (instances == null) {\n      return \"\";\n    }\n\n    StringBuilder sb = new StringBuilder();\n    for (MicroserviceInstance instance : instances) {\n      for (String endpoint : instance.getEndpoints()) {\n        sb.append(endpoint.length() > 64 ? endpoint.substring(0, 64) : endpoint);\n        sb.append(\"|\");\n      }\n      sb.append(instance.getStatus());\n      sb.append(\"|\");\n    }\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.service.center.client.exception.OperationException;\nimport org.apache.servicecomb.service.center.client.model.CreateSchemaRequest;\nimport org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse;\nimport org.apache.servicecomb.service.center.client.model.Framework;\nimport org.apache.servicecomb.service.center.client.model.HeartbeatsRequest;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstancesResponse;\nimport org.apache.servicecomb.service.center.client.model.MicroservicesResponse;\nimport org.apache.servicecomb.service.center.client.model.ModifySchemasRequest;\nimport org.apache.servicecomb.service.center.client.model.RbacTokenRequest;\nimport org.apache.servicecomb.service.center.client.model.RbacTokenResponse;\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\n\npublic interface ServiceCenterOperation {\n  /**\n   * Query service center instances.\n   *\n   * In configuration file, only one address of service center instances can be configured, and\n   * other instances can be discovered by calling this method.\n   *\n   * @return MicroserviceInstancesResponse\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  MicroserviceInstancesResponse getServiceCenterInstances();\n\n  /**\n   * Register microservcie.\n   *\n   * @return RegisterMicroserviceResponse\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  RegisteredMicroserviceResponse registerMicroservice(Microservice microservice);\n\n  /**\n   * find all registered microservice of service-center.\n   *\n   * @return MicroserviceResponse\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  MicroservicesResponse getMicroserviceList();\n\n  /**\n   * Get microservice information by service id.\n   *\n   * @return Microservice\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  Microservice getMicroserviceByServiceId(String serviceId);\n\n  /**\n   * query Microservice ID by appId, serviceName, version and environment.\n   *\n   * @return Microservice ID, null if microservice does not exists.\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  RegisteredMicroserviceResponse queryServiceId(Microservice microservice);\n\n  /**\n   * Register microservice instances to service-center\n   *\n   * Notice: microserviceInstance' service id must be set before calling this method.\n   *\n   * @return instanceId\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  RegisteredMicroserviceInstanceResponse registerMicroserviceInstance(MicroserviceInstance microserviceInstance);\n\n  /**\n   * Find microservice instances of service-center\n   *\n   * @return MicroserviceInstancesResponse\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  MicroserviceInstancesResponse getMicroserviceInstanceList(String serviceId);\n\n  /**\n   * Get microservice instance by id\n   *\n   * @return MicroserviceInstance\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  MicroserviceInstance getMicroserviceInstance(String serviceId, String instanceId);\n\n  /**\n   * Find MicroserviceInstance by properties.\n   *\n   * @return FindMicroserviceInstancesResponse\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.n\n   */\n  FindMicroserviceInstancesResponse findMicroserviceInstance(String consumerId, String appId, String serviceName,\n      String versionRule,\n      String revision);\n\n  /**\n   * Delete a microservice instance\n   *\n   * @throws OperationException\n   */\n  void deleteMicroserviceInstance(String serviceId, String instanceId);\n\n  /**\n   * Update status of microservice Instance\n   *\n   * @return if update is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  boolean updateMicroserviceInstanceStatus(String serviceId, String instanceId,\n      MicroserviceInstanceStatus status);\n\n  /**\n   * register schema.\n   * @return if register is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  boolean registerSchema(String serviceId, String schemaId, CreateSchemaRequest schema);\n\n  /**\n   * update schema context of service\n   *\n   * @return if update is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  boolean updateServiceSchemaContext(String serviceId, SchemaInfo schemaInfo);\n\n  /**\n   * batch update schema context of service\n   *\n   * @return if update is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  boolean batchUpdateServiceSchemaContext(String serviceId, ModifySchemasRequest modifySchemasRequest);\n\n  /**\n   * Batch send heartbeats to service-center\n   *\n   * @param heartbeatsRequest\n   * @throws OperationException\n   */\n  void sendHeartBeats(HeartbeatsRequest heartbeatsRequest);\n\n  /**\n   * send heart beat of this instance.\n   * @return if heartbeat is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  boolean sendHeartBeat(String serviceId, String instanceId);\n\n  /**\n   * Get schemas list of service\n   *\n   * @throws OperationException\n   */\n   List<SchemaInfo> getServiceSchemasList(String serviceId, boolean withContent);\n\n  /**\n   * query token using user confidential\n   *\n   * @return if heartbeat is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  RbacTokenResponse queryToken(RbacTokenRequest request, String host);\n\n  /**\n   * Update properties of microservice\n   *\n   * @return if update is successful\n   * @throws OperationException If some problems happened to contact service center or non http 200 returned.\n   */\n  boolean updateMicroserviceProperties(String microserviceId, Map<String, String> serviceProperties,\n      Framework framework);\n\n  /**\n   * Check serviceCenter isolation address available\n   */\n  void checkIsolationAddressAvailable();\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client;\r\n\r\nimport java.io.IOException;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\nimport org.apache.commons.lang3.StringUtils;\r\nimport org.apache.http.HttpStatus;\r\nimport org.apache.servicecomb.http.client.common.HttpRequest;\r\nimport org.apache.servicecomb.http.client.common.HttpResponse;\r\nimport org.apache.servicecomb.http.client.common.HttpTransport;\r\nimport org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;\r\nimport org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\npublic class ServiceCenterRawClient {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterRawClient.class);\r\n\r\n  private static final String HEADER_TENANT_NAME = \"x-domain-name\";\r\n\r\n  private static final String ADDRESS_CHECK_PATH = \"/v4/default/registry/health/readiness\";\r\n\r\n  private final String tenantName;\r\n\r\n  private final HttpTransport httpTransport;\r\n\r\n  private final ServiceCenterAddressManager addressManager;\r\n\r\n  private EventBus eventBus;\r\n\r\n  private ServiceCenterRawClient(String tenantName, HttpTransport httpTransport,\r\n      ServiceCenterAddressManager addressManager) {\r\n    this.httpTransport = httpTransport;\r\n    this.tenantName = tenantName;\r\n    this.addressManager = addressManager;\r\n  }\r\n\r\n  public void setEventBus(EventBus eventBus) {\r\n    this.eventBus = eventBus;\r\n  }\r\n\r\n  public HttpResponse getHttpRequest(String url, Map<String, String> headers, String content) throws IOException {\r\n    return doHttpRequest(url, false, headers, content, HttpRequest.GET, \"\");\r\n  }\r\n\r\n  public HttpResponse postHttpRequestAbsoluteUrl(String url, Map<String, String> headers, String content,\r\n      String address) throws IOException {\r\n    return doHttpRequest(url, true, headers, content, HttpRequest.POST, address);\r\n  }\r\n\r\n  public HttpResponse postHttpRequest(String url, Map<String, String> headers, String content) throws IOException {\r\n    return doHttpRequest(url, false, headers, content, HttpRequest.POST, \"\");\r\n  }\r\n\r\n  public HttpResponse putHttpRequest(String url, Map<String, String> headers, String content) throws IOException {\r\n    return doHttpRequest(url, false, headers, content, HttpRequest.PUT, \"\");\r\n  }\r\n\r\n  public HttpResponse deleteHttpRequest(String url, Map<String, String> headers, String content) throws IOException {\r\n    return doHttpRequest(url, false, headers, content, HttpRequest.DELETE, \"\");\r\n  }\r\n\r\n  private HttpResponse doHttpRequest(String url, boolean absoluteUrl, Map<String, String> headers, String content,\r\n      String method, String queryAddress) throws IOException {\r\n    String address = StringUtils.isEmpty(queryAddress) ? addressManager.address() : queryAddress;\r\n    String formatUrl = addressManager.formatUrl(url, absoluteUrl, address);\r\n    HttpRequest httpRequest = buildHttpRequest(formatUrl, headers, content, method);\r\n    HttpResponse httpResponse;\r\n    try {\r\n      httpResponse = httpTransport.doRequest(httpRequest);\r\n      recordAndSendUnAuthorizedEvent(httpResponse, address);\r\n      return httpResponse;\r\n    } catch (IOException e) {\r\n      addressManager.recordFailState(address);\r\n      String retryAddress = addressManager.address();\r\n      formatUrl = addressManager.formatUrl(url, absoluteUrl, retryAddress);\r\n      LOGGER.warn(\"send request to {} failed and retry to {} once. \", address, retryAddress, e);\r\n      httpRequest = new HttpRequest(formatUrl, headers, content, method);\r\n      try {\r\n        httpResponse = httpTransport.doRequest(httpRequest);\r\n        recordAndSendUnAuthorizedEvent(httpResponse, retryAddress);\r\n        return httpResponse;\r\n      } catch (IOException ioException) {\r\n        addressManager.recordFailState(retryAddress);\r\n        LOGGER.warn(\"retry to {} failed again. \", retryAddress, e);\r\n        throw ioException;\r\n      }\r\n    }\r\n  }\r\n\r\n  private void recordAndSendUnAuthorizedEvent(HttpResponse response, String address) {\r\n    if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {\r\n      LOGGER.warn(\"request unauthorized from server [{}], message [{}]\", address, response.getMessage());\r\n      addressManager.recordFailState(address);\r\n      this.eventBus.post(new UnAuthorizedOperationEvent(address));\r\n    } else {\r\n      addressManager.recordSuccessState(address);\r\n    }\r\n  }\r\n\r\n  public void checkAddressAvailable(String address) {\r\n    ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH);\r\n  }\r\n\r\n  private HttpRequest buildHttpRequest(String url, Map<String, String> headers, String content, String method) {\r\n    if (headers == null) {\r\n      headers = new HashMap<>();\r\n    }\r\n    headers.put(HEADER_TENANT_NAME, tenantName);\r\n    return new HttpRequest(url, headers, content, method);\r\n  }\r\n\r\n  public static class Builder {\r\n    private String tenantName;\r\n\r\n    private HttpTransport httpTransport;\r\n\r\n    private ServiceCenterAddressManager addressManager;\r\n\r\n    public Builder() {\r\n    }\r\n\r\n    public Builder setTenantName(String tenantName) {\r\n      this.tenantName = tenantName;\r\n      return this;\r\n    }\r\n\r\n    public Builder setHttpTransport(HttpTransport httpTransport) {\r\n      this.httpTransport = httpTransport;\r\n      return this;\r\n    }\r\n\r\n    public Builder setAddressManager(ServiceCenterAddressManager addressManager) {\r\n      this.addressManager = addressManager;\r\n      return this;\r\n    }\r\n\r\n    public ServiceCenterRawClient build() {\r\n      return new ServiceCenterRawClient(tenantName, httpTransport, addressManager);\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.http.client.task.AbstractTask;\nimport org.apache.servicecomb.http.client.task.Task;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.HeartBeatEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.MicroserviceInstanceRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.MicroserviceRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.SchemaRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.model.CreateSchemaRequest;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\nimport org.apache.servicecomb.service.center.client.model.ServiceCenterConfiguration;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.EventBus;\n\npublic class ServiceCenterRegistration extends AbstractTask {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterRegistration.class);\n\n  public static final int MAX_INTERVAL = 600000;\n\n  public static final int MIN_INTERVAL = 1000;\n\n  private final ServiceCenterClient serviceCenterClient;\n\n  private final EventBus eventBus;\n\n  private Microservice microservice;\n\n  private MicroserviceInstance microserviceInstance;\n\n  private List<SchemaInfo> schemaInfos = new ArrayList<>();\n\n  private final ServiceCenterConfiguration serviceCenterConfiguration;\n\n  private long heartBeatInterval = 15000;\n\n  private long heartBeatRequestTimeout = 5000;\n\n  public ServiceCenterRegistration(ServiceCenterClient serviceCenterClient, ServiceCenterConfiguration\n      serviceCenterConfiguration, EventBus eventBus) {\n    super(\"service-center-registration-task\");\n    this.serviceCenterClient = serviceCenterClient;\n    this.serviceCenterConfiguration = serviceCenterConfiguration;\n    this.eventBus = eventBus;\n  }\n\n  public ServiceCenterRegistration setMicroserviceInstance(MicroserviceInstance microserviceInstance) {\n    this.microserviceInstance = microserviceInstance;\n    return this;\n  }\n\n  public ServiceCenterRegistration setMicroservice(Microservice microservice) {\n    this.microservice = microservice;\n    return this;\n  }\n\n  public ServiceCenterRegistration setHeartBeatInterval(long interval) {\n    if (interval > MAX_INTERVAL || interval < MIN_INTERVAL) {\n      return this;\n    }\n    this.heartBeatInterval = interval;\n    return this;\n  }\n\n  public ServiceCenterRegistration setHeartBeatRequestTimeout(long timeout) {\n    if (timeout > MAX_INTERVAL || timeout < MIN_INTERVAL) {\n      return this;\n    }\n    this.heartBeatRequestTimeout = timeout;\n    return this;\n  }\n\n  public ServiceCenterRegistration setSchemaInfos(List<SchemaInfo> schemaInfos) {\n    this.schemaInfos = schemaInfos;\n    return this;\n  }\n\n  public ServiceCenterRegistration addSchemaInfo(SchemaInfo schemaInfo) {\n    this.schemaInfos.add(schemaInfo);\n    return this;\n  }\n\n  public List<SchemaInfo> getSchemaInfos() {\n    return this.schemaInfos;\n  }\n\n  public void startRegistration() {\n    startTask(new RegisterMicroserviceTask(0));\n    schedulerCheckAddressAvailable(\"sc-addr-check\", new CheckAddressTask(), heartBeatInterval);\n  }\n\n  class RegisterMicroserviceTask implements Task {\n    int failedCount;\n\n    RegisterMicroserviceTask(int failedCount) {\n      this.failedCount = failedCount;\n    }\n\n    @Override\n    public void execute() {\n      try {\n        RegisteredMicroserviceResponse serviceResponse = serviceCenterClient.queryServiceId(microservice);\n        if (serviceResponse == null) {\n          RegisteredMicroserviceResponse response = serviceCenterClient.registerMicroservice(microservice);\n          if (StringUtils.isEmpty(response.getServiceId())) {\n            LOGGER.error(\"register microservice failed, and will try again.\");\n            eventBus.post(new MicroserviceRegistrationEvent(false, microservice));\n            startTask(new BackOffSleepTask(failedCount + 1, new RegisterMicroserviceTask(failedCount + 1)));\n            return;\n          }\n          microservice.setServiceId(response.getServiceId());\n          microserviceInstance.setServiceId(response.getServiceId());\n          microserviceInstance.setMicroservice(microservice);\n          eventBus.post(new MicroserviceRegistrationEvent(true, microservice));\n          startTask(new RegisterSchemaTask(0));\n        } else {\n          Microservice newMicroservice = serviceCenterClient.getMicroserviceByServiceId(serviceResponse.getServiceId());\n\n          Map<String, String> propertiesTemp = microservice.getProperties();\n          microservice.setProperties(newMicroservice.getProperties());\n          microservice.getProperties().putAll(propertiesTemp);\n          if (serviceCenterClient.updateMicroserviceProperties(serviceResponse.getServiceId(),\n              microservice.getProperties(), microservice.getFramework())) {\n            LOGGER.info(\n                \"microservice is already registered. Update microservice properties successfully. properties=[{}], \"\n                    + \"frameworkVersion [{}]\", microservice.getProperties(), microservice.getFramework().getVersion());\n          } else {\n            LOGGER.error(\"microservice is already registered. Update microservice properties failed. properties=[{}], \"\n                    + \"frameworkVersion [{}]\", microservice.getProperties(), microservice.getFramework().getVersion());\n          }\n\n          microservice.setServiceId(serviceResponse.getServiceId());\n          microserviceInstance.setServiceId(serviceResponse.getServiceId());\n          microserviceInstance.setMicroservice(microservice);\n          if (isSwaggerDifferent(newMicroservice)) {\n            if (serviceCenterConfiguration.isCanOverwriteSwagger()) {\n              LOGGER.warn(\"Service has already registered, but schema ids not equal, try to register it again\");\n              eventBus.post(new MicroserviceRegistrationEvent(true, microservice));\n              startTask(new RegisterSchemaTask(0));\n              return;\n            }\n            if (serviceCenterConfiguration.isIgnoreSwaggerDifferent()) {\n              LOGGER.warn(\"Service has already registered, but schema ids not equal. Ignore and continue to register\");\n            } else {\n              throw new IllegalStateException(\n                  \"Service has already registered, but schema ids not equal, stop register. \"\n                      + \"Change the microservice version or delete the old microservice info and try again.\");\n            }\n          }\n          eventBus.post(new MicroserviceRegistrationEvent(true, microservice));\n          startTask(new RegisterMicroserviceInstanceTask(0));\n        }\n      } catch (IllegalStateException e) {\n        throw e;\n      } catch (Exception e) {\n        LOGGER.error(\"register microservice failed, and will try again.\", e);\n        eventBus.post(new MicroserviceRegistrationEvent(false, microservice));\n        startTask(new BackOffSleepTask(failedCount + 1, new RegisterMicroserviceTask(failedCount + 1)));\n      }\n    }\n  }\n\n  private boolean isSwaggerDifferent(Microservice newMicroservice) {\n    return !isListEquals(newMicroservice.getSchemas(), microservice.getSchemas());\n  }\n\n  private boolean isListEquals(List<String> one, List<String> two) {\n    return one.size() == two.size() && one.containsAll(two) && two.containsAll(one);\n  }\n\n  class RegisterSchemaTask implements Task {\n    int failedCount;\n\n    RegisterSchemaTask(int failedCount) {\n      this.failedCount = failedCount;\n    }\n\n    @Override\n    public void execute() {\n      try {\n        if (schemaInfos == null || schemaInfos.isEmpty()) {\n          LOGGER.warn(\"no schemas defined for this microservice.\");\n          eventBus.post(new SchemaRegistrationEvent(true, microservice));\n          startTask(new RegisterMicroserviceInstanceTask(0));\n          return;\n        }\n\n        for (SchemaInfo schemaInfo : schemaInfos) {\n          CreateSchemaRequest request = new CreateSchemaRequest();\n          request.setSchema(schemaInfo.getSchema());\n          request.setSummary(schemaInfo.getSummary());\n          if (!serviceCenterClient.registerSchema(microservice.getServiceId(), schemaInfo.getSchemaId(), request)) {\n            LOGGER.error(\"register schema content failed, and will try again.\");\n            eventBus.post(new SchemaRegistrationEvent(false, microservice));\n            // back off by multiply\n            startTask(new BackOffSleepTask(failedCount + 1, new RegisterSchemaTask((failedCount + 1) * 2)));\n            return;\n          }\n        }\n\n        eventBus.post(new SchemaRegistrationEvent(true, microservice));\n        startTask(new RegisterMicroserviceInstanceTask(0));\n      } catch (Exception e) {\n        LOGGER.error(\"register schema content failed, and will try again.\", e);\n        eventBus.post(new SchemaRegistrationEvent(false, microservice));\n        // back off by multiply\n        startTask(new BackOffSleepTask(failedCount + 1, new RegisterSchemaTask((failedCount + 1) * 2)));\n      }\n    }\n  }\n\n  class RegisterMicroserviceInstanceTask implements Task {\n    int failedCount;\n\n    RegisterMicroserviceInstanceTask(int failedCount) {\n      this.failedCount = failedCount;\n    }\n\n    @Override\n    public void execute() {\n      try {\n        RegisteredMicroserviceInstanceResponse instance = serviceCenterClient\n            .registerMicroserviceInstance(microserviceInstance);\n        if (instance == null) {\n          LOGGER.error(\"register microservice instance failed, and will try again.\");\n          eventBus.post(new MicroserviceInstanceRegistrationEvent(false, microservice, microserviceInstance));\n          startTask(new BackOffSleepTask(failedCount + 1, new RegisterMicroserviceInstanceTask(failedCount + 1)));\n        } else {\n          microserviceInstance.setInstanceId(instance.getInstanceId());\n          LOGGER.info(\"register microservice successfully, service id={}, instance id={}\", microservice.getServiceId(),\n              microserviceInstance.getInstanceId());\n          eventBus.post(new MicroserviceInstanceRegistrationEvent(true, microservice, microserviceInstance));\n          startTask(new SendHeartBeatTask(0));\n        }\n      } catch (Exception e) {\n        LOGGER.error(\"register microservice instance failed, and will try again.\", e);\n        eventBus.post(new MicroserviceInstanceRegistrationEvent(false, microservice, microserviceInstance));\n        startTask(new BackOffSleepTask(failedCount + 1, new RegisterMicroserviceInstanceTask(failedCount + 1)));\n      }\n    }\n  }\n\n  class SendHeartBeatTask implements Task {\n    private static final int FAILED_RETRY = 3;\n\n    int failedCount;\n\n    SendHeartBeatTask(int failedCount) {\n      this.failedCount = failedCount;\n    }\n\n    @Override\n    public void execute() {\n      try {\n        if (failedCount >= FAILED_RETRY) {\n          eventBus.post(new HeartBeatEvent(false, microservice, microserviceInstance));\n          startTask(new RegisterMicroserviceTask(0));\n          return;\n        }\n\n        if (!serviceCenterClient.sendHeartBeat(microservice.getServiceId(), microserviceInstance.getInstanceId())) {\n          LOGGER.warn(\"send heart failed, and will try again.\");\n          eventBus.post(new HeartBeatEvent(false, microservice, microserviceInstance));\n          startTask(new BackOffSleepTask(failedCount + 1, new SendHeartBeatTask(failedCount + 1)));\n        } else {\n          // wait 10 * 3000 ms and send heart beat again.\n          eventBus.post(new HeartBeatEvent(true, microservice, microserviceInstance));\n          startTask(\n              new BackOffSleepTask(Math.max(heartBeatInterval, heartBeatRequestTimeout), new SendHeartBeatTask(0)));\n        }\n      } catch (Exception e) {\n        // If heartbeat failures three times, log error stack help troubleshooting. Others just log message as warn.\n        if (failedCount == 2) {\n          LOGGER.error(\"send heart failed, and will try again.\", e);\n        } else {\n          LOGGER.warn(\"send heart failed, and will try again. message [{}]\", e.getMessage());\n        }\n        eventBus.post(new HeartBeatEvent(false, microservice, microserviceInstance));\n        startTask(new BackOffSleepTask(failedCount + 1, new SendHeartBeatTask(failedCount + 1)));\n      }\n    }\n  }\n\n  class CheckAddressTask implements Runnable {\n    @Override\n    public void run() {\n      serviceCenterClient.checkIsolationAddressAvailable();\n    }\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.auth.SignRequest;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.apache.servicecomb.http.client.common.WebSocketListener;\nimport org.apache.servicecomb.http.client.common.WebSocketTransport;\nimport org.apache.servicecomb.service.center.client.DiscoveryEvents.PullInstanceEvent;\nimport org.java_websocket.handshake.ServerHandshake;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.EventBus;\n\npublic class ServiceCenterWatch implements WebSocketListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterWatch.class);\n\n  private static final String HTTP = \"http://\";\n\n  private static final String HTTPS = \"https://\";\n\n  private static final String WS = \"ws://\";\n\n  private static final String WSS = \"wss://\";\n\n  private static final String WATCH = \"/v4/%s/registry/microservices/%s/watcher\";\n\n  private static final long SLEEP_BASE = 3000;\n\n  private static final long SLEEP_MAX = 10 * 60 * 10000;\n\n  private final ServiceCenterAddressManager addressManager;\n\n  private final SSLProperties sslProperties;\n\n  private final RequestAuthHeaderProvider requestAuthHeaderProvider;\n\n  private final String tenantName;\n\n  private final Map<String, String> extraGlobalHeaders;\n\n  private WebSocketTransport webSocketTransport;\n\n  private String project;\n\n  private String serviceId;\n\n  private AtomicInteger continuousError = new AtomicInteger(0);\n\n  private final AtomicBoolean reconnecting = new AtomicBoolean(false);\n\n  private final EventBus eventBus;\n\n  private String currentServerUri;\n\n  private final ExecutorService connector = Executors.newFixedThreadPool(1, (r) -> new\n      Thread(r, \"web-socket-connector\"));\n\n  public ServiceCenterWatch(ServiceCenterAddressManager addressManager,\n      SSLProperties sslProperties,\n      RequestAuthHeaderProvider requestAuthHeaderProvider,\n      String tenantName,\n      Map<String, String> extraGlobalHeaders,\n      EventBus eventBus) {\n    this.addressManager = addressManager;\n    this.sslProperties = sslProperties;\n    this.requestAuthHeaderProvider = requestAuthHeaderProvider;\n    this.tenantName = tenantName;\n    this.extraGlobalHeaders = extraGlobalHeaders;\n    this.eventBus = eventBus;\n  }\n\n  public void startWatch(String project, String serviceId) {\n    this.project = project;\n    this.serviceId = serviceId;\n\n    startWatch();\n  }\n\n  private void startWatch() {\n    connector.submit(() -> {\n      backOff();\n      String address = addressManager.address();\n      try {\n        Map<String, String> headers = new HashMap<>();\n        headers.put(\"x-domain-name\", this.tenantName);\n        headers.putAll(this.extraGlobalHeaders);\n        headers.putAll(this.requestAuthHeaderProvider.loadAuthHeader(createSignRequest(address)));\n        currentServerUri = convertAddress(address);\n        LOGGER.info(\"start watch to address {}\", currentServerUri);\n        webSocketTransport = new WebSocketTransport(currentServerUri, sslProperties,\n            headers, this);\n        webSocketTransport.connectBlocking();\n        addressManager.recordSuccessState(address);\n      } catch (Exception e) {\n        addressManager.recordFailState(address);\n        LOGGER.error(\"start watch failed. \", e);\n      }\n    });\n  }\n\n  private SignRequest createSignRequest(String url) {\n    try {\n      URI uri = URI.create(url);\n      SignRequest signRequest = new SignRequest();\n      signRequest.setEndpoint(uri);\n      return signRequest;\n    } catch (Exception e) {\n      return null;\n    }\n  }\n\n  private String convertAddress(String address) {\n    String url = String.format(WATCH, project, serviceId);\n    if (address.startsWith(HTTP)) {\n      return WS + address.substring(HTTP.length()) + url;\n    }\n\n    if (address.startsWith(HTTPS)) {\n      return WSS + address.substring(HTTPS.length()) + url;\n    }\n    return address + url;\n  }\n\n  public void stop() {\n    if (webSocketTransport != null) {\n      webSocketTransport.close();\n    }\n  }\n\n  private void reconnect() {\n    if (reconnecting.getAndSet(true)) {\n      return;\n    }\n    continuousError.incrementAndGet();\n    if (webSocketTransport != null) {\n      webSocketTransport.close();\n    }\n    startWatch();\n  }\n\n  private void backOff() {\n    if (this.continuousError.get() <= 0) {\n      return;\n    }\n    try {\n      Thread.sleep(Math.min(SLEEP_MAX, this.continuousError.get() * this.continuousError.get() * SLEEP_BASE));\n    } catch (InterruptedException e) {\n      // do not care\n    }\n  }\n\n  @Override\n  public void onMessage(String s) {\n    LOGGER.info(\"web socket receive message [{}], start query instance\", s);\n    this.eventBus.post(new PullInstanceEvent());\n  }\n\n  @Override\n  public void onError(Exception e) {\n    LOGGER.warn(\"web socket receive error [{}], will restart.\", e.getMessage());\n    reconnect();\n  }\n\n  @Override\n  public void onClose(int code, String reason, boolean remote) {\n    LOGGER.warn(\"web socket closed, code={}, reason={}.\", code, reason);\n  }\n\n  @Override\n  public void onOpen(ServerHandshake serverHandshake) {\n    LOGGER.info(\"web socket connected to server {}, status={}, message={}\", currentServerUri,\n        serverHandshake.getHttpStatus(),\n        serverHandshake.getHttpStatusMessage());\n    continuousError.set(0);\n    reconnecting.set(false);\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/exception/OperationException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.exception;\n\npublic class OperationException extends RuntimeException {\n\n  private static final long serialVersionUID = 1L;\n\n  public OperationException() {\n  }\n\n  public OperationException(String message) {\n    super(message);\n  }\n\n  public OperationException(String message, Throwable cause) {\n    super(message, cause);\n  }\n\n  public OperationException(Throwable cause) {\n    super(cause);\n  }\n\n  public OperationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {\n    super(message, cause, enableSuppression, writableStackTrace);\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/BasePath.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\nimport java.util.Map;\r\n\r\npublic class BasePath {\r\n  private String path;\r\n\r\n  private Map<String, String> property;\r\n\r\n  public Map<String, String> getProperty() {\r\n    return property;\r\n  }\r\n\r\n  public void setProperty(Map<String, String> property) {\r\n    this.property = property;\r\n  }\r\n\r\n  public String getPath() {\r\n    return path;\r\n  }\r\n\r\n  public void setPath(String path) {\r\n    this.path = path;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/CreateMicroserviceInstanceRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class CreateMicroserviceInstanceRequest {\n  private MicroserviceInstance instance;\n\n  public MicroserviceInstance getInstance() {\n    return instance;\n  }\n\n  public void setInstance(MicroserviceInstance instance) {\n    this.instance = instance;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/CreateMicroserviceRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class CreateMicroserviceRequest {\n  private Microservice service;\n\n  public Microservice getService() {\n    return service;\n  }\n\n  public void setService(Microservice service) {\n    this.service = service;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/CreateSchemaRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class CreateSchemaRequest {\n  private String schema;\n\n  private String summary;\n\n  public String getSchema() {\n    return schema;\n  }\n\n  public void setSchema(String schema) {\n    this.schema = schema;\n  }\n\n  public String getSummary() {\n    return summary;\n  }\n\n  public void setSummary(String summary) {\n    this.summary = summary;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/DataCenterInfo.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic class DataCenterInfo {\r\n\r\n  private String name;\r\n\r\n  private String region;\r\n\r\n  private String availableZone;\r\n\r\n  public String getName() {\r\n    return name;\r\n  }\r\n\r\n  public void setName(String name) {\r\n    this.name = name;\r\n  }\r\n\r\n  public String getRegion() {\r\n    return region;\r\n  }\r\n\r\n  public void setRegion(String region) {\r\n    this.region = region;\r\n  }\r\n\r\n  public String getAvailableZone() {\r\n    return availableZone;\r\n  }\r\n\r\n  public void setAvailableZone(String availableZone) {\r\n    this.availableZone = availableZone;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/ErrorMessage.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class ErrorMessage {\n  private String errorCode;\n\n  private String errorMessage;\n\n  private String detail;\n\n  public String getErrorCode() {\n    return errorCode;\n  }\n\n  public void setErrorCode(String errorCode) {\n    this.errorCode = errorCode;\n  }\n\n  public String getErrorMessage() {\n    return errorMessage;\n  }\n\n  public void setErrorMessage(String errorMessage) {\n    this.errorMessage = errorMessage;\n  }\n\n  public String getDetail() {\n    return detail;\n  }\n\n  public void setDetail(String detail) {\n    this.detail = detail;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/FindMicroserviceInstancesResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class FindMicroserviceInstancesResponse {\n  private boolean modified;\n\n  private String revision;\n\n  private MicroserviceInstancesResponse microserviceInstancesResponse;\n\n  public boolean isModified() {\n    return modified;\n  }\n\n  public void setModified(boolean modified) {\n    this.modified = modified;\n  }\n\n  public String getRevision() {\n    return revision;\n  }\n\n  public void setRevision(String revision) {\n    this.revision = revision;\n  }\n\n  public MicroserviceInstancesResponse getMicroserviceInstancesResponse() {\n    return microserviceInstancesResponse;\n  }\n\n  public void setMicroserviceInstancesResponse(\n      MicroserviceInstancesResponse microserviceInstancesResponse) {\n    this.microserviceInstancesResponse = microserviceInstancesResponse;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/Framework.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic class Framework {\r\n  private String name;\r\n\r\n  private String version;\r\n\r\n  public String getName() {\r\n    return name;\r\n  }\r\n\r\n  public void setName(String name) {\r\n    this.name = name;\r\n  }\r\n\r\n  public String getVersion() {\r\n    return version;\r\n  }\r\n\r\n  public void setVersion(String version) {\r\n    this.version = version;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/GetSchemaListResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\nimport java.util.List;\n\npublic class GetSchemaListResponse {\n  private List<SchemaInfo> schemas;\n\n  public List<SchemaInfo> getSchemas() {\n    return schemas;\n  }\n\n  public void setSchemas(List<SchemaInfo> schemas) {\n    this.schemas = schemas;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/GetSchemaResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class GetSchemaResponse {\n  private String schema;\n\n  public String getSchema() {\n    return schema;\n  }\n\n  public void setSchema(String schema) {\n    this.schema = schema;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/HealthCheck.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic class HealthCheck {\r\n\r\n  private HealthCheckMode mode;\r\n\r\n  private int port;\r\n\r\n  private int interval;\r\n\r\n  private int times;\r\n\r\n  public HealthCheckMode getMode() {\r\n    return mode;\r\n  }\r\n\r\n  public void setMode(HealthCheckMode mode) {\r\n    this.mode = mode;\r\n  }\r\n\r\n  public int getPort() {\r\n    return port;\r\n  }\r\n\r\n  public void setPort(int port) {\r\n    this.port = port;\r\n  }\r\n\r\n  public int getInterval() {\r\n    return interval;\r\n  }\r\n\r\n  public void setInterval(int interval) {\r\n    this.interval = interval;\r\n  }\r\n\r\n  public int getTimes() {\r\n    return times;\r\n  }\r\n\r\n  public void setTimes(int times) {\r\n    this.times = times;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/HealthCheckMode.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic enum HealthCheckMode {\r\n  unknown,\r\n  push,\r\n  pull\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/HeartbeatsRequest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\npublic class HeartbeatsRequest {\r\n  private List<InstancesRequest> Instances;\r\n\r\n  public HeartbeatsRequest(String serviceId, String instanceId) {\r\n    List<InstancesRequest> instances = new ArrayList<>();\r\n    instances.add(new InstancesRequest(serviceId, instanceId));\r\n    this.Instances = instances;\r\n  }\r\n\r\n  public List<InstancesRequest> getInstances() {\r\n    return Instances;\r\n  }\r\n\r\n  public void setInstances(List<InstancesRequest> instances) {\r\n    this.Instances = instances;\r\n  }\r\n\r\n  public void addInstances(InstancesRequest instancesRequest) {\r\n    if (this.Instances != null) {\r\n      this.Instances.add(instancesRequest);\r\n    } else {\r\n      this.Instances = new ArrayList<>();\r\n      this.Instances.add(instancesRequest);\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/InstancesRequest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic class InstancesRequest {\r\n  private String serviceId;\r\n\r\n  private String instanceId;\r\n\r\n  public InstancesRequest(String serviceId, String instanceId) {\r\n    this.serviceId = serviceId;\r\n    this.instanceId = instanceId;\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return serviceId;\r\n  }\r\n\r\n  public void setServiceId(String serviceId) {\r\n    this.serviceId = serviceId;\r\n  }\r\n\r\n  public String getInstanceId() {\r\n    return instanceId;\r\n  }\r\n\r\n  public void setInstanceId(String instanceId) {\r\n    this.instanceId = instanceId;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/Microservice.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport com.fasterxml.jackson.annotation.JsonRootName;\r\n\r\n@JsonRootName(\"service\")\r\npublic class Microservice {\r\n\r\n  private String serviceId;\r\n\r\n  private Framework framework;\r\n\r\n  private String registerBy;\r\n\r\n  private String environment;\r\n\r\n  private String appId;\r\n\r\n  private String serviceName;\r\n\r\n  /**\r\n   * for governance\r\n   * when invoke cross app, if not use alias name, then {microservice}:{schema}:{operation} will conflict\r\n   */\r\n  private String alias;\r\n\r\n  private String version;\r\n\r\n  private String description;\r\n\r\n  private String level;\r\n\r\n  private List<String> schemas = new ArrayList<>();\r\n\r\n  private List<BasePath> paths = new ArrayList<>();\r\n\r\n  private MicroserviceStatus status = MicroserviceStatus.UP;\r\n\r\n  private Map<String, String> properties = new HashMap<>();\r\n\r\n  private List<MicroserviceInstance> instances;\r\n\r\n  private String timestamp;\r\n\r\n  private String modTimestamp;\r\n\r\n  public Microservice() {\r\n\r\n  }\r\n\r\n  public Microservice(String serviceName) {\r\n    this.serviceName = serviceName;\r\n  }\r\n\r\n  public List<MicroserviceInstance> getInstances() {\r\n    return instances;\r\n  }\r\n\r\n  public void setInstances(List<MicroserviceInstance> instances) {\r\n    this.instances = instances;\r\n  }\r\n\r\n  public Framework getFramework() {\r\n    return framework;\r\n  }\r\n\r\n  public void setFramework(Framework framework) {\r\n    this.framework = framework;\r\n  }\r\n\r\n  public String getAlias() {\r\n    return alias;\r\n  }\r\n\r\n  public void setAlias(String alias) {\r\n    this.alias = alias;\r\n  }\r\n\r\n  public String getVersion() {\r\n    return version;\r\n  }\r\n\r\n  public void setVersion(String version) {\r\n    this.version = version;\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return serviceId;\r\n  }\r\n\r\n  public void setServiceId(String serviceId) {\r\n    this.serviceId = serviceId;\r\n  }\r\n\r\n  public String getRegisterBy() {\r\n    return registerBy;\r\n  }\r\n\r\n  public void setRegisterBy(String registerBy) {\r\n    this.registerBy = registerBy;\r\n  }\r\n\r\n  public String getEnvironment() {\r\n    return environment;\r\n  }\r\n\r\n  public void setEnvironment(String environment) {\r\n    this.environment = environment;\r\n  }\r\n\r\n  public String getAppId() {\r\n    return appId;\r\n  }\r\n\r\n  public void setAppId(String appId) {\r\n    this.appId = appId;\r\n  }\r\n\r\n  public String getServiceName() {\r\n    return serviceName;\r\n  }\r\n\r\n  public void setServiceName(String serviceName) {\r\n    this.serviceName = serviceName;\r\n  }\r\n\r\n  public String getDescription() {\r\n    return description;\r\n  }\r\n\r\n  public void setDescription(String description) {\r\n    this.description = description;\r\n  }\r\n\r\n  public String getLevel() {\r\n    return level;\r\n  }\r\n\r\n  public void setLevel(String level) {\r\n    this.level = level;\r\n  }\r\n\r\n  public List<String> getSchemas() {\r\n    return schemas;\r\n  }\r\n\r\n  public void setSchemas(List<String> schemas) {\r\n    this.schemas = schemas;\r\n  }\r\n\r\n  public MicroserviceStatus getStatus() {\r\n    return status;\r\n  }\r\n\r\n  public void setStatus(MicroserviceStatus status) {\r\n    this.status = status;\r\n  }\r\n\r\n  public Map<String, String> getProperties() {\r\n    return properties;\r\n  }\r\n\r\n  public void setProperties(Map<String, String> properties) {\r\n    this.properties = properties;\r\n  }\r\n\r\n  public String getTimestamp() {\r\n    return timestamp;\r\n  }\r\n\r\n  public void setTimestamp(String timestamp) {\r\n    this.timestamp = timestamp;\r\n  }\r\n\r\n  public String getModTimestamp() {\r\n    return modTimestamp;\r\n  }\r\n\r\n  public void setModTimestamp(String modTimestamp) {\r\n    this.modTimestamp = modTimestamp;\r\n  }\r\n\r\n  public List<BasePath> getPaths() {\r\n    return paths;\r\n  }\r\n\r\n  public void setPaths(List<BasePath> paths) {\r\n    this.paths = paths;\r\n  }\r\n\r\n  public void addSchema(String schema) {\r\n    this.schemas.add(schema);\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstance.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport com.fasterxml.jackson.annotation.JsonIgnore;\r\nimport com.fasterxml.jackson.annotation.JsonRootName;\r\n\r\n@JsonRootName(\"instance\")\r\npublic class MicroserviceInstance {\r\n  // even disconnected from service center\r\n  // instanceId will not be changed\r\n  // when register to service center again, use the old instanceId.\r\n  private String instanceId;\r\n\r\n  private String serviceId;\r\n\r\n  private String version;\r\n\r\n  private List<String> endpoints = new ArrayList<>();\r\n\r\n  private String hostName;\r\n\r\n  private MicroserviceInstanceStatus status;\r\n\r\n  private Map<String, String> properties = new HashMap<>(); // reserved key list: region|az|stage|group\r\n\r\n  private HealthCheck healthCheck;\r\n\r\n  private DataCenterInfo dataCenterInfo;\r\n\r\n  private String timestamp;\r\n\r\n  private String modTimestamp;\r\n\r\n  @JsonIgnore\r\n  private Microservice microservice;\r\n\r\n  public String getInstanceId() {\r\n    return instanceId;\r\n  }\r\n\r\n  public void setInstanceId(String instanceId) {\r\n    this.instanceId = instanceId;\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return serviceId;\r\n  }\r\n\r\n  public void setServiceId(String serviceId) {\r\n    this.serviceId = serviceId;\r\n  }\r\n\r\n  public String getVersion() {\r\n    return version;\r\n  }\r\n\r\n  public void setVersion(String version) {\r\n    this.version = version;\r\n  }\r\n\r\n  public List<String> getEndpoints() {\r\n    return endpoints;\r\n  }\r\n\r\n  public void setEndpoints(List<String> endpoints) {\r\n    this.endpoints = endpoints;\r\n  }\r\n\r\n  public String getHostName() {\r\n    return hostName;\r\n  }\r\n\r\n  public void setHostName(String hostName) {\r\n    this.hostName = hostName;\r\n  }\r\n\r\n  public MicroserviceInstanceStatus getStatus() {\r\n    return status;\r\n  }\r\n\r\n  public void setStatus(MicroserviceInstanceStatus status) {\r\n    this.status = status;\r\n  }\r\n\r\n  public HealthCheck getHealthCheck() {\r\n    return healthCheck;\r\n  }\r\n\r\n  public void setHealthCheck(HealthCheck healthCheck) {\r\n    this.healthCheck = healthCheck;\r\n  }\r\n\r\n  public String getTimestamp() {\r\n    return timestamp;\r\n  }\r\n\r\n  public void setTimestamp(String timestamp) {\r\n    this.timestamp = timestamp;\r\n  }\r\n\r\n  public String getModTimestamp() {\r\n    return modTimestamp;\r\n  }\r\n\r\n  public void setModTimestamp(String modTimestamp) {\r\n    this.modTimestamp = modTimestamp;\r\n  }\r\n\r\n  public Map<String, String> getProperties() {\r\n    return properties;\r\n  }\r\n\r\n  public void setProperties(Map<String, String> properties) {\r\n    this.properties = properties;\r\n  }\r\n\r\n  public DataCenterInfo getDataCenterInfo() {\r\n    return dataCenterInfo;\r\n  }\r\n\r\n  public void setDataCenterInfo(DataCenterInfo dataCenterInfo) {\r\n    this.dataCenterInfo = dataCenterInfo;\r\n  }\r\n\r\n  public void setMicroservice(Microservice microservice) {\r\n    this.microservice = microservice;\r\n  }\r\n\r\n  @JsonIgnore\r\n  public Microservice getMicroservice() {\r\n    return this.microservice;\r\n  }\r\n\r\n  @JsonIgnore\r\n  public String getServiceName() {\r\n    return this.microservice.getServiceName();\r\n  }\r\n\r\n  @JsonIgnore\r\n  public String getApplicationName() {\r\n    return this.microservice.getAppId();\r\n  }\r\n\r\n  public void addEndpoint(String endpoint) {\r\n    this.endpoints.add(endpoint);\r\n  }\r\n\r\n  public void addProperty(String key, String value) {\r\n    this.properties.put(key, value);\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstanceResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class MicroserviceInstanceResponse {\n  private MicroserviceInstance instance;\n\n  public MicroserviceInstance getInstance() {\n    return instance;\n  }\n\n  public void setInstance(MicroserviceInstance instance) {\n    this.instance = instance;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstanceStatus.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic enum MicroserviceInstanceStatus {\r\n  STARTING,\r\n  TESTING,\r\n  UP,\r\n  OUTOFSERVICE,\r\n  DOWN,\r\n  UNKNOWN\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceInstancesResponse.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\nimport java.util.List;\r\n\r\npublic class MicroserviceInstancesResponse {\r\n\r\n  private List<MicroserviceInstance> instances;\r\n\r\n  public List<MicroserviceInstance> getInstances() {\r\n    return instances;\r\n  }\r\n\r\n  public void setInstances(List<MicroserviceInstance> instances) {\r\n    this.instances = instances;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class MicroserviceResponse {\n  private Microservice service;\n\n  public Microservice getService() {\n    return service;\n  }\n\n  public void setService(Microservice service) {\n    this.service = service;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroserviceStatus.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\npublic enum MicroserviceStatus {\r\n  UNKNOWN,\r\n  UP,\r\n  DOWN\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/MicroservicesResponse.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client.model;\r\n\r\nimport java.util.List;\r\n\r\npublic class MicroservicesResponse {\r\n\r\n  private List<Microservice> services;\r\n\r\n  public List<Microservice> getServices() {\r\n    return services;\r\n  }\r\n\r\n  public void setServices(List<Microservice> services) {\r\n    this.services = services;\r\n  }\r\n}\r\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/ModifySchemasRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\nimport java.util.List;\n\npublic class ModifySchemasRequest {\n  private List<SchemaInfo> schemas;\n\n  public List<SchemaInfo> getSchemas() {\n    return schemas;\n  }\n\n  public void setSchemas(List<SchemaInfo> schemas) {\n    this.schemas = schemas;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class RbacTokenRequest {\n  private String name;\n\n  private String password;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getPassword() {\n    return password;\n  }\n\n  public void setPassword(String password) {\n    this.password = password;\n  }\n\n  @Override\n  public String toString() {\n    final StringBuilder sb = new StringBuilder(\"RbacTokenRequest{\");\n    sb.append(\"name='\").append(name).append('\\'');\n    sb.append(\", password='\").append(password).append('\\'');\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RbacTokenResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class RbacTokenResponse {\n  private int statusCode;\n\n  private String token;\n\n  private String errorCode;\n\n  public int getStatusCode() {\n    return statusCode;\n  }\n\n  public void setStatusCode(int statusCode) {\n    this.statusCode = statusCode;\n  }\n\n  public String getToken() {\n    return token;\n  }\n\n  public void setToken(String token) {\n    this.token = token;\n  }\n\n  public String getErrorCode() {\n    return errorCode;\n  }\n\n  public void setErrorCode(String errorCode) {\n    this.errorCode = errorCode;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RegisteredMicroserviceInstanceResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class RegisteredMicroserviceInstanceResponse {\n  private String instanceId;\n\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/RegisteredMicroserviceResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class RegisteredMicroserviceResponse {\n  private String serviceId;\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/SchemaInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class SchemaInfo {\n  private String schema;\n\n  private String schemaId;\n\n  private String summary;\n\n  public SchemaInfo() {\n\n  }\n\n  public SchemaInfo(String schemaId, String schema, String summary) {\n    this.schemaId = schemaId;\n    this.schema = schema;\n    this.summary = summary;\n  }\n\n  public String getSchema() {\n    return schema;\n  }\n\n  public void setSchema(String schema) {\n    this.schema = schema;\n  }\n\n  public String getSchemaId() {\n    return schemaId;\n  }\n\n  public void setSchemaId(String schemaId) {\n    this.schemaId = schemaId;\n  }\n\n  public String getSummary() {\n    return summary;\n  }\n\n  public void setSummary(String summary) {\n    this.summary = summary;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/ServiceCenterConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\npublic class ServiceCenterConfiguration {\n\n  /**\n   * for registration service\n   * when swagger is different between local with remote serviceCenter. if ignoreSwaggerDifferent is true.\n   * it will ignore the different and continue the program. otherwise, the program will be stop.\n   */\n  private boolean ignoreSwaggerDifferent;\n\n  private boolean canOverwriteSwagger = true;\n\n  public boolean isIgnoreSwaggerDifferent() {\n    return ignoreSwaggerDifferent;\n  }\n\n  public boolean isCanOverwriteSwagger(){\n    return canOverwriteSwagger;\n  }\n\n  public ServiceCenterConfiguration setIgnoreSwaggerDifferent(boolean ignoreSwaggerDifferent) {\n    this.ignoreSwaggerDifferent = ignoreSwaggerDifferent;\n    return this;\n  }\n\n  public ServiceCenterConfiguration setCanOverwriteSwagger(boolean canOverwriteSwagger) {\n    this.canOverwriteSwagger = canOverwriteSwagger;\n    return this;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/UpdatePropertiesRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client.model;\n\nimport java.util.Map;\n\npublic class UpdatePropertiesRequest {\n  private Map<String, String> properties;\n\n  private Framework framework;\n\n  public Map<String, String> getProperties() {\n    return properties;\n  }\n\n  public void setProperties(Map<String, String> properties) {\n    this.properties = properties;\n  }\n\n  public Framework getFramework() {\n    return framework;\n  }\n\n  public void setFramework(Framework framework) {\n    this.framework = framework;\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\n\nimport com.google.common.eventbus.EventBus;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nclass ServiceCenterAddressManagerTest {\n\n  private static final List<String> addresses = new ArrayList<>();\n\n  private static ServiceCenterAddressManager addressManager1;\n\n  private static ServiceCenterAddressManager addressManager2;\n\n\n  @Test\n  public void getUrlPrefix() {\n    addresses.add(\"http://127.0.0.1:30103\");\n    addressManager1 = new ServiceCenterAddressManager(\"project\", addresses, new EventBus(), \"\", \"\");\n\n    Assertions.assertNotNull(addressManager1);\n\n    List<String> addresses = addressManager1.getAddresses();\n    Assertions.assertEquals(1, addresses.size());\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addresses.get(0));\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v4/\", addressManager1.getUrlPrefix(\"http://127.0.0.1:30103\"));\n  }\n\n  @Test\n  public void formatUrlTest() {\n    addresses.add(\"http://127.0.0.1:30103\");\n    addressManager1 = new ServiceCenterAddressManager(\"project\", addresses, new EventBus(), \"\", \"\");\n    Assertions.assertNotNull(addressManager1);\n\n    String address = addressManager1.address();\n    Assertions.assertEquals(\"http://127.0.0.1:30103\", address);\n    String url = addressManager1.formatUrl(\"/test/\", false, address);\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v4/project/test/\", url);\n\n    url = addressManager1.formatUrl(\"/test/\", true, address);\n    Assertions.assertEquals(\"http://127.0.0.1:30103/test/\", url);\n  }\n\n  @Test\n  public void onRefreshEndpointEvent() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"http://127.0.0.3:30100\");\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"http://127.0.0.4:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    addressManager1 = new ServiceCenterAddressManager(\"project\", addresses, new EventBus(), \"\", \"\");\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"SERVICECENTER\");\n    addressManager1.refreshEndpoint(event, \"SERVICECENTER\");\n\n    List<String> availableZone = addressManager1.getAvailableZone();\n    Assertions.assertEquals(\"http://127.0.0.3:30100\", availableZone.get(0));\n\n    List<String> availableRegion = addressManager1.getAvailableRegion();\n    Assertions.assertEquals(\"http://127.0.0.4:30100\", availableRegion.get(0));\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.service.center.client;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.apache.servicecomb.http.client.common.HttpResponse;\nimport org.apache.servicecomb.service.center.client.model.Framework;\nimport org.apache.servicecomb.service.center.client.model.HeartbeatsRequest;\nimport org.apache.servicecomb.service.center.client.model.InstancesRequest;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstancesResponse;\nimport org.apache.servicecomb.service.center.client.model.MicroservicesResponse;\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceInstanceResponse;\nimport org.apache.servicecomb.service.center.client.model.RegisteredMicroserviceResponse;\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.mockito.ArgumentMatchers;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.SerializationFeature;\nimport com.google.common.eventbus.EventBus;\n\n/**\n * Created by   on 2019/10/17.\n */\npublic class ServiceCenterClientTest {\n  private final ServiceCenterAddressManager addressManager;\n\n  public ServiceCenterClientTest() {\n    this.addressManager = new ServiceCenterAddressManager(\"default\", Arrays.asList(\"http://127.0.0.1:30100\"),\n        new EventBus(), \"\", \"\");\n  }\n\n  @Test\n  public void TestGetServiceCenterInstances() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    String responseString = \"{\\n\"\n        + \"  \\\"instances\\\": [\\n\"\n        + \"    {\\n\"\n        + \"      \\\"instanceId\\\": \\\"111111\\\",\\n\"\n        + \"      \\\"serviceId\\\": \\\"222222\\\",\\n\"\n        + \"      \\\"version\\\": \\\"1.0\\\",\\n\"\n        + \"      \\\"hostName\\\": \\\"Test\\\",\\n\"\n        + \"      \\\"endpoints\\\": [\\n\"\n        + \"        \\\"string\\\"\\n\"\n        + \"      ],\\n\"\n        + \"      \\\"status\\\": \\\"UP\\\",\\n\"\n        + \"      \\\"properties\\\": {\\n\"\n        + \"        \\\"additionalProp1\\\": \\\"string\\\",\\n\"\n        + \"        \\\"additionalProp2\\\": \\\"string\\\",\\n\"\n        + \"        \\\"additionalProp3\\\": \\\"string\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"healthCheck\\\": {\\n\"\n        + \"        \\\"mode\\\": \\\"push\\\",\\n\"\n        + \"        \\\"port\\\": \\\"0\\\",\\n\"\n        + \"        \\\"interval\\\": \\\"0\\\",\\n\"\n        + \"        \\\"times\\\": \\\"0\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"dataCenterInfo\\\": {\\n\"\n        + \"        \\\"name\\\": \\\"string\\\",\\n\"\n        + \"        \\\"region\\\": \\\"string\\\",\\n\"\n        + \"        \\\"availableZone\\\": \\\"string\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"timestamp\\\": \\\"333333\\\",\\n\"\n        + \"      \\\"modTimestamp\\\": \\\"4444444\\\"\\n\"\n        + \"    }\\n\"\n        + \"  ]\\n\"\n        + \"}\";\n\n    httpResponse.setContent(responseString);\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(\"/registry/health\", null, null)).thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    MicroserviceInstancesResponse serviceCenterInstances = serviceCenterClient.getServiceCenterInstances();\n\n    Assertions.assertNotNull(serviceCenterInstances);\n    Assertions.assertEquals(1, serviceCenterInstances.getInstances().size());\n    Assertions.assertEquals(\"111111\", serviceCenterInstances.getInstances().get(0).getInstanceId());\n    Assertions.assertEquals(\"222222\", serviceCenterInstances.getInstances().get(0).getServiceId());\n  }\n\n  @Test\n  public void TestRegistryService() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    httpResponse.setContent(\"{\\\"serviceId\\\": \\\"111111\\\"}\");\n\n    Microservice microservice = new Microservice();\n    microservice.setServiceName(\"Test\");\n    ObjectMapper objectMapper = new ObjectMapper();\n    objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);\n\n    Mockito.when(serviceCenterRawClient\n        .postHttpRequest(ArgumentMatchers.eq(\"/registry/microservices\"), ArgumentMatchers.eq(null),\n        Mockito.anyString()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    RegisteredMicroserviceResponse actualResponse = serviceCenterClient.registerMicroservice(microservice);\n\n    Assertions.assertNotNull(actualResponse);\n    Assertions.assertEquals(\"111111\", actualResponse.getServiceId());\n  }\n\n  @Test\n  public void TestGetServiceMessage() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    String responseString = \"{\\n\"\n        + \"  \\\"service\\\": {\\n\"\n        + \"      \\\"serviceId\\\": \\\"111111\\\",\\n\"\n        + \"      \\\"environment\\\": \\\"string\\\",\\n\"\n        + \"      \\\"appId\\\": \\\"string\\\",\\n\"\n        + \"      \\\"serviceName\\\": \\\"string\\\",\\n\"\n        + \"      \\\"version\\\": \\\"string\\\",\\n\"\n        + \"      \\\"description\\\": \\\"string\\\",\\n\"\n        + \"      \\\"level\\\": \\\"string\\\",\\n\"\n        + \"      \\\"registerBy\\\": \\\"string\\\",\\n\"\n        + \"      \\\"schemas\\\": [\\n\"\n        + \"        \\\"string\\\"\\n\"\n        + \"      ],\\n\"\n        + \"      \\\"status\\\": \\\"UP\\\",\\n\"\n        + \"      \\\"timestamp\\\": \\\"string\\\",\\n\"\n        + \"      \\\"modTimestamp\\\": \\\"string\\\",\\n\"\n        + \"      \\\"framework\\\": {\\n\"\n        + \"        \\\"name\\\": \\\"string\\\",\\n\"\n        + \"        \\\"version\\\": \\\"string\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"paths\\\": [\\n\"\n        + \"        {\\n\"\n        + \"          \\\"Path\\\": \\\"string\\\",\\n\"\n        + \"          \\\"Property\\\": {\\n\"\n        + \"            \\\"additionalProp1\\\": \\\"string\\\",\\n\"\n        + \"            \\\"additionalProp2\\\": \\\"string\\\",\\n\"\n        + \"            \\\"additionalProp3\\\": \\\"string\\\"\\n\"\n        + \"          }\\n\"\n        + \"        }\\n\"\n        + \"      ],\\n\"\n        + \"      \\\"properties\\\": {\\n\"\n        + \"        \\\"additionalProp1\\\": \\\"string\\\",\\n\"\n        + \"        \\\"additionalProp2\\\": \\\"string\\\",\\n\"\n        + \"        \\\"additionalProp3\\\": \\\"string\\\"\\n\"\n        + \"      }\\n\"\n        + \"    }\\n\"\n        + \"}\";\n\n    httpResponse.setContent(responseString);\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(\"/registry/microservices/111111\", null, null))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    Microservice microservices = serviceCenterClient.getMicroserviceByServiceId(\"111111\");\n\n    Assertions.assertNotNull(microservices);\n    Assertions.assertEquals(\"111111\", microservices.getServiceId());\n  }\n\n  @Test\n  public void TestGetServiceList() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n\n    MicroservicesResponse microservicesResponse = new MicroservicesResponse();\n    List<Microservice> microserviceList = new ArrayList<>();\n    microserviceList.add(new Microservice(\"Test1\"));\n    microserviceList.add(new Microservice(\"Test2\"));\n    microserviceList.add(new Microservice(\"Test3\"));\n    microservicesResponse.setServices(microserviceList);\n    ObjectMapper mapper = new ObjectMapper();\n    httpResponse.setContent(mapper.writeValueAsString(microservicesResponse));\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    MicroservicesResponse actualMicroservicesResponse = serviceCenterClient.getMicroserviceList();\n\n    Assertions.assertNotNull(actualMicroservicesResponse);\n    Assertions.assertEquals(3, actualMicroservicesResponse.getServices().size());\n    Assertions.assertEquals(\"Test1\", actualMicroservicesResponse.getServices().get(0).getServiceName());\n  }\n\n  @Test\n  public void TestQueryServiceId() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    httpResponse.setContent(\"{\\\"serviceId\\\": \\\"111111\\\"}\");\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    Microservice microservice = new Microservice(\"Test111\");\n    RegisteredMicroserviceResponse actualServiceId = serviceCenterClient.queryServiceId(microservice);\n\n    Assertions.assertNotNull(actualServiceId);\n    Assertions.assertEquals(\"111111\", actualServiceId.getServiceId());\n  }\n\n  @Test\n  public void TestRegisterServiceInstance() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    httpResponse.setContent(\"{\\\"instanceId\\\": \\\"111111\\\"}\");\n\n    MicroserviceInstance instance = new MicroserviceInstance();\n    instance.setInstanceId(\"111111\");\n    instance.setServiceId(\"222222\");\n    ObjectMapper mapper = new ObjectMapper();\n    mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);\n\n    Mockito.when(serviceCenterRawClient.postHttpRequest(ArgumentMatchers.eq(\"/registry/microservices/222222/instances\"),\n        ArgumentMatchers.eq(null),\n        Mockito.anyString()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    RegisteredMicroserviceInstanceResponse actualResponse = serviceCenterClient.registerMicroserviceInstance(instance);\n\n    Assertions.assertNotNull(actualResponse);\n    Assertions.assertEquals(\"111111\", actualResponse.getInstanceId());\n  }\n\n  @Test\n  public void TestDeleteServiceInstance() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n\n    Mockito.when(serviceCenterRawClient.deleteHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    serviceCenterClient.deleteMicroserviceInstance(\"111\", \"222\");\n  }\n\n  @Test\n  public void TestGetServiceInstanceList() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    String responseString = \"{\\n\"\n        + \"  \\\"instances\\\": [\\n\"\n        + \"    {\\n\"\n        + \"      \\\"instanceId\\\": \\\"111111\\\",\\n\"\n        + \"      \\\"serviceId\\\": \\\"222222\\\",\\n\"\n        + \"      \\\"version\\\": \\\"1.0\\\",\\n\"\n        + \"      \\\"hostName\\\": \\\"Test\\\",\\n\"\n        + \"      \\\"endpoints\\\": [\\n\"\n        + \"        \\\"string\\\"\\n\"\n        + \"      ],\\n\"\n        + \"      \\\"status\\\": \\\"UP\\\",\\n\"\n        + \"      \\\"timestamp\\\": \\\"333333\\\",\\n\"\n        + \"      \\\"modTimestamp\\\": \\\"4444444\\\"\\n\"\n        + \"    }\\n\"\n        + \"  ]\\n\"\n        + \"}\";\n\n    httpResponse.setContent(responseString);\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(\"/registry/microservices/222222/instances\", null, null))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    MicroserviceInstancesResponse serviceCenterInstances = serviceCenterClient\n        .getMicroserviceInstanceList(\"222222\");\n\n    Assertions.assertNotNull(serviceCenterInstances);\n    Assertions.assertEquals(1, serviceCenterInstances.getInstances().size());\n    Assertions.assertEquals(\"111111\", serviceCenterInstances.getInstances().get(0).getInstanceId());\n    Assertions.assertEquals(\"222222\", serviceCenterInstances.getInstances().get(0).getServiceId());\n  }\n\n  @Test\n  public void TestGetServiceInstanceMessage() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    String responseString = \"{\\n\"\n        + \"  \\\"instance\\\": {\\n\"\n        + \"      \\\"instanceId\\\": \\\"111\\\",\\n\"\n        + \"      \\\"serviceId\\\": \\\"222\\\",\\n\"\n        + \"      \\\"version\\\": \\\"1.0\\\",\\n\"\n        + \"      \\\"hostName\\\": \\\"Test\\\",\\n\"\n        + \"      \\\"endpoints\\\": [\\n\"\n        + \"        \\\"string\\\"\\n\"\n        + \"      ],\\n\"\n        + \"      \\\"status\\\": \\\"UP\\\",\\n\"\n        + \"      \\\"properties\\\": {\\n\"\n        + \"        \\\"additionalProp1\\\": \\\"string\\\",\\n\"\n        + \"        \\\"additionalProp2\\\": \\\"string\\\",\\n\"\n        + \"        \\\"additionalProp3\\\": \\\"string\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"healthCheck\\\": {\\n\"\n        + \"        \\\"mode\\\": \\\"push\\\",\\n\"\n        + \"        \\\"port\\\": \\\"0\\\",\\n\"\n        + \"        \\\"interval\\\": \\\"0\\\",\\n\"\n        + \"        \\\"times\\\": \\\"0\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"dataCenterInfo\\\": {\\n\"\n        + \"        \\\"name\\\": \\\"string\\\",\\n\"\n        + \"        \\\"region\\\": \\\"string\\\",\\n\"\n        + \"        \\\"availableZone\\\": \\\"string\\\"\\n\"\n        + \"      },\\n\"\n        + \"      \\\"timestamp\\\": \\\"333333\\\",\\n\"\n        + \"      \\\"modTimestamp\\\": \\\"4444444\\\"\\n\"\n        + \"    }\\n\"\n        + \"}\";\n\n    httpResponse.setContent(responseString);\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    MicroserviceInstance responseInstance = serviceCenterClient\n        .getMicroserviceInstance(\"111\", \"222\");\n\n    Assertions.assertNotNull(responseInstance);\n    Assertions.assertEquals(\"111\", responseInstance.getInstanceId());\n    Assertions.assertEquals(\"Test\", responseInstance.getHostName());\n  }\n\n  @Test\n  public void TestSendHeartBeats() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n\n    HeartbeatsRequest heartbeatsRequest = new HeartbeatsRequest(\"001\", \"1001\");\n    heartbeatsRequest.addInstances(new InstancesRequest(\"002\", \"1002\"));\n    ObjectMapper mapper = new ObjectMapper();\n\n    Mockito\n        .when(serviceCenterRawClient.putHttpRequest(\"/registry/microservices/111/instances/222/heartbeat\", null, null))\n        .thenReturn(httpResponse);\n    Mockito.when(serviceCenterRawClient\n        .putHttpRequest(ArgumentMatchers.eq(\"/registry/heartbeats\"), ArgumentMatchers.eq(null),\n        Mockito.anyString()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    serviceCenterClient.sendHeartBeats(heartbeatsRequest);\n  }\n\n  @Test\n  public void TestUpdateServicesInstanceStatus() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n\n    Mockito.when(serviceCenterRawClient.putHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    Boolean result = serviceCenterClient\n        .updateMicroserviceInstanceStatus(\"111\", \"222\", MicroserviceInstanceStatus.UP);\n\n    Assertions.assertNotNull(result);\n    Assertions.assertEquals(true, result);\n  }\n\n  @Test\n  public void TestGetServiceSchemas() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    String responseString = \"{\\n\"\n        + \"  \\\"schemas\\\": [\\n\"\n        + \"    {\\n\"\n        + \"      \\\"schemaId\\\": \\\"111111\\\",\\n\"\n        + \"      \\\"schema\\\": \\\"test\\\",\\n\"\n        + \"      \\\"summary\\\": \\\"test\\\"\\n\"\n        + \"    }\\n\"\n        + \"  ]\\n\"\n        + \"}\";\n    httpResponse.setContent(responseString);\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    List<SchemaInfo> schemaResponse = serviceCenterClient\n        .getServiceSchemasList(\"111\", false);\n\n    ObjectMapper mapper = new ObjectMapper();\n    JsonNode jsonNode = mapper.readTree(mapper.writeValueAsString(schemaResponse));\n\n    Assertions.assertNotNull(jsonNode);\n    Assertions.assertEquals(\"111111\", jsonNode.get(0).get(\"schemaId\").textValue());\n    Assertions.assertEquals(\"test\", jsonNode.get(0).get(\"schema\").textValue());\n  }\n\n  @Test\n  public void TestGetServiceSchemasContext() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n    String responseString = \"{\\n\"\n        + \"  \\\"schema\\\": \\\"test context\\\"\\n\"\n        + \"}\";\n    httpResponse.setContent(responseString);\n\n    Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    String schemaContext = serviceCenterClient\n        .getServiceSchemaContext(\"111\", \"222\");\n\n    Assertions.assertNotNull(schemaContext);\n    Assertions.assertEquals(\"test context\", schemaContext);\n  }\n\n  @Test\n  public void TestUpdateServiceSchema() throws IOException {\n\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n\n    Mockito.when(serviceCenterRawClient.putHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n        .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    boolean result = serviceCenterClient\n        .updateServiceSchemaContext(\"111\", new SchemaInfo());\n\n    Assertions.assertTrue(result);\n  }\n\n  @Test\n  public void testUpdateMicroserviceProperties() throws IOException {\n    ServiceCenterRawClient serviceCenterRawClient = Mockito.mock(ServiceCenterRawClient.class);\n\n    HttpResponse httpResponse = new HttpResponse();\n    httpResponse.setStatusCode(200);\n    httpResponse.setMessage(\"ok\");\n\n    Mockito.when(serviceCenterRawClient.putHttpRequest(Mockito.any(), Mockito.any(), Mockito.any()))\n            .thenReturn(httpResponse);\n\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager);\n    boolean result = serviceCenterClient\n            .updateMicroserviceProperties(\"111\", new HashMap<String, String>(), new Framework());\n\n    Assertions.assertTrue(result);\n  }\n}\n"
  },
  {
    "path": "clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.service.center.client;\r\n\r\nimport java.io.IOException;\r\nimport java.util.Arrays;\r\n\r\nimport org.apache.servicecomb.http.client.common.HttpResponse;\r\nimport org.apache.servicecomb.http.client.common.HttpTransport;\r\nimport org.junit.jupiter.api.Assertions;\r\nimport org.junit.jupiter.api.Test;\r\nimport org.mockito.Mockito;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\n/**\r\n * Created by   on 2019/10/16.\r\n */\r\npublic class ServiceCenterRawClientTest {\r\n\r\n  private static final String PROJECT_NAME = \"default\";\r\n\r\n  private static final String TENANT_NAME = \"default\";\r\n\r\n  @Test\r\n  public void TestDefaultParameter() throws IOException {\r\n\r\n    HttpTransport httpTransport = Mockito.mock(HttpTransport.class);\r\n    ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(PROJECT_NAME,\r\n        Arrays.asList(\"http://127.0.0.1:30100\"), new EventBus(), \"\", \"\");\r\n    ServiceCenterRawClient client = new ServiceCenterRawClient.Builder()\r\n        .setHttpTransport(httpTransport)\r\n        .setAddressManager(addressManager)\r\n        .setTenantName(TENANT_NAME)\r\n        .build();\r\n\r\n    HttpResponse httpResponse = new HttpResponse();\r\n    httpResponse.setStatusCode(200);\r\n    httpResponse.setContent(\"ok\");\r\n\r\n    Mockito.when(httpTransport.doRequest(Mockito.any())).thenReturn(httpResponse);\r\n\r\n    HttpResponse actualGetResponse = client.getHttpRequest(null, null, null);\r\n    HttpResponse actualPostResponse = client.postHttpRequest(null, null, null);\r\n    HttpResponse actualPutResponse = client.putHttpRequest(null, null, null);\r\n    HttpResponse actualDeleteResponse = client.putHttpRequest(null, null, null);\r\n\r\n    Assertions.assertNotNull(actualGetResponse);\r\n    Assertions.assertEquals(\"ok\", actualGetResponse.getContent());\r\n    Assertions.assertNotNull(actualPostResponse);\r\n    Assertions.assertEquals(\"ok\", actualPostResponse.getContent());\r\n    Assertions.assertNotNull(actualPutResponse);\r\n    Assertions.assertEquals(\"ok\", actualPutResponse.getContent());\r\n    Assertions.assertNotNull(actualDeleteResponse);\r\n    Assertions.assertEquals(\"ok\", actualDeleteResponse.getContent());\r\n  }\r\n}\r\n"
  },
  {
    "path": "common/common-access-log/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>common</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>common-access-log</artifactId>\n  <name>Java Chassis::Common::CommonAccessLog</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/AccessLogBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\n\npublic class AccessLogBootListener implements BootListener {\n\n  private final AccessLogBootstrap accessLogBootstrap = new AccessLogBootstrap();\n\n  @Override\n  public void onAfterRegistry(BootEvent event) {\n    accessLogBootstrap.start(EventManager.getEventBus());\n  }\n\n  @Override\n  public void onBeforeClose(BootEvent event) {\n    accessLogBootstrap.shutdown();\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/AccessLogBootstrap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\nimport com.google.common.eventbus.EventBus;\n\npublic class AccessLogBootstrap {\n  private static final AccessLogConfig config = AccessLogConfig.INSTANCE;\n\n  public void start(EventBus eventBus) {\n    SPIServiceUtils.getSortedService(AccessLogInitializer.class)\n        .forEach(initializer -> initializer.init(eventBus, config));\n  }\n\n  public void shutdown() {\n    SPIServiceUtils.getSortedService(AccessLogInitializer.class)\n        .forEach(AccessLogInitializer::destroy);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/AccessLogConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\n\npublic class AccessLogConfig {\n\n  public static final String SERVER_BASE = \"servicecomb.accesslog.\";\n\n  public static final String CLIENT_BASE = \"servicecomb.accesslog.request.\";\n\n  public static final String SERVER_LOG_ENABLED = SERVER_BASE + \"enabled\";\n\n  public static final String SERVER_LOG_PATTERN = SERVER_BASE + \"pattern\";\n\n  public static final String CLIENT_LOG_ENABLED = CLIENT_BASE + \"enabled\";\n\n  public static final String CLIENT_LOG_PATTERN = CLIENT_BASE + \"pattern\";\n\n  public static final String DEFAULT_SERVER_PATTERN = \"%h - - %t %r %s %B %D\";\n\n  public static final String DEFAULT_CLIENT_PATTERN = \"%h %SCB-transport - - %t %r %s %D\";\n\n  public static final AccessLogConfig INSTANCE = new AccessLogConfig();\n\n  private boolean serverLogEnabled;\n\n  private boolean clientLogEnabled;\n\n  private String serverLogPattern;\n\n  private String clientLogPattern;\n\n  private AccessLogConfig() {\n    init();\n  }\n\n  private void init() {\n    clientLogEnabled = LegacyPropertyFactory.getBooleanProperty(CLIENT_LOG_ENABLED, false);\n    serverLogEnabled = LegacyPropertyFactory.getBooleanProperty(SERVER_LOG_ENABLED, false);\n    clientLogPattern = LegacyPropertyFactory.getStringProperty(CLIENT_LOG_PATTERN, DEFAULT_CLIENT_PATTERN);\n    serverLogPattern = LegacyPropertyFactory.getStringProperty(SERVER_LOG_PATTERN, DEFAULT_SERVER_PATTERN);\n  }\n\n  public boolean isServerLogEnabled() {\n    return serverLogEnabled;\n  }\n\n  public boolean isClientLogEnabled() {\n    return clientLogEnabled;\n  }\n\n  public String getServerLogPattern() {\n    return serverLogPattern;\n  }\n\n  public String getClientLogPattern() {\n    return clientLogPattern;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/AccessLogConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.accessLog;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class AccessLogConfiguration {\n  @Bean\n  public AccessLogBootListener scbAccessLogBootListener() {\n    return new AccessLogBootListener();\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/AccessLogInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.accessLog;\n\nimport com.google.common.eventbus.EventBus;\n\npublic interface AccessLogInitializer {\n    default int getOrder() {\n        return 0;\n    }\n\n    void init(EventBus eventBus, AccessLogConfig accessLogConfig);\n\n    default void destroy() {}\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/client/ClientDefaultInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.client;\n\nimport org.apache.servicecomb.common.accessLog.AccessLogConfig;\nimport org.apache.servicecomb.common.accessLog.AccessLogInitializer;\nimport org.apache.servicecomb.common.accessLog.core.AccessLogGenerator;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class ClientDefaultInitializer implements AccessLogInitializer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(\"scb-access\");\n\n  private AccessLogGenerator accessLogGenerator;\n\n  @Override\n  public void init(EventBus eventBus, AccessLogConfig accessLogConfig) {\n    if (!accessLogConfig.isClientLogEnabled()) {\n      return;\n    }\n    accessLogGenerator = new AccessLogGenerator(accessLogConfig.getClientLogPattern());\n    eventBus.register(this);\n  }\n\n  @Subscribe\n  @AllowConcurrentEvents\n  public void onRequestOut(InvocationFinishEvent finishEvent) {\n    if (InvocationType.CONSUMER.equals(finishEvent.getInvocation().getInvocationType())) {\n      LOGGER.info(accessLogGenerator.generateClientLog(finishEvent));\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/AccessLogGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core;\n\nimport java.util.List;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.parser.AccessLogPatternParser;\nimport org.apache.servicecomb.common.accessLog.core.parser.impl.VertxRestAccessLogPatternParser;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport com.google.common.collect.Iterables;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/*\n * Accept {@link AccessLogParam} and generate access log.\n * <br/>\n * Each AccessLogParam for a line of access log.\n */\npublic class AccessLogGenerator {\n  /*\n   * traversal this array to generate access log segment.\n   */\n  private final AccessLogItem<RoutingContext>[] accessLogItems;\n\n  private final AccessLogPatternParser<RoutingContext> logPatternParser = new VertxRestAccessLogPatternParser();\n\n  @SuppressWarnings(\"unchecked\")\n  public AccessLogGenerator(String rawPattern) {\n    List<AccessLogItem<RoutingContext>> accessLogItemList = logPatternParser.parsePattern(rawPattern);\n    accessLogItems = Iterables.toArray(accessLogItemList, AccessLogItem.class);\n  }\n\n  public String generateServerLog(ServerAccessLogEvent accessLogEvent) {\n    StringBuilder log = new StringBuilder(128);\n    for (AccessLogItem<RoutingContext> accessLogItem : getAccessLogItems()) {\n      accessLogItem.appendServerFormattedItem(accessLogEvent, log);\n    }\n    return log.toString();\n  }\n\n  public String generateClientLog(InvocationFinishEvent finishEvent) {\n    StringBuilder log = new StringBuilder(128);\n    for (AccessLogItem<RoutingContext> accessLogItem : getAccessLogItems()) {\n      accessLogItem.appendClientFormattedItem(finishEvent, log);\n    }\n    return log.toString();\n  }\n\n  @VisibleForTesting\n  AccessLogItem<RoutingContext>[] getAccessLogItems() {\n    return accessLogItems;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/AccessLogItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\n/*\n * Access log item represents the items supported in access log and request log printing.\n * It generate the segment of log according to {@link AccessLogParam}\n */\npublic interface AccessLogItem<T> {\n  default void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n  }\n\n  default void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/ConfigurableDatetimeAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Locale;\nimport java.util.TimeZone;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * Configurable dateTime element.\n */\npublic class ConfigurableDatetimeAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String DEFAULT_DATETIME_PATTERN = \"EEE, dd MMM yyyy HH:mm:ss zzz\";\n\n  public static final Locale DEFAULT_LOCALE = Locale.US;\n\n  private final ThreadLocal<SimpleDateFormat> datetimeFormatHolder = new ThreadLocal<>();\n\n  private String pattern;\n\n  private TimeZone timezone;\n\n  private Locale locale;\n\n  /**\n   * all configuration is set to default value.\n   */\n  public ConfigurableDatetimeAccessItem() {\n    this(DEFAULT_DATETIME_PATTERN);\n  }\n\n  /**\n   * the configurations not specified will get a default value.\n   * @param config the format of configuration is \"PATTERN|TIMEZONE|LOCALE\" or \"PATTERN\". It depends on whether the config contains the separator \"|\"\n   */\n  public ConfigurableDatetimeAccessItem(String config) {\n    String[] configArr;\n    if (config.contains(\"|\")) {\n      configArr = splitConfig(config);\n    } else {\n      // if there is no separator \"|\", regard configuration as pattern.\n      configArr = new String[3];\n      configArr[0] = config;\n    }\n    if (3 != configArr.length) {\n      throw new IllegalArgumentException(\n          \"wrong format of configuration, \\\"PATTERN|TIMEZONE|LOCALE\\\" is expected, but actually is \\\"\" + config + \"\\\"\");\n    }\n\n    setConfigurations(configArr);\n  }\n\n  private String[] splitConfig(String config) {\n    return config.split(\"\\\\|{1}?\", -1);\n  }\n\n  private void setConfigurations(String[] configArr) {\n    this.pattern = StringUtils.isEmpty(configArr[0]) ? DEFAULT_DATETIME_PATTERN : configArr[0];\n    this.timezone = StringUtils.isEmpty(configArr[1]) ? TimeZone.getDefault() : TimeZone.getTimeZone(configArr[1]);\n    this.locale = StringUtils.isEmpty(configArr[2]) ? DEFAULT_LOCALE : Locale.forLanguageTag(configArr[2]);\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    doAppendFormattedItem(accessLogEvent.getMilliStartTime(), builder);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    long milliDuration = finishEvent.getInvocation().getInvocationStageTrace().calcTotal() / 1000_000;\n    doAppendFormattedItem(\n        finishEvent.getInvocation().getInvocationStageTrace().getStartInMillis() + milliDuration, builder);\n  }\n\n  private void doAppendFormattedItem(long milliStartTime, StringBuilder builder) {\n    SimpleDateFormat dateFormat = getDatetimeFormat();\n    builder.append(dateFormat.format(new Date(milliStartTime)));\n  }\n\n  private SimpleDateFormat getDatetimeFormat() {\n    SimpleDateFormat dateFormat = datetimeFormatHolder.get();\n    if (null == dateFormat) {\n      dateFormat = new SimpleDateFormat(pattern, locale);\n      dateFormat.setTimeZone(timezone);\n\n      datetimeFormatHolder.set(dateFormat);\n    }\n\n    return dateFormat;\n  }\n\n  public String getPattern() {\n    return pattern;\n  }\n\n  public TimeZone getTimezone() {\n    return timezone;\n  }\n\n  public Locale getLocale() {\n    return locale;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/CookieAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport java.util.Map.Entry;\nimport java.util.Set;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\n\nimport io.vertx.core.http.Cookie;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class CookieAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String RESULT_NOT_FOUND = \"-\";\n\n  private final String varName;\n\n  public CookieAccessItem(String varName) {\n    this.varName = varName;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    Set<Cookie> cookies = accessLogEvent.getRoutingContext().request().cookies();\n    if (null == cookies) {\n      builder.append(RESULT_NOT_FOUND);\n      return;\n    }\n    for (Cookie cookie : cookies) {\n      if (varName.equals(cookie.getName())) {\n        builder.append(cookie.getValue());\n        return;\n      }\n    }\n    builder.append(RESULT_NOT_FOUND);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    RestClientRequestParameters restRequestImpl = (RestClientRequestParameters) finishEvent.getInvocation().getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getCookieMap()) {\n      builder.append(RESULT_NOT_FOUND);\n      return;\n    }\n    for (Entry<String, String> entry : restRequestImpl.getCookieMap().entrySet()) {\n      if (entry.getKey().equals(varName)) {\n        builder.append(entry.getValue());\n        return;\n      }\n    }\n    builder.append(RESULT_NOT_FOUND);\n  }\n\n  public String getVarName() {\n    return varName;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/DurationMillisecondAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class DurationMillisecondAccessItem implements AccessLogItem<RoutingContext> {\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(accessLogEvent.getMilliEndTime() - accessLogEvent.getMilliStartTime());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    builder.append(finishEvent.getInvocation().getInvocationStageTrace().calcTotal() / 1000_000);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/DurationSecondAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class DurationSecondAccessItem implements AccessLogItem<RoutingContext> {\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append((accessLogEvent.getMilliEndTime() - accessLogEvent.getMilliStartTime()) / 1000);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    builder.append(finishEvent.getInvocation().getInvocationStageTrace().calcTotal() / 1000_000_000);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/FirstLineOfRequestAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class FirstLineOfRequestAccessItem implements AccessLogItem<RoutingContext> {\n  private static final HttpMethodAccessItem METHOD_ELEMENT = new HttpMethodAccessItem();\n\n  private static final UrlPathAccessItem URI_PATH_ONLY_ELEMENT = new UrlPathAccessItem();\n\n  private static final RequestProtocolAccessItem VERSION_OR_PROTOCOL_ELEMENT = new RequestProtocolAccessItem();\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(\"\\\"\");\n    METHOD_ELEMENT.appendServerFormattedItem(accessLogEvent, builder);\n    builder.append(\" \");\n    URI_PATH_ONLY_ELEMENT.appendServerFormattedItem(accessLogEvent, builder);\n    builder.append(\" \");\n    VERSION_OR_PROTOCOL_ELEMENT.appendServerFormattedItem(accessLogEvent, builder);\n    builder.append(\"\\\"\");\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    builder.append(\"\\\"\");\n    METHOD_ELEMENT.appendClientFormattedItem(finishEvent, builder);\n    builder.append(\" \");\n    URI_PATH_ONLY_ELEMENT.appendClientFormattedItem(finishEvent, builder);\n    builder.append(\" \");\n    VERSION_OR_PROTOCOL_ELEMENT.appendClientFormattedItem(finishEvent, builder);\n    builder.append(\"\\\"\");\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/HttpMethodAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * HTTP method\n */\npublic class HttpMethodAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || null == request.method()) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(request.method().toString());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    OperationMeta operationMeta = finishEvent.getInvocation().getOperationMeta();\n    if (operationMeta != null && !StringUtils.isEmpty(operationMeta.getHttpMethod())) {\n      builder.append(operationMeta.getHttpMethod());\n      return;\n    }\n    RestClientRequest restRequestImpl = (RestClientRequest) finishEvent.getInvocation().getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getHttpClientRequest()\n        || null == restRequestImpl.getHttpClientRequest().getMethod()) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(restRequestImpl.getHttpClientRequest().getMethod().toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/HttpStatusAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class HttpStatusAccessItem implements AccessLogItem<RoutingContext> {\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerResponse response = accessLogEvent.getRoutingContext().response();\n    if (null == response) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    if (response.closed() && !response.ended()) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(response.getStatusCode());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    Response response = finishEvent.getResponse();\n    if (null == response) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(response.getStatusCode());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/InvocationContextAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class InvocationContextAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String NOT_FOUND = \"-\";\n\n  final String varName;\n\n  public InvocationContextAccessItem(String varName) {\n    this.varName = varName;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    String invocationContextValue = getValueFromInvocationContext(accessLogEvent);\n    if (StringUtils.isEmpty(invocationContextValue)) {\n      builder.append(NOT_FOUND);\n      return;\n    }\n    builder.append(invocationContextValue);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    Invocation invocation = finishEvent.getInvocation();\n    if (null == invocation || invocation.getContext() == null\n        || StringUtils.isEmpty(finishEvent.getInvocation().getContext().get(varName))) {\n      builder.append(NOT_FOUND);\n      return;\n    }\n    builder.append(finishEvent.getInvocation().getContext().get(varName));\n  }\n\n\n  protected String getValueFromInvocationContext(ServerAccessLogEvent accessLogEvent) {\n    Map<String, Object> data = accessLogEvent.getRoutingContext().data();\n    if (null == data || null == data.get(RestConst.REST_INVOCATION_CONTEXT)) {\n      return null;\n    }\n    return ((Invocation) data.get(RestConst.REST_INVOCATION_CONTEXT)).getContext(varName);\n  }\n\n  public String getVarName() {\n    return varName;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/LocalHostAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class LocalHostAccessItem implements AccessLogItem<RoutingContext> {\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(accessLogEvent.getLocalAddress());\n  }\n\n  /**\n   * client do not need localhost\n   */\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    RestClientRequest restRequestImpl = (RestClientRequest) finishEvent.getInvocation().getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getHttpClientRequest()\n        || null == restRequestImpl.getHttpClientRequest().connection()\n        || null == restRequestImpl.getHttpClientRequest().connection().localAddress()\n        || StringUtils.isEmpty(restRequestImpl.getHttpClientRequest().connection().localAddress().host())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(restRequestImpl.getHttpClientRequest().connection().localAddress().host());\n  }\n\n  public static String getLocalAddress(RoutingContext context) {\n    HttpServerRequest request = context.request();\n    if (null == request || null == request.localAddress() || StringUtils.isEmpty(request.localAddress().host())) {\n      return EMPTY_RESULT;\n    }\n    return request.localAddress().host();\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/LocalPortAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class LocalPortAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || null == request.localAddress()) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(request.localAddress().port());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    RestClientRequestParameters restRequestImpl = (RestClientRequestParameters) finishEvent.getInvocation()\n        .getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getHttpClientRequest()\n        || null == restRequestImpl.getHttpClientRequest().connection()\n        || null == restRequestImpl.getHttpClientRequest().connection().localAddress()) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(restRequestImpl.getHttpClientRequest().connection().localAddress().port());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/PlainTextAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * Print content as it is.\n */\npublic class PlainTextAccessItem implements AccessLogItem<RoutingContext> {\n  private final String content;\n\n  public PlainTextAccessItem(String content) {\n    this.content = content;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(content);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    builder.append(content);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/QueryStringAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class QueryStringAccessItem implements AccessLogItem<RoutingContext> {\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || StringUtils.isEmpty(request.query())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(request.query());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    RestClientRequestParameters restRequestImpl = (RestClientRequestParameters) finishEvent.getInvocation()\n        .getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getHttpClientRequest()\n        || StringUtils.isEmpty(restRequestImpl.getHttpClientRequest().query())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(restRequestImpl.getHttpClientRequest().query());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/RemoteHostAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RemoteHostAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || null == request.remoteAddress()\n        || StringUtils.isEmpty(request.remoteAddress().host())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(request.remoteAddress().host());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {\n    Endpoint endpoint = clientLogEvent.getInvocation().getEndpoint();\n    if (null == endpoint || null == endpoint.getAddress()\n        || StringUtils.isEmpty(((URIEndpointObject) endpoint.getAddress()).getHostOrIp())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(((URIEndpointObject) endpoint.getAddress()).getHostOrIp());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestHeaderAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RequestHeaderAccessItem implements AccessLogItem<RoutingContext> {\n  public static final String RESULT_NOT_FOUND = \"-\";\n\n  private final String varName;\n\n  public RequestHeaderAccessItem(String varName) {\n    this.varName = varName;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    MultiMap headers = accessLogEvent.getRoutingContext().request().headers();\n    if (null == headers || StringUtils.isEmpty(headers.get(varName))) {\n      builder.append(RESULT_NOT_FOUND);\n      return;\n    }\n    builder.append(headers.get(varName));\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {\n    RestClientRequestParameters restRequestImpl = (RestClientRequestParameters) clientLogEvent.getInvocation()\n        .getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getHttpClientRequest()\n        || null == restRequestImpl.getHttpClientRequest().headers()\n        || StringUtils.isEmpty(restRequestImpl.getHttpClientRequest().headers().get(varName))) {\n      builder.append(RESULT_NOT_FOUND);\n      return;\n    }\n    builder.append(restRequestImpl.getHttpClientRequest().headers().get(varName));\n  }\n\n  public String getVarName() {\n    return varName;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestProtocolAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.HttpVersion;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RequestProtocolAccessItem implements AccessLogItem<RoutingContext> {\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || null == request.version()) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(getStringVersion(request.version()));\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    Invocation invocation = finishEvent.getInvocation();\n    if (invocation == null || null == invocation.getEndpoint() || null == invocation.getEndpoint().getAddress()\n        || !(invocation.getEndpoint().getAddress() instanceof URIEndpointObject)\n        || !((URIEndpointObject) invocation.getEndpoint().getAddress()).isHttp2Enabled()) {\n      builder.append(\"HTTP/1.1\");\n      return;\n    }\n    builder.append(\"HTTP/2.0\");\n  }\n\n  private String getStringVersion(HttpVersion version) {\n    switch (version) {\n      case HTTP_2:\n        return \"HTTP/2.0\";\n      case HTTP_1_0:\n        return \"HTTP/1.0\";\n      case HTTP_1_1:\n        return \"HTTP/1.1\";\n      default:\n        return EMPTY_RESULT;\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseHeaderAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class ResponseHeaderAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String RESULT_NOT_FOUND = \"-\";\n\n  private final String varName;\n\n  public ResponseHeaderAccessItem(String varName) {\n    this.varName = varName;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerResponse response = accessLogEvent.getRoutingContext().response();\n    if (null == response || null == response.headers() || StringUtils.isEmpty(response.headers().get(varName))) {\n      builder.append(RESULT_NOT_FOUND);\n      return;\n    }\n    builder.append(response.headers().get(varName));\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    Response response = finishEvent.getResponse();\n    String value = response != null ? response.getHeader(varName) : null;\n    if (null == value) {\n      builder.append(RESULT_NOT_FOUND);\n      return;\n    }\n    builder.append(value);\n  }\n\n  public String getVarName() {\n    return varName;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseSizeAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class ResponseSizeAccessItem implements AccessLogItem<RoutingContext> {\n  // print zeroBytes when bytes is zero\n  private final String zeroBytes;\n\n  public ResponseSizeAccessItem(String zeroBytesPlaceholder) {\n    zeroBytes = zeroBytesPlaceholder;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerResponse response = accessLogEvent.getRoutingContext().response();\n    if (null == response || 0 == response.bytesWritten()) {\n      builder.append(zeroBytes);\n      return;\n    }\n    builder.append(response.bytesWritten());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    // client do not know how to calculate is right, maybe Object#toString().length\n    builder.append(zeroBytes);\n  }\n\n  public String getZeroBytes() {\n    return zeroBytes;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/TraceIdAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\npublic class TraceIdAccessItem extends InvocationContextAccessItem {\n\n  public static final String TRACE_ID = CoreConst.TRACE_ID_NAME;\n\n  public TraceIdAccessItem() {\n    super(TRACE_ID);\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    String traceId = getValueFromInvocationContext(accessLogEvent);\n    if (StringUtils.isEmpty(traceId)) {\n      traceId = accessLogEvent.getRoutingContext().request().getHeader(TRACE_ID);\n    }\n    builder.append(StringUtils.isEmpty(traceId) ? InvocationContextAccessItem.NOT_FOUND : traceId);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    Invocation invocation = finishEvent.getInvocation();\n    if (invocation == null || invocation.getContext() == null\n        || StringUtils.isEmpty(invocation.getContext().get(TRACE_ID))) {\n      builder.append(InvocationContextAccessItem.NOT_FOUND);\n      return;\n    }\n    builder.append(invocation.getContext().get(TRACE_ID));\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/TransportAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class TransportAccessItem implements AccessLogItem<RoutingContext> {\n  private static final String EMPTY_STR = \"-\";\n\n  /**\n   * access log only support rest\n   */\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(\"rest\");\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    String transportName = finishEvent.getInvocation().getConfigTransportName();\n    if (!StringUtils.isEmpty(transportName)) {\n      builder.append(transportName);\n      return;\n    }\n    Endpoint endpoint = finishEvent.getInvocation().getEndpoint();\n    if (endpoint == null || StringUtils.isEmpty(endpoint.getEndpoint())) {\n      builder.append(EMPTY_STR);\n      return;\n    }\n    builder.append(endpoint.getEndpoint().split(\":\")[0]);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/UrlPathAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class UrlPathAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || StringUtils.isEmpty(request.path())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(request.path());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    OperationMeta operationMeta = finishEvent.getInvocation().getOperationMeta();\n    SchemaMeta schemaMeta = finishEvent.getInvocation().getSchemaMeta();\n    if (operationMeta != null && schemaMeta != null && schemaMeta.getSwagger() != null) {\n      builder.append(operationMeta.getOperationPath());\n      return;\n    }\n    RestClientRequestParameters restRequestImpl = (RestClientRequestParameters) finishEvent.getInvocation()\n        .getHandlerContext()\n        .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);\n    if (null == restRequestImpl || null == restRequestImpl.getHttpClientRequest()\n        || StringUtils.isEmpty(restRequestImpl.getHttpClientRequest().path())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(restRequestImpl.getHttpClientRequest().path());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/element/impl/UrlPathWithQueryAccessItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.apache.servicecomb.common.rest.RestConst.REST_CLIENT_REQUEST_PATH;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class UrlPathWithQueryAccessItem implements AccessLogItem<RoutingContext> {\n\n  public static final String EMPTY_RESULT = \"-\";\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    HttpServerRequest request = accessLogEvent.getRoutingContext().request();\n    if (null == request || StringUtils.isEmpty(request.uri())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(request.uri());\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {\n    Invocation invocation = finishEvent.getInvocation();\n    if (null == invocation || null == invocation.getLocalContext(REST_CLIENT_REQUEST_PATH)\n        || StringUtils.isEmpty(invocation.getLocalContext(REST_CLIENT_REQUEST_PATH).toString())) {\n      builder.append(EMPTY_RESULT);\n      return;\n    }\n    builder.append(invocation.getLocalContext(REST_CLIENT_REQUEST_PATH).toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/AccessLogItemCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.CookieAccessItem;\n\n/**\n * The {@linkplain AccessLogItemCreator}s are able to instantiate a group of {@linkplain AccessLogItem}.\n */\npublic interface AccessLogItemCreator<T> {\n  /**\n   * Create an instance of {@linkplain AccessLogItem} which is specified by the config.\n   * @param config\n   * e.g. For {@linkplain CookieAccessItem CookieItem},\n   * the pattern may be \"%{varName}C\", and it's config is \"varName\". Some {@linkplain AccessLogItem} with no configurable\n   * pattern (like \"%m\") will receive {@code null} as config.\n   */\n  AccessLogItem<T> createItem(String config);\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/AccessLogItemMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser;\n\n\npublic class AccessLogItemMeta<T> {\n  protected String prefix;\n\n  protected String suffix;\n\n  /**\n   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.\n   * Smaller one has higher priority.\n   */\n  protected int order;\n\n  protected AccessLogItemCreator<T> accessLogItemCreator;\n\n  public String getPrefix() {\n    return prefix;\n  }\n\n  public AccessLogItemMeta<T> setPrefix(String prefix) {\n    this.prefix = prefix;\n    return this;\n  }\n\n  public String getSuffix() {\n    return suffix;\n  }\n\n  public AccessLogItemMeta<T> setSuffix(String suffix) {\n    this.suffix = suffix;\n    return this;\n  }\n\n  public int getOrder() {\n    return order;\n  }\n\n  public AccessLogItemMeta<T> setOrder(int order) {\n    this.order = order;\n    return this;\n  }\n\n  public AccessLogItemCreator<T> getAccessLogItemCreator() {\n    return accessLogItemCreator;\n  }\n\n  public AccessLogItemMeta<T> setAccessLogItemCreator(AccessLogItemCreator<T> accessLogItemCreator) {\n    this.accessLogItemCreator = accessLogItemCreator;\n    return this;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/AccessLogPatternParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.common.accessLog.core.AccessLogGenerator;\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\n\n\n/**\n * This parser will parse the rawPattern of access log and generate a list of {@link AccessLogItem},\n * which will be used in {@link AccessLogGenerator} to generate\n * access log content.\n * @param <T> the type of {@linkplain AccessLogItem\n * AccessLogParam.contextData}, which usually depends on the transport way.\n */\npublic interface AccessLogPatternParser<T> {\n  List<AccessLogItem<T>> parsePattern(String rawPattern);\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/CompositeVertxRestAccessLogItemMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser;\n\nimport java.util.List;\n\n/**\n * Hold a group of {@link VertxRestAccessLogItemMeta} so that user can define\n * only one VertxRestAccessLogItemMeta in spi loading file and load a group of meta.\n *\n * Once the access log loading mechanism finds that a meta is CompositeVertxRestAccessLogItemMeta,\n * the meta hold by it will be used in access log while this meta itself will be ignored.\n */\npublic abstract class CompositeVertxRestAccessLogItemMeta extends VertxRestAccessLogItemMeta {\n  public abstract List<VertxRestAccessLogItemMeta> getAccessLogItemMetas();\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/VertxRestAccessLogItemMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * For vertx-rest transport way.\n */\npublic class VertxRestAccessLogItemMeta extends AccessLogItemMeta<RoutingContext> {\n  public VertxRestAccessLogItemMeta() {\n  }\n\n  public VertxRestAccessLogItemMeta(String prefix, String suffix,\n      AccessLogItemCreator<RoutingContext> accessLogItemCreator, int order) {\n    this.prefix = prefix;\n    this.suffix = suffix;\n    this.accessLogItemCreator = accessLogItemCreator;\n    this.order = order;\n  }\n\n  public VertxRestAccessLogItemMeta(String prefix, AccessLogItemCreator<RoutingContext> accessLogItemCreator) {\n    this(prefix, null, accessLogItemCreator, 0);\n  }\n\n  public VertxRestAccessLogItemMeta(String prefix, String suffix,\n      AccessLogItemCreator<RoutingContext> accessLogItemCreator) {\n    this(prefix, suffix, accessLogItemCreator, 0);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/impl/DefaultCompositeVertxRestAccessLogItemMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser.impl;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.CookieAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ConfigurableDatetimeAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.DurationMillisecondAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.DurationSecondAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.FirstLineOfRequestAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.HttpMethodAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.HttpStatusAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.InvocationContextAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.LocalHostAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.LocalPortAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.QueryStringAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RemoteHostAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RequestHeaderAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RequestProtocolAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ResponseHeaderAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ResponseSizeAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.TraceIdAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.TransportAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UrlPathAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UrlPathWithQueryAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.parser.CompositeVertxRestAccessLogItemMeta;\nimport org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class DefaultCompositeVertxRestAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta {\n  private static final List<VertxRestAccessLogItemMeta> SUPPORTED_META = new ArrayList<>();\n\n  static {\n    final AccessLogItem<RoutingContext> httpMethodItem = new HttpMethodAccessItem();\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%m\", config -> httpMethodItem));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"cs-method\", config -> httpMethodItem));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%s\", config -> new HttpStatusAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"sc-status\", config -> new HttpStatusAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%T\", config -> new DurationSecondAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%D\", config -> new DurationMillisecondAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%h\", config -> new RemoteHostAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%v\", config -> new LocalHostAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%p\", config -> new LocalPortAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%B\", config -> new ResponseSizeAccessItem(\"0\")));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%b\", config -> new ResponseSizeAccessItem(\"-\")));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%r\", config -> new FirstLineOfRequestAccessItem()));\n    final AccessLogItem<RoutingContext> urlPathItem = new UrlPathAccessItem();\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%U\", config -> urlPathItem));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"cs-uri-stem\", config -> urlPathItem));\n    final AccessLogItem<RoutingContext> queryStringItem = new QueryStringAccessItem();\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%q\", config -> queryStringItem));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"cs-uri-query\", config -> queryStringItem));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"cs-uri\", config -> new UrlPathWithQueryAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%H\", config -> new RequestProtocolAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%t\", config -> new ConfigurableDatetimeAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%SCB-traceId\", config -> new TraceIdAccessItem()));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%SCB-transport\", config -> new TransportAccessItem()));\n\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%{\", \"}t\", ConfigurableDatetimeAccessItem::new));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%{\", \"}i\", RequestHeaderAccessItem::new));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%{\", \"}o\", ResponseHeaderAccessItem::new));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%{\", \"}C\", CookieAccessItem::new));\n    SUPPORTED_META.add(new VertxRestAccessLogItemMeta(\"%{\", \"}SCB-ctx\", InvocationContextAccessItem::new));\n  }\n\n  @Override\n  public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {\n    return SUPPORTED_META;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/impl/VertxRestAccessLogPatternParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser.impl;\n\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.PlainTextAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.parser.AccessLogItemMeta;\nimport org.apache.servicecomb.common.accessLog.core.parser.AccessLogPatternParser;\nimport org.apache.servicecomb.common.accessLog.core.parser.CompositeVertxRestAccessLogItemMeta;\nimport org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * The parser is used for rest-over-vertx transport.\n */\npublic class VertxRestAccessLogPatternParser implements AccessLogPatternParser<RoutingContext> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestAccessLogPatternParser.class);\n\n  public static final Comparator<VertxRestAccessLogItemMeta> accessLogItemMetaComparator = (m1, m2) -> {\n    int result = m1.getOrder() - m2.getOrder();\n    if (result != 0) {\n      return result;\n    }\n\n    // one of m1 & m2 has suffix, but the other one doesn't have\n    if (m1.getSuffix() == null ^ m2.getSuffix() == null) {\n      return m1.getSuffix() == null ? 1 : -1;\n    }\n\n    if (null != m1.getSuffix()) {\n      result = comparePlaceholderString(m1.getSuffix(), m2.getSuffix());\n    }\n\n    return 0 == result ?\n        comparePlaceholderString(m1.getPrefix(), m2.getPrefix())\n        : result;\n  };\n\n  private final List<VertxRestAccessLogItemMeta> metaList = new ArrayList<>();\n\n  public VertxRestAccessLogPatternParser() {\n    List<VertxRestAccessLogItemMeta> loadedMeta = loadVertxRestLogItemMeta();\n    if (null == loadedMeta || loadedMeta.isEmpty()) {\n      LOGGER.error(\"cannot load AccessLogItemMeta!\");\n      throw new IllegalStateException(\"cannot load AccessLogItemMeta!\");\n    }\n    for (VertxRestAccessLogItemMeta meta : loadedMeta) {\n      if (CompositeVertxRestAccessLogItemMeta.class.isAssignableFrom(meta.getClass())) {\n        this.metaList.addAll(((CompositeVertxRestAccessLogItemMeta) meta).getAccessLogItemMetas());\n      } else {\n        this.metaList.add(meta);\n      }\n    }\n    sortAccessLogItemMeta(this.metaList);\n  }\n\n  @VisibleForTesting\n  List<VertxRestAccessLogItemMeta> getMetaList() {\n    return metaList;\n  }\n\n  @VisibleForTesting\n  List<VertxRestAccessLogItemMeta> loadVertxRestLogItemMeta() {\n    return SPIServiceUtils.getOrLoadSortedService(VertxRestAccessLogItemMeta.class);\n  }\n\n  /**\n   * Behavior of this compare:\n   * 1. comparePlaceholderString(\"abc\",\"bbc\") &lt; 0\n   * 2. comparePlaceholderString(\"abc\",\"ab\") &lt; 0\n   * 3. comparePlaceholderString(\"abc\",\"abc\") = 0\n   */\n  public static int comparePlaceholderString(String s1, String s2) {\n    int result = s1.compareTo(s2);\n    if (0 == result) {\n      return result;\n    }\n\n    // there are two possible cases:\n    // 1. s1=\"ab\", s2=\"def\"\n    // 2. s1=\"ab\", s2=\"abc\"\n    // in the case1 just return the result, but int the case2 the result should be reversed\n    return result < 0 ?\n        (s2.startsWith(s1) ? -result : result)\n        : (s1.startsWith(s2) ? -result : result);\n  }\n\n  /**\n   * Sort all of the {@link AccessLogItemMeta}, the meta that is in front of the others has higher priority.\n   *\n   * Sort rule(priority decreased):\n   * <ol>\n   *   <li>compare the {@link AccessLogItemMeta#getOrder()}</li>\n   *   <li>compare the {@link AccessLogItemMeta#getSuffix()} in lexicographic order, if one's suffix is start with\n   *   the other one's suffix, this one(who's suffix is longer) has higher priority</li>\n   *   <li>compare the {@link AccessLogItemMeta#getPrefix()}, compare rule is the same as suffix.</li>\n   * </ol>\n   *\n   * e.g. given a list of {@link AccessLogItemMeta} like below:\n   * <ol>\n   * <li>(%ac{,}bcd)</li>\n   * <li>(%ac{,}bc)</li>\n   * <li>(%ac{,}a)</li>\n   * <li>(%ac,)</li>\n   * <li>(%b,)</li>\n   * <li>(%a)</li>\n   * <li>(%{,}b)</li>\n   * <li>(%{,}bc)</li>\n   * </ol>\n   * the result is:\n   * <ol>\n   * <li>(%ac{,}a)</li>\n   * <li>(%ac{,}bcd)</li>\n   * <li>(%ac{,}bc)</li>\n   * <li>(%{,}bc)</li>\n   * <li>(%{,}b)</li>\n   * <li>(%ac,)</li>\n   * <li>(%a)</li>\n   * <li>(%b,)</li>\n   * </ol>\n   */\n  public static void sortAccessLogItemMeta(List<VertxRestAccessLogItemMeta> accessLogItemMetaList) {\n    accessLogItemMetaList.sort(accessLogItemMetaComparator);\n  }\n\n  /**\n   * @param rawPattern The access log pattern string specified by users.\n   * @return A list of {@linkplain AccessLogItem} which actually generate the content of access log.\n   */\n  @Override\n  public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {\n    LOGGER.info(\"parse the pattern of access log: [{}]\", rawPattern);\n    List<AccessLogItemLocation> locationList = matchAccessLogItem(rawPattern);\n    locationList = fillInPlainTextLocation(rawPattern, locationList);\n\n    return convertToItemList(rawPattern, locationList);\n  }\n\n  /**\n   * Use the {@link #metaList} to match rawPattern.\n   * Return a list of {@link AccessLogItemLocation}.\n   * Plain text is ignored.\n   */\n  private List<AccessLogItemLocation> matchAccessLogItem(String rawPattern) {\n    List<AccessLogItemLocation> locationList = new ArrayList<>();\n    int cursor = 0;\n    while (cursor < rawPattern.length()) {\n      AccessLogItemLocation candidate = null;\n      for (VertxRestAccessLogItemMeta meta : metaList) {\n        if (null != candidate && null == meta.getSuffix()) {\n          // if user define item(\"%{\",\"}ab\") and item(\"%{_\",\"}abc\") and the pattern is \"%{_var}ab}abc\"\n          // currently the result is item(\"%{\",\"_var\",\"}ab\"), plaintext(\"}abc\")\n          // is this acceptable?\n\n          // We've gotten an AccessLogItem with suffix, so there is no need to match those without suffix,\n          // just break this match loop\n          cursor = candidate.tail;\n          break;\n        }\n        if (rawPattern.startsWith(meta.getPrefix(), cursor)) {\n          if (null == meta.getSuffix()) {\n            // for simple type AccessLogItem, there is no need to try to match the next item.\n            candidate = new AccessLogItemLocation(cursor, meta);\n            cursor = candidate.tail;\n            break;\n          }\n          // for configurable type, like %{...}i, more check is needed\n          // e.g. \"%{varName1}o ${varName2}i\" should be divided into\n          // ResponseHeaderItem with varName=\"varName1\" and RequestHeaderItem with varName=\"varName2\"\n          // INSTEAD OF RequestHeaderItem with varName=\"varName1}o ${varName2\"\n          int rear = rawPattern.indexOf(meta.getSuffix(), cursor);\n          if (rear < 0) {\n            continue;\n          }\n          if (null == candidate || rear < candidate.suffixIndex) {\n            candidate = new AccessLogItemLocation(cursor, rear, meta);\n          }\n          // There is a matched item which is in front of this item, so this item is ignored.\n        }\n      }\n\n      if (candidate == null) {\n        ++cursor;\n        continue;\n      }\n      locationList.add(candidate);\n    }\n\n    return locationList;\n  }\n\n  /**\n   * After processing of {@link #matchAccessLogItem(String)}, all of the placeholders of {@link AccessLogItem} have been\n   * picked out. So the rest part of rawPattern should be treated as plain text. Those parts will be located in this\n   * method and wrapped as {@link PlainTextAccessItem}.\n   * @param rawPattern raw pattern string of access log\n   * @param locationList locations picked out by {@link #matchAccessLogItem(String)}\n   * @return all of the locations including {@link PlainTextAccessItem}.\n   */\n  private List<AccessLogItemLocation> fillInPlainTextLocation(String rawPattern,\n      List<AccessLogItemLocation> locationList) {\n    List<AccessLogItemLocation> resultList = new ArrayList<>();\n    if (locationList.isEmpty()) {\n      resultList.add(createTextPlainItemLocation(0, rawPattern.length()));\n      return resultList;\n    }\n\n    Iterator<AccessLogItemLocation> itemLocationIterator = locationList.iterator();\n    AccessLogItemLocation previousItemLocation = itemLocationIterator.next();\n    if (previousItemLocation.prefixIndex > 0) {\n      resultList.add(createTextPlainItemLocation(0, previousItemLocation.prefixIndex));\n    }\n    resultList.add(previousItemLocation);\n\n    while (itemLocationIterator.hasNext()) {\n      AccessLogItemLocation thisItemLocation = itemLocationIterator.next();\n      if (previousItemLocation.tail < thisItemLocation.prefixIndex) {\n        resultList.add(createTextPlainItemLocation(previousItemLocation.tail, thisItemLocation.prefixIndex));\n      }\n      previousItemLocation = thisItemLocation;\n      resultList.add(previousItemLocation);\n    }\n\n    if (previousItemLocation.tail < rawPattern.length()) {\n      resultList.add(createTextPlainItemLocation(\n          previousItemLocation.tail,\n          rawPattern.length()));\n    }\n    return resultList;\n  }\n\n  private AccessLogItemLocation createTextPlainItemLocation(int front, int rear) {\n    return new AccessLogItemLocation(front, rear);\n  }\n\n  private List<AccessLogItem<RoutingContext>> convertToItemList(String rawPattern,\n      List<AccessLogItemLocation> locationList) {\n    List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();\n\n    for (AccessLogItemLocation accessLogItemLocation : locationList) {\n      VertxRestAccessLogItemMeta accessLogItemMeta = accessLogItemLocation.accessLogItemMeta;\n      if (null == accessLogItemMeta) {\n        // a PlainTextItem location\n        itemList.add(new PlainTextAccessItem(rawPattern.substring(\n            accessLogItemLocation.prefixIndex, accessLogItemLocation.tail\n        )));\n        continue;\n      }\n\n      itemList.add(accessLogItemMeta.getAccessLogItemCreator().createItem(\n          getConfigString(rawPattern, accessLogItemLocation))\n      );\n    }\n\n    return itemList;\n  }\n\n  private String getConfigString(String rawPattern, AccessLogItemLocation accessLogItemLocation) {\n    if (null == accessLogItemLocation.getSuffix()) {\n      // simple AccessLogItem\n      return null;\n    }\n\n    return rawPattern.substring(\n        accessLogItemLocation.prefixIndex + accessLogItemLocation.getPrefix().length(),\n        accessLogItemLocation.suffixIndex);\n  }\n\n  private static class AccessLogItemLocation {\n    /**\n     * prefixIndex = rawPattern.indexOf(prefix)\n     */\n    final int prefixIndex;\n\n    /**\n     * suffixIndex = rawPattern.indexOf(suffix)\n     */\n    final int suffixIndex;\n\n    /**\n     * tail = suffixIndex + suffix.length()\n     */\n    final int tail;\n\n    VertxRestAccessLogItemMeta accessLogItemMeta;\n\n    /**\n     * for {@link PlainTextAccessItem} only\n     */\n    AccessLogItemLocation(int prefixIndex, int suffixIndex) {\n      this.prefixIndex = prefixIndex;\n      this.suffixIndex = suffixIndex;\n      this.tail = suffixIndex;\n    }\n\n    /**\n     * for configurable type AccessLogItem\n     */\n    AccessLogItemLocation(int prefixIndex, int suffixIndex, VertxRestAccessLogItemMeta accessLogItemMeta) {\n      this.prefixIndex = prefixIndex;\n      this.suffixIndex = suffixIndex;\n      this.tail = suffixIndex + accessLogItemMeta.getSuffix().length();\n      this.accessLogItemMeta = accessLogItemMeta;\n    }\n\n    /**\n     * for simple type AccessLogItem\n     */\n    AccessLogItemLocation(int prefixIndex, VertxRestAccessLogItemMeta accessLogItemMeta) {\n      this.prefixIndex = prefixIndex;\n      this.suffixIndex = prefixIndex + accessLogItemMeta.getPrefix().length();\n      this.tail = this.suffixIndex;\n      this.accessLogItemMeta = accessLogItemMeta;\n    }\n\n    public String getPrefix() {\n      if (null == accessLogItemMeta) {\n        return null;\n      }\n      return accessLogItemMeta.getPrefix();\n    }\n\n    public String getSuffix() {\n      if (null == accessLogItemMeta) {\n        return null;\n      }\n      return accessLogItemMeta.getSuffix();\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/placeholder/AccessLogItemTypeEnum.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.placeholder;\n\n/**\n * record what kinds of access log item we support\n */\npublic enum AccessLogItemTypeEnum {\n  TEXT_PLAIN,\n  // %m, cs-method\n  HTTP_METHOD,\n  // %s, sc-status\n  HTTP_STATUS,\n  // %T\n  DURATION_IN_SECOND,\n  // %D\n  DURATION_IN_MILLISECOND,\n  // %h\n  REMOTE_HOSTNAME,\n  // %v\n  LOCAL_HOSTNAME,\n  // %p\n  LOCAL_PORT,\n  // %B\n  RESPONSE_SIZE,\n  // %b\n  RESPONSE_SIZE_CLF,\n  // %r\n  FIRST_LINE_OF_REQUEST,\n  // %U, cs-uri-stem\n  URL_PATH,\n  // %q, cs-uri-query\n  QUERY_STRING,\n  // cs-uri\n  URL_PATH_WITH_QUERY,\n  //%H\n  REQUEST_PROTOCOL,\n  // %t\n  DATETIME_DEFAULT,\n  // %{PATTERN}t, %{PATTERN|TIMEZONE|LOCALE}t\n  DATETIME_CONFIGURABLE,\n  // %{VARNAME}i\n  REQUEST_HEADER,\n  // %{VARNAME}o\n  RESPONSE_HEADER,\n  // %{VARNAME}C\n  COOKIE,\n  // %SCB-traceId\n  SCB_TRACE_ID,\n  // %{VARNAME}SCB-ctx\n  SCB_INVOCATION_CONTEXT\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/server/ServerDefaultInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.server;\n\nimport org.apache.servicecomb.common.accessLog.AccessLogConfig;\nimport org.apache.servicecomb.common.accessLog.AccessLogInitializer;\nimport org.apache.servicecomb.common.accessLog.core.AccessLogGenerator;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class ServerDefaultInitializer implements AccessLogInitializer {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(\"scb-access\");\n\n  private AccessLogGenerator accessLogGenerator;\n\n  @Override\n  public void init(EventBus eventBus, AccessLogConfig accessLogConfig) {\n    if (!accessLogConfig.isServerLogEnabled()) {\n      return;\n    }\n    accessLogGenerator = new AccessLogGenerator(accessLogConfig.getServerLogPattern());\n    eventBus.register(this);\n  }\n\n  @Subscribe\n  @AllowConcurrentEvents\n  public void onRequestReceived(ServerAccessLogEvent accessLogEvent) {\n    LOGGER.info(accessLogGenerator.generateServerLog(accessLogEvent));\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/main/resources/META-INF/services/org.apache.servicecomb.common.accessLog.AccessLogInitializer",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.common.accessLog.client.ClientDefaultInitializer\norg.apache.servicecomb.common.accessLog.server.ServerDefaultInitializer\n"
  },
  {
    "path": "common/common-access-log/src/main/resources/META-INF/services/org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.common.accessLog.core.parser.impl.DefaultCompositeVertxRestAccessLogItemMeta\n"
  },
  {
    "path": "common/common-access-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.common.accessLog.AccessLogConfiguration\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/AccessLogGeneratorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core;\n\nimport static org.mockito.Mockito.when;\n\nimport java.text.SimpleDateFormat;\nimport java.util.TimeZone;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ConfigurableDatetimeAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.HttpMethodAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.PlainTextAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RemoteHostAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UserDefinedAccessLogItem;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class AccessLogGeneratorTest {\n\n  private static final AccessLogGenerator LOG_GENERATOR = new AccessLogGenerator(\"%m - %t\");\n\n  private static final AccessLogGenerator USER_DEFINED_LOG_GENERATOR = new AccessLogGenerator(\n      \"%h - - %{test-config}user-defined\");\n\n  @Test\n  public void testConstructor() {\n    AccessLogItem<RoutingContext>[] elements = LOG_GENERATOR.getAccessLogItems();\n    Assertions.assertEquals(3, elements.length);\n    Assertions.assertEquals(HttpMethodAccessItem.class, elements[0].getClass());\n    Assertions.assertEquals(PlainTextAccessItem.class, elements[1].getClass());\n    Assertions.assertEquals(ConfigurableDatetimeAccessItem.class, elements[2].getClass());\n  }\n\n  @Test\n  public void testServerLog() {\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);\n    long startMillisecond = 1416863450581L;\n    ServerAccessLogEvent serverAccessLogEvent = new ServerAccessLogEvent();\n    serverAccessLogEvent.setMilliStartTime(startMillisecond).setRoutingContext(context);\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ConfigurableDatetimeAccessItem.DEFAULT_DATETIME_PATTERN,\n        ConfigurableDatetimeAccessItem.DEFAULT_LOCALE);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    when(context.request()).thenReturn(request);\n    when(request.method()).thenReturn(HttpMethod.DELETE);\n\n    String log = LOG_GENERATOR.generateServerLog(serverAccessLogEvent);\n    Assertions.assertEquals(\"DELETE\" + \" - \" + simpleDateFormat.format(startMillisecond), log);\n  }\n\n  @Test\n  public void testClientLog() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    InvocationStageTrace stageTrace = Mockito.mock(InvocationStageTrace.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    long startMillisecond = 1416863450581L;\n    when(stageTrace.getStartInMillis()).thenReturn(startMillisecond);\n    when(stageTrace.calcTotal()).thenReturn(0L);\n    when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);\n\n    InvocationFinishEvent finishEvent = new InvocationFinishEvent(invocation, null);\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ConfigurableDatetimeAccessItem.DEFAULT_DATETIME_PATTERN,\n        ConfigurableDatetimeAccessItem.DEFAULT_LOCALE);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n    when(operationMeta.getHttpMethod()).thenReturn(HttpMethod.DELETE.toString());\n    String log = LOG_GENERATOR.generateClientLog(finishEvent);\n    Assertions.assertEquals(\"DELETE\" + \" - \" + simpleDateFormat.format(startMillisecond), log);\n  }\n\n  @Test\n  public void testUserDefinedLogGenerator() {\n    AccessLogItem<RoutingContext>[] elements = USER_DEFINED_LOG_GENERATOR.getAccessLogItems();\n    Assertions.assertEquals(3, elements.length);\n    Assertions.assertEquals(RemoteHostAccessItem.class, elements[0].getClass());\n    Assertions.assertEquals(PlainTextAccessItem.class, elements[1].getClass());\n    Assertions.assertEquals(UserDefinedAccessLogItem.class, elements[2].getClass());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/CookieItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.Cookie;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.impl.CookieImpl;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class CookieItemTest {\n\n  public static final String COOKIE_NAME = \"cookieName\";\n\n  public static final String COOKIE_VALUE = \"cookieVALUE\";\n\n  private static final CookieAccessItem ELEMENT = new CookieAccessItem(COOKIE_NAME);\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext mockContext;\n\n  private HttpServerRequest httpServerRequest;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    mockContext = Mockito.mock(RoutingContext.class);\n    httpServerRequest = Mockito.mock(HttpServerRequest.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    HashSet<Cookie> cookieSet = new HashSet<>();\n    CookieImpl cookie = new CookieImpl(COOKIE_NAME, COOKIE_VALUE);\n\n    cookieSet.add(cookie);\n    Mockito.when(mockContext.request()).thenReturn(httpServerRequest);\n    Mockito.when(httpServerRequest.cookies()).thenReturn(cookieSet);\n    accessLogEvent.setRoutingContext(mockContext);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(COOKIE_VALUE, strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n\n    Map<String, String> cookieMap = new HashMap<>();\n    cookieMap.put(COOKIE_NAME, COOKIE_VALUE);\n\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    when(restClientRequest.getCookieMap()).thenReturn(cookieMap);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(COOKIE_VALUE, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnCookieCountIsZero() {\n    HashSet<Cookie> cookieSet = new HashSet<>();\n    Mockito.when(mockContext.request()).thenReturn(httpServerRequest);\n    Mockito.when(httpServerRequest.cookies()).thenReturn(cookieSet);\n    accessLogEvent.setRoutingContext(mockContext);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnCookieCountIsZero() {\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    Map<String, String> cookieMap = new HashMap<>();\n\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    when(restClientRequest.getCookieMap()).thenReturn(cookieMap);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n\n  @Test\n  public void serverFormattedElementOnCookieSetIsNull() {\n    Mockito.when(mockContext.request()).thenReturn(httpServerRequest);\n    Mockito.when(httpServerRequest.cookies()).thenReturn(null);\n    accessLogEvent.setRoutingContext(mockContext);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnCookieSetIsNull() {\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    when(restClientRequest.getCookieMap()).thenReturn(null);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n\n  @Test\n  public void serverFormattedElementOnNotFound() {\n    HashSet<Cookie> cookieSet = new HashSet<>();\n    CookieImpl cookie = new CookieImpl(\"anotherCookieName\", COOKIE_VALUE);\n    cookieSet.add(cookie);\n    Mockito.when(mockContext.request()).thenReturn(httpServerRequest);\n    Mockito.when(httpServerRequest.cookies()).thenReturn(cookieSet);\n    accessLogEvent.setRoutingContext(mockContext);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnNotFound() {\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n\n    Map<String, String> cookieMap = new HashMap<>();\n    cookieMap.put(\"anotherCookieValue\", COOKIE_VALUE);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    when(restClientRequest.getCookieMap()).thenReturn(cookieMap);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/DatetimeConfigurableItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Locale;\nimport java.util.TimeZone;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class DatetimeConfigurableItemTest {\n\n  private static final long START_MILLISECOND = 1416863450581L;\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private Invocation invocation;\n\n  private InvocationStageTrace invocationStageTrace;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    when(invocationStageTrace.getStartInMillis()).thenReturn(START_MILLISECOND);\n    when(invocationStageTrace.calcTotal()).thenReturn(0L);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setMilliStartTime(START_MILLISECOND);\n    strBuilder = new StringBuilder();\n  }\n\n\n  @Test\n  public void getFormattedElementOnNoTimezone() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\n        \"yyyy/MM/dd zzz||zh-CN\");\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"yyyy/MM/dd zzz\", Locale.forLanguageTag(\"zh-CN\"));\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnNoTimezone() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\n        \"yyyy/MM/dd zzz||zh-CN\");\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"yyyy/MM/dd zzz\", Locale.forLanguageTag(\"zh-CN\"));\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnNoLocale() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\n        \"EEE, dd MMM yyyy HH:mm:ss zzz|GMT+08|\");\n\n    element.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"Tue, 25 Nov 2014 05:10:50 GMT+08:00\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnNoLocale() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\n        \"EEE, dd MMM yyyy HH:mm:ss zzz|GMT+08|\");\n\n    element.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"Tue, 25 Nov 2014 05:10:50 GMT+08:00\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnNoConfig() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\n        \"||\");\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ConfigurableDatetimeAccessItem.DEFAULT_DATETIME_PATTERN,\n        Locale.US);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnNoConfig() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\n        \"||\");\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ConfigurableDatetimeAccessItem.DEFAULT_DATETIME_PATTERN,\n        Locale.US);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void serverConstructorWithNoArg() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem();\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"EEE, dd MMM yyyy HH:mm:ss zzz\", Locale.US);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"EEE, dd MMM yyyy HH:mm:ss zzz\", element.getPattern());\n    Assertions.assertEquals(Locale.US, element.getLocale());\n    Assertions.assertEquals(TimeZone.getDefault(), element.getTimezone());\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void clientConstructorWithNoArg() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem();\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"EEE, dd MMM yyyy HH:mm:ss zzz\", Locale.US);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"EEE, dd MMM yyyy HH:mm:ss zzz\", element.getPattern());\n    Assertions.assertEquals(Locale.US, element.getLocale());\n    Assertions.assertEquals(TimeZone.getDefault(), element.getTimezone());\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void serverConstructorWithNoSeparator() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\"yyyy/MM/dd HH:mm:ss zzz\");\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"yyyy/MM/dd HH:mm:ss zzz\", Locale.US);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"yyyy/MM/dd HH:mm:ss zzz\", element.getPattern());\n    Assertions.assertEquals(Locale.US, element.getLocale());\n    Assertions.assertEquals(TimeZone.getDefault(), element.getTimezone());\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n\n  @Test\n  public void clientConstructorWithNoSeparator() {\n    ConfigurableDatetimeAccessItem element = new ConfigurableDatetimeAccessItem(\"yyyy/MM/dd HH:mm:ss zzz\");\n    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"yyyy/MM/dd HH:mm:ss zzz\", Locale.US);\n    simpleDateFormat.setTimeZone(TimeZone.getDefault());\n\n    element.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"yyyy/MM/dd HH:mm:ss zzz\", element.getPattern());\n    Assertions.assertEquals(Locale.US, element.getLocale());\n    Assertions.assertEquals(TimeZone.getDefault(), element.getTimezone());\n    Assertions.assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/DurationMillisecondItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class DurationMillisecondItemTest {\n\n  public static final DurationMillisecondAccessItem ELEMENT = new DurationMillisecondAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private Invocation invocation;\n\n  private InvocationStageTrace invocationStageTrace;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    when(invocationStageTrace.calcTotal()).thenReturn(1000_000L);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setMilliStartTime(1L);\n    accessLogEvent.setMilliEndTime(2L);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void testAppendFormattedElement() {\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"1\", strBuilder.toString());\n\n    strBuilder = new StringBuilder();\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"1\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/DurationSecondItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class DurationSecondItemTest {\n\n  public static final DurationSecondAccessItem ELEMENT = new DurationSecondAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private Invocation invocation;\n\n  private InvocationStageTrace invocationStageTrace;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    when(invocationStageTrace.calcTotal()).thenReturn(1L);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setMilliStartTime(1L);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElementOn999ms() {\n    accessLogEvent.setMilliEndTime(1000L);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"0\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOn999ms() {\n    when(invocationStageTrace.calcTotal()).thenReturn(0L);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"0\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOn1000ms() {\n    accessLogEvent.setMilliEndTime(1001L);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"1\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOn1000ms() {\n    when(invocationStageTrace.calcTotal()).thenReturn(1000_000_000L);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"1\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOn1001ms() {\n    accessLogEvent.setMilliEndTime(1002L);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"1\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOn1001ms() {\n    when(invocationStageTrace.calcTotal()).thenReturn(1000_000_000L);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"1\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/FirstLineOfRequestItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.HttpVersion;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class FirstLineOfRequestItemTest {\n\n  public static final FirstLineOfRequestAccessItem ELEMENT = new FirstLineOfRequestAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext mockContext;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpClientRequest clientRequest;\n\n  private Endpoint endpoint;\n\n  private URIEndpointObject urlEndpoint;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    mockContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n    endpoint = Mockito.mock(Endpoint.class);\n    urlEndpoint = Mockito.mock(URIEndpointObject.class);\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(urlEndpoint);\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(mockContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);\n    String uri = \"/test/uri\";\n\n    when(mockContext.request()).thenReturn(request);\n    when(request.method()).thenReturn(HttpMethod.DELETE);\n    when(request.path()).thenReturn(uri);\n    when(request.version()).thenReturn(HttpVersion.HTTP_1_1);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"\\\"DELETE \" + uri + \" HTTP/1.1\\\"\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    String uri = \"/test/uri\";\n    when(clientRequest.getMethod()).thenReturn(HttpMethod.DELETE);\n    when(clientRequest.path()).thenReturn(uri);\n    when(urlEndpoint.isHttp2Enabled()).thenReturn(true);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"\\\"DELETE \" + uri + \" HTTP/2.0\\\"\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/HttpMethodItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class HttpMethodItemTest {\n  private static final HttpMethodAccessItem ITEM = new HttpMethodAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpClientRequest clientRequest;\n\n  private Endpoint endpoint;\n\n  private URIEndpointObject urlEndpoint;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n    endpoint = Mockito.mock(Endpoint.class);\n    urlEndpoint = Mockito.mock(URIEndpointObject.class);\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(urlEndpoint);\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);\n    Mockito.when(routingContext.request()).thenReturn(request);\n    Mockito.when(request.method()).thenReturn(HttpMethod.DELETE);\n    accessLogEvent.setRoutingContext(routingContext);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"DELETE\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.getMethod()).thenReturn(HttpMethod.DELETE);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"DELETE\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRequestIsNull() {\n    accessLogEvent.setRoutingContext(routingContext);\n    Mockito.when(routingContext.request()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n\n  @Test\n  public void serverFormattedElementOnMethodIsNull() {\n    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);\n    accessLogEvent.setRoutingContext(routingContext);\n\n    Mockito.when(routingContext.request()).thenReturn(request);\n    Mockito.when(request.method()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnMethodIsNull() {\n    when(clientRequest.getMethod()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/HttpStatusItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class HttpStatusItemTest {\n\n  private static final HttpStatusAccessItem STATUS_ELEMENT = new HttpStatusAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Response response;\n\n  private HttpServerResponse serverResponse;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    response = Mockito.mock(Response.class);\n    serverResponse = Mockito.mock(HttpServerResponse.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    int statusCode = 200;\n    when(routingContext.response()).thenReturn(serverResponse);\n    when(serverResponse.getStatusCode()).thenReturn(statusCode);\n\n    STATUS_ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"200\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    int statusCode = 200;\n    when(finishEvent.getResponse()).thenReturn(response);\n    when(response.getStatusCode()).thenReturn(statusCode);\n\n    STATUS_ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"200\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnResponseIsNull() {\n    Mockito.when(routingContext.response()).thenReturn(null);\n    STATUS_ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n\n    Mockito.when(routingContext.response()).thenReturn(serverResponse);\n    Mockito.when(serverResponse.closed()).thenReturn(true);\n    Mockito.when(serverResponse.ended()).thenReturn(false);\n\n    strBuilder = new StringBuilder();\n    STATUS_ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnResponseIsNull() {\n    when(finishEvent.getResponse()).thenReturn(null);\n    STATUS_ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/InvocationContextItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class InvocationContextItemTest {\n\n  public static final String INVOCATION_CONTEXT_KEY = \"testKey\";\n\n  public static final String INVOCATION_CONTEXT_VALUE = \"testValue\";\n\n  private static final InvocationContextAccessItem ITEM = new InvocationContextAccessItem(INVOCATION_CONTEXT_KEY);\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverGetFormattedItem() {\n    Map<String, Object> routingContextData = new HashMap<>();\n    when(routingContext.data()).thenReturn(routingContextData);\n    routingContextData.put(RestConst.REST_INVOCATION_CONTEXT, invocation);\n    when(invocation.getContext(INVOCATION_CONTEXT_KEY)).thenReturn(INVOCATION_CONTEXT_VALUE);\n\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(INVOCATION_CONTEXT_VALUE));\n  }\n\n  @Test\n  public void clientGetFormattedItem() {\n    Map<String, String> context = new HashMap<>();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(context);\n    context.put(INVOCATION_CONTEXT_KEY, INVOCATION_CONTEXT_VALUE);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(INVOCATION_CONTEXT_VALUE));\n  }\n\n  @Test\n  public void serverGetFormattedItemOnInvocationContextValueNotFound() {\n    Map<String, Object> routingContextData = new HashMap<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    when(routingContext.data()).thenReturn(routingContextData);\n    routingContextData.put(RestConst.REST_INVOCATION_CONTEXT, invocation);\n    when(invocation.getContext(INVOCATION_CONTEXT_KEY)).thenReturn(null);\n\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n\n  @Test\n  public void clientGetFormattedItemOnInvocationContextValueNotFound() {\n    Map<String, String> context = new HashMap<>();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(context);\n    context.put(INVOCATION_CONTEXT_KEY, null);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n\n  @Test\n  public void serverGetFormattedItemOnInvocationNotFound() {\n    Map<String, Object> routingContextData = new HashMap<>();\n    when(routingContext.data()).thenReturn(routingContextData);\n\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n\n  @Test\n  public void clientGetFormattedItemOnInvocationContextNotFound() {\n    Map<String, String> context = new HashMap<>();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(context);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n\n  @Test\n  public void testGetFormattedItemOnRoutingContextDataNotFound() {\n    when(routingContext.data()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n\n  @Test\n  public void clientGetFormattedItemOnRoutingContextDataNotFound() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n\n  @Test\n  public void clientGetFormattedItemOnInvocationNotFound() {\n    when(finishEvent.getInvocation()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextAccessItem.NOT_FOUND));\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/LocalHostItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpConnection;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class LocalHostItemTest {\n  public static final LocalHostAccessItem ELEMENT = new LocalHostAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private HttpServerRequest serverRequest;\n\n  private SocketAddress socketAddress;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpClientRequest clientRequest;\n\n  private HttpConnection connection;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n    socketAddress = Mockito.mock(SocketAddress.class);\n    invocation = Mockito.mock(Invocation.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n    connection = Mockito.mock(HttpConnection.class);\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void clientFormattedItem() {\n    String localAddress = \"192.168.0.1\";\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.connection()).thenReturn(connection);\n    when(connection.localAddress()).thenReturn(socketAddress);\n    when(socketAddress.host()).thenReturn(localAddress);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(localAddress, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedItem() {\n    String localAddress = \"192.168.0.1\";\n    accessLogEvent.setLocalAddress(localAddress);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(localAddress, strBuilder.toString());\n  }\n\n  @Test\n  public void getLocalAddress() {\n    String localHost = \"testHost\";\n    Mockito.when(routingContext.request()).thenReturn(serverRequest);\n    Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);\n    Mockito.when(socketAddress.host()).thenReturn(localHost);\n\n    String result = LocalHostAccessItem.getLocalAddress(routingContext);\n    Assertions.assertEquals(localHost, result);\n  }\n\n  @Test\n  public void serverLocalAddressOnRequestIsNull() {\n    Mockito.when(routingContext.request()).thenReturn(null);\n    String result = LocalHostAccessItem.getLocalAddress(routingContext);\n    Assertions.assertEquals(\"-\", result);\n  }\n\n  @Test\n  public void clientLocalAddressOnRequestIsNull() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverLocalAddressOnLocalAddressIsNull() {\n    Mockito.when(routingContext.request()).thenReturn(serverRequest);\n    Mockito.when(serverRequest.localAddress()).thenReturn(null);\n    String result = LocalHostAccessItem.getLocalAddress(routingContext);\n    Assertions.assertEquals(\"-\", result);\n  }\n\n  @Test\n  public void clientLocalAddressOnLocalAddressIsNull() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.connection()).thenReturn(connection);\n    when(connection.localAddress()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverLocalAddressOnHostIsNull() {\n    Mockito.when(routingContext.request()).thenReturn(serverRequest);\n    Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);\n    Mockito.when(socketAddress.host()).thenReturn(null);\n\n    String result = LocalHostAccessItem.getLocalAddress(routingContext);\n    Assertions.assertEquals(\"-\", result);\n  }\n\n  @Test\n  public void clientLocalAddressOnHostIsNull() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.connection()).thenReturn(connection);\n    when(connection.localAddress()).thenReturn(socketAddress);\n    when(socketAddress.host()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverLocalAddressIsEmpty() {\n    String localHost = \"\";\n    Mockito.when(routingContext.request()).thenReturn(serverRequest);\n    Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);\n    Mockito.when(socketAddress.host()).thenReturn(localHost);\n\n    String result = LocalHostAccessItem.getLocalAddress(routingContext);\n    Assertions.assertEquals(\"-\", result);\n  }\n\n  @Test\n  public void clientLocalAddressIsEmpty() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.connection()).thenReturn(connection);\n    when(connection.localAddress()).thenReturn(socketAddress);\n    when(socketAddress.host()).thenReturn(\"\");\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/LocalPortItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpConnection;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class LocalPortItemTest {\n  public static final LocalPortAccessItem ELEMENT = new LocalPortAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private HttpServerRequest serverRequest;\n\n  private SocketAddress socketAddress;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpClientRequest clientRequest;\n\n  private HttpConnection connection;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n    socketAddress = Mockito.mock(SocketAddress.class);\n    invocation = Mockito.mock(Invocation.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n    connection = Mockito.mock(HttpConnection.class);\n    Map<String, Object> handlerMap = new HashMap<>();\n    handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerMap);\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    Mockito.when(routingContext.request()).thenReturn(serverRequest);\n    Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);\n    Mockito.when(socketAddress.port()).thenReturn(8080);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"8080\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.connection()).thenReturn(connection);\n    when(connection.localAddress()).thenReturn(socketAddress);\n    when(socketAddress.port()).thenReturn(8080);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"8080\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRequestIsNull() {\n    Mockito.when(routingContext.request()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnLocalAddressIsNull() {\n    Mockito.when(routingContext.request()).thenReturn(serverRequest);\n    Mockito.when(serverRequest.localAddress()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnLocalAddressIsNull() {\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.connection()).thenReturn(connection);\n    when(connection.localAddress()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/PlainTextItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class PlainTextItemTest {\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private StringBuilder strBuilder;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    PlainTextAccessItem element = new PlainTextAccessItem(\"contentTest\");\n    element.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"contentTest\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    PlainTextAccessItem element = new PlainTextAccessItem(\"contentTest\");\n    element.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"contentTest\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/QueryStringItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class QueryStringItemTest {\n  private static final QueryStringAccessItem ITEM = new QueryStringAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpServerRequest serverRequest;\n\n  private HttpClientRequest clientRequest;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    String query = \"?status=up\";\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.query()).thenReturn(query);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(query, strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    String query = \"?status=up\";\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.query()).thenReturn(query);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(query, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRequestIsNull() {\n    when(routingContext.request()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(null);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnQueryIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.query()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnQueryIsNull() {\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.query()).thenReturn(null);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnQueryIsEmpty() {\n    String query = \"\";\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.query()).thenReturn(query);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnQueryIsEmpty() {\n    String query = \"\";\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.query()).thenReturn(query);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RemoteHostItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.ext.web.RoutingContext;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class RemoteHostItemTest {\n  public static final RemoteHostAccessItem ELEMENT = new RemoteHostAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private HttpServerRequest serverRequest;\n\n  private Endpoint endpoint;\n\n  private URIEndpointObject uriEndpointObject;\n\n  private SocketAddress socketAddress;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = mock(RoutingContext.class);\n    finishEvent = mock(InvocationFinishEvent.class);\n    invocation = mock(Invocation.class);\n    serverRequest = mock(HttpServerRequest.class);\n    endpoint = mock(Endpoint.class);\n    uriEndpointObject = mock(URIEndpointObject.class);\n    socketAddress = mock(SocketAddress.class);\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    String remoteHost = \"remoteHost\";\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.remoteAddress()).thenReturn(socketAddress);\n    when(socketAddress.host()).thenReturn(remoteHost);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(remoteHost, strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    String remoteHost = \"remoteHost\";\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(uriEndpointObject);\n    when(uriEndpointObject.getHostOrIp()).thenReturn(remoteHost);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(remoteHost, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRequestIsNull() {\n    when(routingContext.request()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRemoteAddressIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.remoteAddress()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRemoteAddressIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnHostIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.remoteAddress()).thenReturn(socketAddress);\n    when(socketAddress.host()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnHostIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(uriEndpointObject);\n    when(uriEndpointObject.getHostOrIp()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnHostIsEmpty() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.remoteAddress()).thenReturn(socketAddress);\n    when(socketAddress.host()).thenReturn(\"\");\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnHostIsEmpty() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(uriEndpointObject);\n    when(uriEndpointObject.getHostOrIp()).thenReturn(\"\");\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestHeaderItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.impl.headers.HeadersMultiMap;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RequestHeaderItemTest {\n  private static final String VAR_NAME = \"varName\";\n\n  private static final RequestHeaderAccessItem ELEMENT = new RequestHeaderAccessItem(VAR_NAME);\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpServerRequest serverRequest;\n\n  private HttpClientRequest clientRequest;\n\n  private MultiMap headers;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n    headers = Mockito.mock(MultiMap.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    HeadersMultiMap headers = HeadersMultiMap.httpHeaders();\n    String testValue = \"testValue\";\n    headers.add(VAR_NAME, testValue);\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.headers()).thenReturn(headers);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(testValue, strBuilder.toString());\n    Assertions.assertEquals(ELEMENT.getVarName(), VAR_NAME);\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    Map<String, Object> handlerContext = new HashMap<>();\n    String testValue = \"testValue\";\n\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.headers()).thenReturn(headers);\n    when(headers.get(VAR_NAME)).thenReturn(testValue);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(testValue, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementIfHeaderIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.headers()).thenReturn(null);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementIfHeaderIsNull() {\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.headers()).thenReturn(null);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementIfNotFound() {\n    HeadersMultiMap headers = HeadersMultiMap.httpHeaders();\n    String testValue = \"testValue\";\n    headers.add(\"anotherKey\", testValue);\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.headers()).thenReturn(headers);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestProtocolItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.HttpVersion;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RequestProtocolItemTest {\n  private static final RequestProtocolAccessItem ITEM = new RequestProtocolAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private HttpServerRequest serverRequest;\n\n  private Endpoint endpoint;\n\n  private URIEndpointObject urlEndpoint;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n    urlEndpoint = Mockito.mock(URIEndpointObject.class);\n    endpoint = Mockito.mock(Endpoint.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.version()).thenReturn(HttpVersion.HTTP_1_1);\n\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"HTTP/1.1\", strBuilder.toString());\n\n    strBuilder = new StringBuilder();\n    when(serverRequest.version()).thenReturn(HttpVersion.HTTP_1_0);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"HTTP/1.0\", strBuilder.toString());\n\n    strBuilder = new StringBuilder();\n    when(serverRequest.version()).thenReturn(HttpVersion.HTTP_2);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"HTTP/2.0\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(urlEndpoint);\n    when(urlEndpoint.isHttp2Enabled()).thenReturn(true);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"HTTP/2.0\", strBuilder.toString());\n\n    strBuilder = new StringBuilder();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(urlEndpoint);\n    when(urlEndpoint.isHttp2Enabled()).thenReturn(false);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"HTTP/1.1\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnVersionIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.version()).thenReturn(null);\n\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnVersionIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getAddress()).thenReturn(null);\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"HTTP/1.1\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseHeaderItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.core.http.impl.headers.HeadersMultiMap;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class ResponseHeaderItemTest {\n\n  private static final String VAR_NAME = \"varName\";\n\n  private static final ResponseHeaderAccessItem ELEMENT = new ResponseHeaderAccessItem(VAR_NAME);\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private HttpServerResponse serverResponse;\n\n  private Response response;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    serverResponse = Mockito.mock(HttpServerResponse.class);\n    response = Mockito.mock(Response.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    HeadersMultiMap headers = HeadersMultiMap.httpHeaders();\n    String headerValue = \"headerValue\";\n    headers.add(VAR_NAME, headerValue);\n    when(routingContext.response()).thenReturn(serverResponse);\n    when(serverResponse.headers()).thenReturn(headers);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(headerValue, strBuilder.toString());\n    Assertions.assertEquals(ELEMENT.getVarName(), VAR_NAME);\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    String headerValue = \"headerValue\";\n\n    response = Response.ok(null)\n        .setHeader(VAR_NAME, headerValue);\n    when(finishEvent.getResponse()).thenReturn(response);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(headerValue, strBuilder.toString());\n    Assertions.assertEquals(ELEMENT.getVarName(), VAR_NAME);\n  }\n\n  @Test\n  public void serverFormattedElementOnHeadersIsNull() {\n    when(routingContext.response()).thenReturn(serverResponse);\n    when(serverResponse.headers()).thenReturn(null);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnHeadersIsNull() {\n    when(finishEvent.getResponse()).thenReturn(response);\n    when(response.getHeaders()).thenReturn(null);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnResponseIsNull() {\n    when(routingContext.response()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnResponseIsNull() {\n    when(finishEvent.getResponse()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnNotFound() {\n    HeadersMultiMap headers = HeadersMultiMap.httpHeaders();\n    String headerValue = \"headerValue\";\n    headers.add(\"anotherHeader\", headerValue);\n    when(routingContext.response()).thenReturn(serverResponse);\n    when(serverResponse.headers()).thenReturn(headers);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnNotFound() {\n    String headerValue = \"headerValue\";\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.set(\"anotherHeader\", headerValue);\n    when(finishEvent.getResponse()).thenReturn(response);\n    when(response.getHeaders()).thenReturn(headers);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseSizeItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class ResponseSizeItemTest {\n  private static final ResponseSizeAccessItem ELEMENT = new ResponseSizeAccessItem(\"0\");\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private HttpServerResponse serverResponse;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    serverResponse = Mockito.mock(HttpServerResponse.class);\n\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    long bytesWritten = 16L;\n    when(routingContext.response()).thenReturn(serverResponse);\n    when(serverResponse.bytesWritten()).thenReturn(bytesWritten);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(String.valueOf(bytesWritten), strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"0\", strBuilder.toString());\n  }\n\n  @Test\n  public void getFormattedElementOnResponseIsNull() {\n    when(routingContext.response()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"0\", strBuilder.toString());\n  }\n\n  @Test\n  public void getFormattedElementOnBytesWrittenIsZero() {\n    long bytesWritten = 0L;\n    when(routingContext.response()).thenReturn(serverResponse);\n    when(serverResponse.bytesWritten()).thenReturn(bytesWritten);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"0\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/TraceIdItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.hamcrest.core.Is.is;\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class TraceIdItemTest {\n  private static final TraceIdAccessItem ELEMENT = new TraceIdAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private HttpServerRequest serverRequest;\n\n  private Invocation invocation;\n\n  private final Map<String, String> clientContext = new HashMap<>();\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n    clientContext.clear();\n  }\n\n  @Test\n  public void serverGetFormattedElementFromInvocationContext() {\n    Map<String, Object> data = new HashMap<>();\n    String traceIdTest = \"traceIdTest\";\n    when(invocation.getContext(CoreConst.TRACE_ID_NAME)).thenReturn(traceIdTest);\n    when(routingContext.data()).thenReturn(data);\n    data.put(RestConst.REST_INVOCATION_CONTEXT, invocation);\n\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(traceIdTest));\n  }\n\n  @Test\n  public void clientGetFormattedElementFromInvocationContext() {\n    String traceIdTest = \"traceIdTest\";\n    clientContext.put(CoreConst.TRACE_ID_NAME, traceIdTest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(clientContext);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(traceIdTest));\n  }\n\n  @Test\n  public void serverGetFormattedElementFromRequestHeader() {\n    Map<String, Object> data = new HashMap<>();\n    String traceIdTest = \"traceIdTest\";\n    when(invocation.getContext(CoreConst.TRACE_ID_NAME)).thenReturn(null);\n    when(routingContext.data()).thenReturn(data);\n    data.put(RestConst.REST_INVOCATION_CONTEXT, invocation);\n\n    when(serverRequest.getHeader(CoreConst.TRACE_ID_NAME)).thenReturn(traceIdTest);\n    when(routingContext.request()).thenReturn(serverRequest);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(traceIdTest));\n  }\n\n  @Test\n  public void serverGetFormattedElementOnTraceIdNotFound() {\n    Map<String, Object> data = new HashMap<>();\n    when(invocation.getContext(CoreConst.TRACE_ID_NAME)).thenReturn(\"\");\n    when(routingContext.data()).thenReturn(data);\n    data.put(RestConst.REST_INVOCATION_CONTEXT, invocation);\n\n    when(serverRequest.getHeader(CoreConst.TRACE_ID_NAME)).thenReturn(null);\n    when(routingContext.request()).thenReturn(serverRequest);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(\"-\"));\n\n    strBuilder = new StringBuilder();\n    when(invocation.getContext(CoreConst.TRACE_ID_NAME)).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(\"-\"));\n  }\n\n  @Test\n  public void clientGetFormattedElementOnTraceIdNotFound() {\n    clientContext.put(CoreConst.TRACE_ID_NAME, null);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(clientContext);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(\"-\"));\n  }\n\n  @Test\n  public void serverGetFormattedElementOnInvocationContextIsNull() {\n    when(routingContext.data()).thenReturn(null);\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.getHeader(CoreConst.TRACE_ID_NAME)).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(\"-\"));\n  }\n\n  @Test\n  public void clientGetFormattedElementOnInvocationContextIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getContext()).thenReturn(null);\n\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(\"-\"));\n  }\n\n  @Test\n  public void serverGetFormattedElementOnDataIsNull() {\n    when(serverRequest.getHeader(CoreConst.TRACE_ID_NAME)).thenReturn(null);\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(routingContext.data()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    MatcherAssert.assertThat(strBuilder.toString(), is(\"-\"));\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/TransportItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TransportItemTest {\n  private static final TransportAccessItem ITEM = new TransportAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private Invocation invocation;\n\n  private Endpoint endpoint;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    endpoint = Mockito.mock(Endpoint.class);\n    accessLogEvent = new ServerAccessLogEvent();\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getConfigTransportName()).thenReturn(\"rest\");\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"rest\", strBuilder.toString());\n\n    strBuilder = new StringBuilder();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getEndpoint()).thenReturn(\"rest:xxx:30100\");\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"rest\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"rest\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientConfigTransportNameIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getConfigTransportName()).thenReturn(null);\n\n    strBuilder = new StringBuilder();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getEndpoint()).thenReturn(\"rest:xxx:30100\");\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"rest\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientConfigTransportNameIsEmpty() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getConfigTransportName()).thenReturn(\"\");\n    strBuilder = new StringBuilder();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(endpoint);\n    when(endpoint.getEndpoint()).thenReturn(\"rest:xxx:30100\");\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"rest\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientALLIsEmpty() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getConfigTransportName()).thenReturn(null);\n    strBuilder = new StringBuilder();\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getEndpoint()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/UrlPathItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.transport.rest.client.RestClientRequestParameters;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class UrlPathItemTest {\n  private static final UrlPathAccessItem ITEM = new UrlPathAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private HttpServerRequest serverRequest;\n\n  private OperationMeta operationMeta;\n\n  private SchemaMeta schemaMeta;\n\n  private OpenAPI swagger;\n\n  private RestClientRequestParameters restClientRequest;\n\n  private HttpClientRequest clientRequest;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n    operationMeta = Mockito.mock(OperationMeta.class);\n    schemaMeta = Mockito.mock(SchemaMeta.class);\n    swagger = Mockito.mock(OpenAPI.class);\n    restClientRequest = Mockito.mock(RestClientRequestParameters.class);\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    String uri = \"/test\";\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    when(invocation.getSchemaMeta()).thenReturn(schemaMeta);\n    when(schemaMeta.getSwagger()).thenReturn(swagger);\n    when(operationMeta.getOperationPath()).thenReturn(\"/test\");\n\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(uri, strBuilder.toString());\n\n    strBuilder = new StringBuilder();\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(invocation.getOperationMeta()).thenReturn(null);\n    when(invocation.getSchemaMeta()).thenReturn(null);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.path()).thenReturn(uri);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(uri, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    String uri = \"/test\";\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.path()).thenReturn(uri);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(uri, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRequestIsNull() {\n    when(routingContext.request()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnMethodIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.path()).thenReturn(null);\n    ITEM.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnMethodIsNull() {\n    Map<String, Object> handlerContext = new HashMap<>();\n    handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    when(restClientRequest.getHttpClientRequest()).thenReturn(clientRequest);\n    when(clientRequest.path()).thenReturn(null);\n    ITEM.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/UrlPathWithQueryItemTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport static org.mockito.Mockito.when;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class UrlPathWithQueryItemTest {\n\n  public static final UrlPathWithQueryAccessItem ELEMENT = new UrlPathWithQueryAccessItem();\n\n  private StringBuilder strBuilder;\n\n  private InvocationFinishEvent finishEvent;\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n  private Invocation invocation;\n\n  private HttpServerRequest serverRequest;\n\n  @BeforeEach\n  public void initStrBuilder() {\n    accessLogEvent = new ServerAccessLogEvent();\n    routingContext = Mockito.mock(RoutingContext.class);\n    finishEvent = Mockito.mock(InvocationFinishEvent.class);\n    invocation = Mockito.mock(Invocation.class);\n    serverRequest = Mockito.mock(HttpServerRequest.class);\n\n    accessLogEvent.setRoutingContext(routingContext);\n    strBuilder = new StringBuilder();\n  }\n\n  @Test\n  public void serverFormattedElement() {\n    String uri = \"uriTest\";\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.uri()).thenReturn(uri);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(uri, strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElement() {\n    String uri = \"uriTest\";\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH)).thenReturn(uri);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(uri, strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnRequestIsNull() {\n    when(routingContext.request()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnRequestIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnUriIsNull() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.uri()).thenReturn(null);\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnUriIsNull() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH)).thenReturn(null);\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void serverFormattedElementOnUriIsEmpty() {\n    when(routingContext.request()).thenReturn(serverRequest);\n    when(serverRequest.uri()).thenReturn(\"\");\n    ELEMENT.appendServerFormattedItem(accessLogEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n\n  @Test\n  public void clientFormattedElementOnUriIsEmpty() {\n    when(finishEvent.getInvocation()).thenReturn(invocation);\n    when(invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH)).thenReturn(\"\");\n    ELEMENT.appendClientFormattedItem(finishEvent, strBuilder);\n    Assertions.assertEquals(\"-\", strBuilder.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/UserDefinedAccessLogItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * For access log extension test\n */\npublic class UserDefinedAccessLogItem implements AccessLogItem<RoutingContext> {\n  private final String config;\n\n  public UserDefinedAccessLogItem(String config) {\n    this.config = config;\n  }\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(\"user-defined-\")\n        .append(config);\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {\n    builder.append(\"user-defined-\")\n        .append(config);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/UserDefinedAccessLogItemLowPriority.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.element.impl;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\n\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * For access log extension test, will be overridden by {@link RemoteHostAccessItem}(\"%h\"),\n * and takes no effect.\n */\npublic class UserDefinedAccessLogItemLowPriority implements AccessLogItem<RoutingContext> {\n\n  @Override\n  public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {\n    builder.append(\"OverriddenItem\");\n  }\n\n  @Override\n  public void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {\n    builder.append(\"OverriddenItem\");\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/parser/impl/TestCompositeExtendedAccessLogItemMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser.impl;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UserDefinedAccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.parser.CompositeVertxRestAccessLogItemMeta;\nimport org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta;\n\n\npublic class TestCompositeExtendedAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta {\n  private static final List<VertxRestAccessLogItemMeta> META_LIST = new ArrayList<>();\n\n  static {\n    META_LIST.add(new VertxRestAccessLogItemMeta(\"%{\", \"}user-defined\", UserDefinedAccessLogItem::new));\n  }\n\n  @Override\n  public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {\n    return META_LIST;\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/parser/impl/TestSingleExtendedAccessLogItemMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser.impl;\n\n\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UserDefinedAccessLogItemLowPriority;\nimport org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta;\n\npublic class TestSingleExtendedAccessLogItemMeta extends VertxRestAccessLogItemMeta {\n  public TestSingleExtendedAccessLogItemMeta() {\n    super(\"%h\", null, config -> new UserDefinedAccessLogItemLowPriority(), 1);\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/parser/impl/VertxRestAccessLogPatternParserTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.accessLog.core.parser.impl;\n\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.TimeZone;\n\nimport org.apache.servicecomb.common.accessLog.core.element.AccessLogItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.CookieAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ConfigurableDatetimeAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.DurationMillisecondAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.DurationSecondAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.FirstLineOfRequestAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.HttpMethodAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.HttpStatusAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.InvocationContextAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.LocalHostAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.LocalPortAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.QueryStringAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RemoteHostAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RequestHeaderAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.RequestProtocolAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ResponseHeaderAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.ResponseSizeAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.TraceIdAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.TransportAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UrlPathAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.UrlPathWithQueryAccessItem;\nimport org.apache.servicecomb.common.accessLog.core.parser.CompositeVertxRestAccessLogItemMeta;\nimport org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class VertxRestAccessLogPatternParserTest {\n  private static final String ROW_PATTERN = \"[cs-method] %m %s%T%D%h%v%p%B%b%r%U%q\"\n      + \"cs-uri-stemcs-uri-querycs-uri%H%t%{yyyy MM dd HH:mm:ss zzz}t\"\n      + \"%{yyyy MM dd HH:mm:ss|GMT+0|en-US}t\"\n      + \"%{incoming-header}i\"\n      + \"%{outgoing-header}o\"\n      + \"%{cookie}C\"\n      + \"%SCB-traceId\"\n      + \"%{ctx}SCB-ctx\"\n      + \"%SCB-transport\";\n\n  private static final VertxRestAccessLogPatternParser logPatternParser = new VertxRestAccessLogPatternParser();\n\n  private ServerAccessLogEvent accessLogEvent;\n\n  private RoutingContext routingContext;\n\n\n  @BeforeEach\n  public void initStrBuilder() {\n    routingContext = Mockito.mock(RoutingContext.class);\n    accessLogEvent = new ServerAccessLogEvent();\n    accessLogEvent.setRoutingContext(routingContext);\n  }\n\n  @Test\n  public void testParsePatternFullTest() {\n    List<AccessLogItem<RoutingContext>> result = logPatternParser.parsePattern(ROW_PATTERN);\n    Assertions.assertEquals(29, result.size());\n    StringBuilder builder = new StringBuilder();\n    result.get(0).appendServerFormattedItem(accessLogEvent, builder);\n    Assertions.assertEquals(\"[\", builder.toString());\n    Assertions.assertEquals(HttpMethodAccessItem.class, result.get(1).getClass());\n    builder = new StringBuilder();\n    result.get(2).appendServerFormattedItem(accessLogEvent, builder);\n    Assertions.assertEquals(\"] \", builder.toString());\n    Assertions.assertEquals(HttpMethodAccessItem.class, result.get(3).getClass());\n    builder = new StringBuilder();\n    result.get(4).appendServerFormattedItem(accessLogEvent, builder);\n    Assertions.assertEquals(\" \", builder.toString());\n    Assertions.assertEquals(HttpStatusAccessItem.class, result.get(5).getClass());\n    Assertions.assertEquals(DurationSecondAccessItem.class, result.get(6).getClass());\n    Assertions.assertEquals(DurationMillisecondAccessItem.class, result.get(7).getClass());\n    Assertions.assertEquals(RemoteHostAccessItem.class, result.get(8).getClass());\n    Assertions.assertEquals(LocalHostAccessItem.class, result.get(9).getClass());\n    Assertions.assertEquals(LocalPortAccessItem.class, result.get(10).getClass());\n    Assertions.assertEquals(ResponseSizeAccessItem.class, result.get(11).getClass());\n    Assertions.assertEquals(\"0\", ((ResponseSizeAccessItem) result.get(11)).getZeroBytes());\n    Assertions.assertEquals(ResponseSizeAccessItem.class, result.get(12).getClass());\n    Assertions.assertEquals(\"-\", ((ResponseSizeAccessItem) result.get(12)).getZeroBytes());\n    Assertions.assertEquals(FirstLineOfRequestAccessItem.class, result.get(13).getClass());\n    Assertions.assertEquals(UrlPathAccessItem.class, result.get(14).getClass());\n    Assertions.assertEquals(QueryStringAccessItem.class, result.get(15).getClass());\n    Assertions.assertEquals(UrlPathAccessItem.class, result.get(16).getClass());\n    Assertions.assertEquals(QueryStringAccessItem.class, result.get(17).getClass());\n    Assertions.assertEquals(UrlPathWithQueryAccessItem.class, result.get(18).getClass());\n    Assertions.assertEquals(RequestProtocolAccessItem.class, result.get(19).getClass());\n    Assertions.assertEquals(ConfigurableDatetimeAccessItem.class, result.get(20).getClass());\n    Assertions.assertEquals(ConfigurableDatetimeAccessItem.DEFAULT_DATETIME_PATTERN,\n        ((ConfigurableDatetimeAccessItem) result.get(20)).getPattern());\n    Assertions.assertEquals(ConfigurableDatetimeAccessItem.DEFAULT_LOCALE, ((ConfigurableDatetimeAccessItem) result.get(20)).getLocale());\n    Assertions.assertEquals(TimeZone.getDefault(), ((ConfigurableDatetimeAccessItem) result.get(20)).getTimezone());\n    Assertions.assertEquals(\"yyyy MM dd HH:mm:ss zzz\", ((ConfigurableDatetimeAccessItem) result.get(21)).getPattern());\n    Assertions.assertEquals(ConfigurableDatetimeAccessItem.DEFAULT_LOCALE, ((ConfigurableDatetimeAccessItem) result.get(21)).getLocale());\n    Assertions.assertEquals(TimeZone.getDefault(), ((ConfigurableDatetimeAccessItem) result.get(21)).getTimezone());\n    Assertions.assertEquals(\"yyyy MM dd HH:mm:ss\", ((ConfigurableDatetimeAccessItem) result.get(22)).getPattern());\n    Assertions.assertEquals(Locale.forLanguageTag(\"en-US\"), ((ConfigurableDatetimeAccessItem) result.get(22)).getLocale());\n    Assertions.assertEquals(TimeZone.getTimeZone(\"GMT+0\"), ((ConfigurableDatetimeAccessItem) result.get(22)).getTimezone());\n    Assertions.assertEquals(RequestHeaderAccessItem.class, result.get(23).getClass());\n    Assertions.assertEquals(\"incoming-header\", ((RequestHeaderAccessItem) result.get(23)).getVarName());\n    Assertions.assertEquals(ResponseHeaderAccessItem.class, result.get(24).getClass());\n    Assertions.assertEquals(\"outgoing-header\", ((ResponseHeaderAccessItem) result.get(24)).getVarName());\n    Assertions.assertEquals(CookieAccessItem.class, result.get(25).getClass());\n    Assertions.assertEquals(\"cookie\", ((CookieAccessItem) result.get(25)).getVarName());\n    Assertions.assertEquals(TraceIdAccessItem.class, result.get(26).getClass());\n    Assertions.assertEquals(InvocationContextAccessItem.class, result.get(27).getClass());\n    Assertions.assertEquals(\"ctx\", ((InvocationContextAccessItem) result.get(27)).getVarName());\n    Assertions.assertEquals(TransportAccessItem.class, result.get(28).getClass());\n  }\n\n  @Test\n  public void testParsePattern() {\n    String pattern = \" %m  cs-uri-stem %{response-header}o \";\n    List<AccessLogItem<RoutingContext>> result = logPatternParser.parsePattern(pattern);\n    Assertions.assertEquals(7, result.size());\n    StringBuilder stringBuilder = new StringBuilder();\n    result.get(0).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" \", stringBuilder.toString());\n    Assertions.assertEquals(HttpMethodAccessItem.class, result.get(1).getClass());\n    stringBuilder = new StringBuilder();\n    result.get(2).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\"  \", stringBuilder.toString());\n    Assertions.assertEquals(UrlPathAccessItem.class, result.get(3).getClass());\n    stringBuilder = new StringBuilder();\n    result.get(4).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" \", stringBuilder.toString());\n    Assertions.assertEquals(ResponseHeaderAccessItem.class, result.get(5).getClass());\n    Assertions.assertEquals(\"response-header\", ((ResponseHeaderAccessItem) result.get(5)).getVarName());\n    stringBuilder = new StringBuilder();\n    result.get(6).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" \", stringBuilder.toString());\n  }\n\n  @Test\n  public void testParsePatternWithNoBlank() {\n    String pattern = \"%mcs-uri-stem%{response-header}o\";\n    List<AccessLogItem<RoutingContext>> result = logPatternParser.parsePattern(pattern);\n    Assertions.assertEquals(3, result.size());\n\n    Assertions.assertEquals(HttpMethodAccessItem.class, result.get(0).getClass());\n    Assertions.assertEquals(UrlPathAccessItem.class, result.get(1).getClass());\n    Assertions.assertEquals(ResponseHeaderAccessItem.class, result.get(2).getClass());\n    Assertions.assertEquals(\"response-header\", ((ResponseHeaderAccessItem) result.get(2)).getVarName());\n  }\n\n  @Test\n  public void testParsePatternComplex() {\n    String pattern = \"%m  cs-uri-stem %{response-header}o abc cs-uri-query %s%{request} header}i plain cs-uri\";\n    List<AccessLogItem<RoutingContext>> result = logPatternParser.parsePattern(pattern);\n    Assertions.assertEquals(12, result.size());\n\n    Assertions.assertEquals(HttpMethodAccessItem.class, result.get(0).getClass());\n    StringBuilder stringBuilder = new StringBuilder();\n    result.get(1).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\"  \", stringBuilder.toString());\n    Assertions.assertEquals(UrlPathAccessItem.class, result.get(2).getClass());\n    stringBuilder = new StringBuilder();\n    result.get(3).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" \", stringBuilder.toString());\n    Assertions.assertEquals(ResponseHeaderAccessItem.class, result.get(4).getClass());\n    Assertions.assertEquals(\"response-header\", ((ResponseHeaderAccessItem) result.get(4)).getVarName());\n    stringBuilder = new StringBuilder();\n    result.get(5).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" abc \", stringBuilder.toString());\n    Assertions.assertEquals(QueryStringAccessItem.class, result.get(6).getClass());\n    stringBuilder = new StringBuilder();\n    result.get(7).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" \", stringBuilder.toString());\n    Assertions.assertEquals(HttpStatusAccessItem.class, result.get(8).getClass());\n    Assertions.assertEquals(RequestHeaderAccessItem.class, result.get(9).getClass());\n    Assertions.assertEquals(\"request} header\", ((RequestHeaderAccessItem) result.get(9)).getVarName());\n    stringBuilder = new StringBuilder();\n    result.get(10).appendServerFormattedItem(accessLogEvent, stringBuilder);\n    Assertions.assertEquals(\" plain \", stringBuilder.toString());\n    Assertions.assertEquals(UrlPathWithQueryAccessItem.class, result.get(11).getClass());\n  }\n\n  final Comparator<VertxRestAccessLogItemMeta> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaComparator;\n\n  /**\n   * one factor test\n   */\n  @Test\n  public void testCompareMetaSimple() {\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(null, null, null, 0),\n            new VertxRestAccessLogItemMeta(null, null, null, 1)\n        ) < 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(null, \"}abc\", null, 0),\n            new VertxRestAccessLogItemMeta(null, null, null, 0)\n        ) < 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(null, \"}abc\", null, 0),\n            new VertxRestAccessLogItemMeta(null, \"}de\", null, 0)\n        ) < 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(null, \"}abc\", null, 0),\n            new VertxRestAccessLogItemMeta(null, \"}ab\", null, 0)\n        ) < 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(\"%abc\", null, null, 0),\n            new VertxRestAccessLogItemMeta(\"%de\", null, null, 0)\n        ) < 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(\"%abc\", null, null, 0),\n            new VertxRestAccessLogItemMeta(\"%ab\", null, null, 0)\n        ) < 0\n    );\n    Assertions.assertEquals(0, comparator.compare(\n        new VertxRestAccessLogItemMeta(\"%abc\", null, null, 0),\n        new VertxRestAccessLogItemMeta(\"%abc\", null, null, 0)\n    ));\n  }\n\n  /**\n   * multiple factors test\n   */\n  @Test\n  public void testCompareMetaComplex() {\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(\"%bcd\", \"}ab\", null, 0),\n            new VertxRestAccessLogItemMeta(\"%abc\", \"}abc\", null, 0)\n        ) > 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(\"%abc\", null, null, 0),\n            new VertxRestAccessLogItemMeta(\"%bcd\", \"}ab\", null, 0)\n        ) > 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(\"%bcd\", \"}abc\", null, 0),\n            new VertxRestAccessLogItemMeta(\"%abc\", \"}abc\", null, 0)\n        ) > 0\n    );\n    Assertions.assertTrue(\n        comparator.compare(\n            new VertxRestAccessLogItemMeta(\"%abc\", \"}abc\", null, 1),\n            new VertxRestAccessLogItemMeta(\"%ab\", \"}ab\", null, 0)\n        ) > 0\n    );\n  }\n\n  @Test\n  public void testComparePlaceholderString() {\n    Assertions.assertTrue(\n        VertxRestAccessLogPatternParser.comparePlaceholderString(\"abc\", \"bbc\") < 0\n    );\n    Assertions.assertTrue(\n        VertxRestAccessLogPatternParser.comparePlaceholderString(\"abc\", \"ab\") < 0\n    );\n    Assertions.assertEquals(0, VertxRestAccessLogPatternParser.comparePlaceholderString(\"abc\", \"abc\"));\n    Assertions.assertTrue(\n        VertxRestAccessLogPatternParser.comparePlaceholderString(\"bbc\", \"abc\") > 0\n    );\n    Assertions.assertTrue(\n        VertxRestAccessLogPatternParser.comparePlaceholderString(\"ab\", \"abc\") > 0\n    );\n  }\n\n  @Test\n  public void testExtendedVertxRestAccessLogItemCreator() {\n    final List<VertxRestAccessLogItemMeta> metaList0 = new ArrayList<>();\n    metaList0.add(new VertxRestAccessLogItemMeta(\"%{\", \"}abc\", null));\n    metaList0.add(new VertxRestAccessLogItemMeta(\"%{\", \"}a\", null));\n    metaList0.add(new VertxRestAccessLogItemMeta(\"%_\", null, null, -1));\n\n    final List<VertxRestAccessLogItemMeta> metaList1 = new ArrayList<>();\n    metaList0.add(new VertxRestAccessLogItemMeta(\"%a\", \"}abc\", null));\n    metaList0.add(new VertxRestAccessLogItemMeta(\"%0\", \"}abc\", null, 1));\n    metaList0.add(new VertxRestAccessLogItemMeta(\"%m\", null, null));\n\n    CompositeVertxRestAccessLogItemMeta compositeMeta0 = new CompositeVertxRestAccessLogItemMeta() {\n      @Override\n      public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {\n        return metaList0;\n      }\n    };\n    CompositeVertxRestAccessLogItemMeta compositeMeta1 = new CompositeVertxRestAccessLogItemMeta() {\n      @Override\n      public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {\n        return metaList1;\n      }\n    };\n\n    List<VertxRestAccessLogItemMeta> metaList = new ArrayList<>(1);\n    metaList.add(compositeMeta0);\n    metaList.add(compositeMeta1);\n    metaList.add(new VertxRestAccessLogItemMeta(\"%{\", null, null));\n\n    VertxRestAccessLogPatternParser parser = Mockito.mock(VertxRestAccessLogPatternParser.class);\n    Mockito.when(parser.getMetaList()).thenAnswer(invocation -> {\n      List<VertxRestAccessLogItemMeta> resultMetaList = new ArrayList<>();\n      for (VertxRestAccessLogItemMeta meta : metaList) {\n        if (CompositeVertxRestAccessLogItemMeta.class.isAssignableFrom(meta.getClass())) {\n          resultMetaList.addAll(((CompositeVertxRestAccessLogItemMeta) meta).getAccessLogItemMetas());\n        } else {\n          resultMetaList.add(meta);\n        }\n      }\n      VertxRestAccessLogPatternParser.sortAccessLogItemMeta(resultMetaList);\n      return resultMetaList;\n    });\n\n    List<VertxRestAccessLogItemMeta> accessLogItemMetaList = parser.getMetaList();\n\n    Assertions.assertEquals(7, accessLogItemMetaList.size());\n    Assertions.assertEquals(\"%_\", accessLogItemMetaList.get(0).getPrefix());\n    Assertions.assertEquals(\"%a\", accessLogItemMetaList.get(1).getPrefix());\n    Assertions.assertEquals(\"}abc\", accessLogItemMetaList.get(1).getSuffix());\n    Assertions.assertEquals(\"%{\", accessLogItemMetaList.get(2).getPrefix());\n    Assertions.assertEquals(\"}abc\", accessLogItemMetaList.get(2).getSuffix());\n    Assertions.assertEquals(\"%{\", accessLogItemMetaList.get(3).getPrefix());\n    Assertions.assertEquals(\"}a\", accessLogItemMetaList.get(3).getSuffix());\n    Assertions.assertEquals(\"%m\", accessLogItemMetaList.get(4).getPrefix());\n    Assertions.assertNull(accessLogItemMetaList.get(4).getSuffix());\n    Assertions.assertEquals(\"%{\", accessLogItemMetaList.get(5).getPrefix());\n    Assertions.assertNull(accessLogItemMetaList.get(5).getSuffix());\n    Assertions.assertEquals(\"%0\", accessLogItemMetaList.get(6).getPrefix());\n    Assertions.assertEquals(\"}abc\", accessLogItemMetaList.get(6).getSuffix());\n  }\n}\n"
  },
  {
    "path": "common/common-access-log/src/test/resources/META-INF/services/org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.common.accessLog.core.parser.impl.TestCompositeExtendedAccessLogItemMeta\norg.apache.servicecomb.common.accessLog.core.parser.impl.TestSingleExtendedAccessLogItemMeta\n"
  },
  {
    "path": "common/common-protobuf/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>common</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>common-protobuf</artifactId>\n  <name>Java Chassis::Common::Protobuf</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-protobuf</artifactId>\n    </dependency>\n    <!-- will not update anymore, only for testing -->\n    <dependency>\n      <groupId>com.google.protobuf</groupId>\n      <artifactId>protobuf-java</artifactId>\n      <scope>test</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-springmvc</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.xolstice.maven.plugins</groupId>\n        <artifactId>protobuf-maven-plugin</artifactId>\n        <version>${protobuf-maven-plugin.version}</version>\n        <configuration>\n          <protocArtifact>com.google.protobuf:protoc:${protoc3-maven-plugin.version}:exe:${os.detected.classifier}</protocArtifact>\n          <checkStaleness>true</checkStaleness>\n          <pluginId>grpc-java</pluginId>\n          <pluginArtifact>io.grpc:protoc-gen-grpc-java:${protoc-gen-grpc-java-plugin.version}:exe:${os.detected.classifier}\n          </pluginArtifact>\n        </configuration>\n        <executions>\n          <execution>\n            <phase>generate-test-sources</phase>\n            <goals>\n              <goal>test-compile</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/HighwayJsonUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.time.Instant;\nimport java.time.LocalDateTime;\nimport java.time.ZoneOffset;\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.utils.RestObjectMapper;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n/**\n * Add a separate converter for highway. Now highway compile types depends on swagger information, do not use any consumer information,\n * This will cause any invocation will convert swagger raw types to consumer types. This will lose performance.\n *\n * In later improvements, need add consumer information to OperationProtobuf.\n *\n * Why not using RestObjectMapper? Because the reason above, highway use java.util.Date for date-time, and will serialize to a String\n * that can not convert to LocalDateTime. (This is a jackson change to format java.util.Date to `2017-07-21T16:32:28.320+0000`\n * but jackson can only convert `2017-07-21T16:32:28.320Z` to LocalDateTime\n */\npublic class HighwayJsonUtils {\n\n  public static final ObjectMapper OBJ_MAPPER = new RestObjectMapper();\n\n\n  private HighwayJsonUtils() {\n\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T convertValue(Object fromValue, JavaType toValueType) {\n    if (fromValue == null) {\n      return null;\n    }\n\n    if (TypeFactory.defaultInstance().constructType(LocalDateTime.class).equals(toValueType)) {\n      // jackson do not have a proper converter for this.\n      if (fromValue instanceof Date) {\n        return (T) LocalDateTime.ofInstant(Instant.ofEpochMilli(((Date) fromValue).getTime()), ZoneOffset.UTC);\n      }\n    }\n    return OBJ_MAPPER.convertValue(fromValue, toValueType);\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.compiler.model.Message;\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.Status.Family;\n\npublic final class OperationProtobuf {\n  private RequestRootSerializer requestRootSerializer;\n\n  private RequestRootDeserializer<Object> requestRootDeserializer;\n\n  private ResponseRootSerializer responseRootSerializer;\n\n  private ResponseRootDeserializer<Object> responseRootDeserializer;\n\n  private ResponseRootSerializer anyResponseRootSerializer;\n\n  private ResponseRootDeserializer<Object> anyResponseRootDeserializer;\n\n  public OperationProtobuf(ScopedProtobufSchemaManager scopedProtobufSchemaManager, Invocation invocation) {\n    initRequestCodec(scopedProtobufSchemaManager, invocation);\n    initResponseCodec(scopedProtobufSchemaManager, invocation);\n  }\n\n  public RequestRootSerializer getRequestRootSerializer() {\n    return this.requestRootSerializer;\n  }\n\n  public RequestRootDeserializer<Object> getRequestRootDeserializer() {\n    return this.requestRootDeserializer;\n  }\n\n  public ResponseRootSerializer findResponseRootSerializer(int statusCode) {\n    if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {\n      return this.responseRootSerializer;\n    }\n    return anyResponseRootSerializer;\n  }\n\n  public ResponseRootDeserializer<Object> findResponseRootDeserializer(int statusCode) {\n    if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {\n      return this.responseRootDeserializer;\n    }\n    return anyResponseRootDeserializer;\n  }\n\n  private void initProducerRequestCodec(Invocation invocation, Message requestMessage, ProtoMapper mapper) {\n    Map<String, Type> swaggerParameterTypes = invocation.getOperationMeta().getSwaggerProducerOperation()\n        .getSwaggerParameterTypes();\n    if (ProtoUtils.isWrapArguments(requestMessage)) {\n      requestRootDeserializer = new RequestRootDeserializer<>(\n          mapper.createRootDeserializer(requestMessage, swaggerParameterTypes), true, null);\n    } else {\n      if (swaggerParameterTypes.isEmpty()) {\n        requestRootDeserializer = new RequestRootDeserializer<>(\n            mapper.createRootDeserializer(requestMessage, Object.class), false, null);\n      } else if (swaggerParameterTypes.size() == 1) {\n        Entry<String, Type> entry = swaggerParameterTypes.entrySet().iterator().next();\n        requestRootDeserializer = new RequestRootDeserializer<>(mapper.createRootDeserializer(requestMessage,\n            entry.getValue()), false, entry.getKey());\n      } else {\n        throw new IllegalStateException(\n            \"unexpected operation definition \" + invocation.getOperationMeta().getMicroserviceQualifiedName());\n      }\n    }\n  }\n\n  private void initConsumerRequestCodec(Invocation invocation, Message requestMessage, ProtoMapper mapper) {\n    if (ProtoUtils.isWrapArguments(requestMessage)) {\n      requestRootSerializer = new RequestRootSerializer(\n          mapper.createRootSerializer(requestMessage, Object.class), true, false);\n    } else {\n      if (invocation.getOperationMeta().parameterCount() == 0) {\n        requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage, Object.class),\n            false, false);\n      } else if (invocation.getOperationMeta().parameterCount() == 1) {\n        requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage,\n            Object.class), false, true);\n      } else {\n        throw new IllegalStateException(\n            \"unexpected operation definition \" + invocation.getOperationMeta().getMicroserviceQualifiedName());\n      }\n    }\n  }\n\n  private void initRequestCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, Invocation invocation) {\n    ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(invocation.getSchemaMeta());\n    Message requestMessage = mapper.getRequestMessage(invocation.getOperationMeta().getOperationId());\n\n    if (invocation.isProducer()) {\n      initProducerRequestCodec(invocation, requestMessage, mapper);\n    } else {\n      initConsumerRequestCodec(invocation, requestMessage, mapper);\n    }\n  }\n\n  private void initProviderResponseCode(Message responseMessage, ProtoMapper mapper,\n      JavaType responseType) {\n    if (ProtoUtils.isWrapProperty(responseMessage)) {\n      responseRootSerializer = new ResponseRootSerializer(\n          mapper.createRootSerializer(responseMessage, responseType), true, false);\n    } else {\n      if (ProtoUtils.isEmptyMessage(responseMessage)) {\n        responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,\n            Object.class), false, false);\n      } else {\n        responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,\n            responseType), false, true);\n      }\n    }\n  }\n\n  private void initConsumerResponseCode(Message responseMessage, ProtoMapper mapper,\n      JavaType responseType) {\n    if (ProtoUtils.isWrapProperty(responseMessage)) {\n      responseRootSerializer = new ResponseRootSerializer(\n          mapper.createRootSerializer(responseMessage, responseType), true, false);\n      responseRootDeserializer = new ResponseRootDeserializer<>(\n          mapper.createRootDeserializer(responseMessage, responseType), false);\n    } else {\n      if (ProtoUtils.isEmptyMessage(responseMessage)) {\n        responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,\n            Object.class), false, false);\n        responseRootDeserializer = new ResponseRootDeserializer<>(\n            mapper.createRootDeserializer(responseMessage, Object.class), true);\n      } else {\n        responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,\n            responseType), false, false);\n        responseRootDeserializer = new ResponseRootDeserializer<>(\n            mapper.createRootDeserializer(responseMessage, responseType), false);\n      }\n    }\n  }\n\n  private void initResponseCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, Invocation invocation) {\n    ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(invocation.getSchemaMeta());\n    Message responseMessage = mapper.getResponseMessage(invocation.getOperationMeta().getOperationId());\n\n    JavaType responseType = invocation.findResponseType(Status.OK.getStatusCode());\n    if (invocation.isProducer()) {\n      initProviderResponseCode(responseMessage, mapper, responseType);\n    } else {\n      initConsumerResponseCode(responseMessage, mapper, responseType);\n    }\n    anyResponseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(ProtoConst.ANY,\n        Object.class), false, true);\n    anyResponseRootDeserializer = new ResponseRootDeserializer<>(\n        mapper.createRootDeserializer(ProtoConst.ANY, Object.class), false);\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Objects;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.google.common.annotations.VisibleForTesting;\n\npublic final class ProtobufManager {\n  public static final String EXT_ID = \"protobuf\";\n\n  private static final Object LOCK = new Object();\n\n  static class RuntimeCacheKey {\n    final InvocationType invocationType;\n\n    final String uniqueOperationId;\n\n    // Using response type as the cache key.\n    // May consider request type as well, but now not implemented\n    final JavaType responseType;\n\n    public RuntimeCacheKey(InvocationType invocationType, String operationId, JavaType responseType) {\n      this.invocationType = invocationType;\n      this.uniqueOperationId = operationId;\n      this.responseType = responseType;\n    }\n\n\n    @Override\n    public boolean equals(Object o) {\n      if (this == o) {\n        return true;\n      }\n      if (o == null || getClass() != o.getClass()) {\n        return false;\n      }\n\n      RuntimeCacheKey that = (RuntimeCacheKey) o;\n\n      if (invocationType != that.invocationType) {\n        return false;\n      }\n      if (!uniqueOperationId.equals(that.uniqueOperationId)) {\n        return false;\n      }\n      return Objects.equals(responseType, that.responseType);\n    }\n\n    @Override\n    public int hashCode() {\n      int result = invocationType.hashCode();\n      result = 31 * result + uniqueOperationId.hashCode();\n      result = 31 * result + (responseType != null ? responseType.hashCode() : 0);\n      return result;\n    }\n  }\n\n  private static final Map<RuntimeCacheKey, OperationProtobuf> RUNTIME_CACHE = new HashMap<>();\n\n  public static OperationProtobuf getOrCreateOperation(Invocation invocation) {\n    RuntimeCacheKey cacheKey = new RuntimeCacheKey(invocation.getInvocationType(),\n        invocation.getOperationMeta().getMicroserviceQualifiedName(),\n        invocation.findResponseType(Status.OK.getStatusCode()));\n    OperationProtobuf operationProtobuf = RUNTIME_CACHE.get(cacheKey);\n    if (operationProtobuf == null) {\n      synchronized (LOCK) {\n        MicroserviceMeta microserviceMeta = invocation.getMicroserviceMeta();\n        ScopedProtobufSchemaManager scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);\n        if (scopedProtobufSchemaManager == null) {\n          scopedProtobufSchemaManager = new ScopedProtobufSchemaManager();\n          microserviceMeta.putExtData(EXT_ID, scopedProtobufSchemaManager);\n        }\n\n        operationProtobuf = RUNTIME_CACHE.get(cacheKey);\n        if (operationProtobuf == null) {\n          operationProtobuf = new OperationProtobuf(scopedProtobufSchemaManager, invocation);\n          RUNTIME_CACHE.put(cacheKey, operationProtobuf);\n        }\n      }\n    }\n\n    return operationProtobuf;\n  }\n\n  @VisibleForTesting\n  public static void clear() {\n    RUNTIME_CACHE.clear();\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootDeserializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\n\npublic class RequestRootDeserializer<T> {\n  private final boolean wrapArgument;\n\n  private final String parameterName;\n\n  private final RootDeserializer<T> rootDeserializer;\n\n  public RequestRootDeserializer(RootDeserializer<T> rootDeserializer, boolean wrapArgument, String parameterName) {\n    this.rootDeserializer = rootDeserializer;\n    this.wrapArgument = wrapArgument;\n    this.parameterName = parameterName;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public Map<String, Object> deserialize(byte[] bytes) throws IOException {\n    if (!wrapArgument) {\n      Map<String, Object> result = new HashMap<>(1);\n      Object obj = rootDeserializer.deserialize(bytes);\n      if (obj instanceof PropertyWrapper) {\n        obj = ((PropertyWrapper) obj).getValue();\n      }\n      if (parameterName == null) {\n        return result;\n      }\n      result.put(parameterName, obj);\n      return result;\n    } else {\n      return (Map<String, Object>) rootDeserializer.deserialize(bytes);\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootSerializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.io.IOException;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\nimport io.vertx.core.json.JsonObject;\n\npublic class RequestRootSerializer {\n  private final RootSerializer rootSerializer;\n\n  private final boolean noTypesInfo;\n\n  private final boolean isWrap;\n\n  public RequestRootSerializer(RootSerializer serializer, boolean isWrap, boolean noTypesInfo) {\n    this.rootSerializer = serializer;\n    this.noTypesInfo = noTypesInfo;\n    this.isWrap = isWrap;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public byte[] serialize(Object value) throws IOException {\n    if (noTypesInfo && !isWrap) {\n      Object param = ((Map<String, Object>) value).values().iterator().next();\n      if (param instanceof JsonObject) {\n        param = ((JsonObject) param).getMap();\n      }\n      return this.rootSerializer.serialize(param);\n    } else {\n      return this.rootSerializer.serialize(value);\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootDeserializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.io.IOException;\n\nimport org.apache.commons.lang3.ClassUtils;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic class ResponseRootDeserializer<T> {\n  private final RootDeserializer<T> rootDeserializer;\n\n  private final boolean empty;\n\n  public ResponseRootDeserializer(RootDeserializer<T> rootDeserializer, boolean empty) {\n    this.rootDeserializer = rootDeserializer;\n    this.empty = empty;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public T deserialize(byte[] bytes, JavaType invocationTimeType) throws IOException {\n    if (empty) {\n      rootDeserializer.deserialize(bytes); // read buffers if possible.\n      return null;\n    }\n\n    Object obj = rootDeserializer.deserialize(bytes);\n    if (obj instanceof PropertyWrapper) {\n      obj = ((PropertyWrapper) obj).getValue();\n    }\n    if (needConvert(obj, invocationTimeType)) {\n      obj = HighwayJsonUtils.convertValue(obj, invocationTimeType);\n    }\n    return (T) obj;\n  }\n\n  public static boolean needConvert(Object obj, JavaType invocationTimeType) {\n    if (obj == null || ClassUtils.isPrimitiveOrWrapper(obj.getClass()) || invocationTimeType.isPrimitive()\n        || ProtoConst.OBJECT_TYPE.equals(invocationTimeType)) {\n      return false;\n    }\n\n    if (obj.getClass() == invocationTimeType.getRawClass()) {\n      return false;\n    }\n\n    if (invocationTimeType.getRawClass().isAssignableFrom(obj.getClass())) {\n      if (invocationTimeType.getContentType() == null) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootSerializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\npublic class ResponseRootSerializer {\n  private final RootSerializer rootSerializer;\n\n  private final boolean noTypesInfo;\n\n  private final boolean isWrap;\n\n  public ResponseRootSerializer(RootSerializer serializer, boolean isWrap, boolean noTypesInfo) {\n    this.rootSerializer = serializer;\n    this.noTypesInfo = noTypesInfo;\n    this.isWrap = isWrap;\n  }\n\n  public byte[] serialize(Object value) throws IOException {\n    if (noTypesInfo && !isWrap) {\n      return this.rootSerializer.serialize(value);\n    } else {\n      Map<String, Object> responseValue = new HashMap<>(1);\n      // key is fixed to \"value\" in IDL\n      responseValue.put(\"value\", value);\n      return this.rootSerializer.serialize(responseValue);\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoMethod.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ProtoMethod {\n  private String argTypeName;\n\n  @JsonProperty\n  // key is status\n  private final Map<Integer, ProtoResponse> responses = new HashMap<>();\n\n  private ProtoResponse defaultResponse;\n\n  public String getArgTypeName() {\n    return argTypeName;\n  }\n\n  public void setArgTypeName(String argTypeName) {\n    this.argTypeName = argTypeName;\n  }\n\n  public void addResponse(String status, ProtoResponse response) {\n    if (status.equals(\"default\")) {\n      defaultResponse = response;\n      return;\n    }\n\n    int statusCode = Integer.parseInt(status);\n    responses.put(statusCode, response);\n\n    if (defaultResponse == null && statusCode == Status.OK.getStatusCode()) {\n      defaultResponse = response;\n    }\n  }\n\n  public ProtoResponse findResponse(int statusCode) {\n    ProtoResponse response = responses.get(statusCode);\n    if (response != null) {\n      return response;\n    }\n\n    if (statusCode == Status.OK.getStatusCode()) {\n      for (Entry<Integer, ProtoResponse> code : responses.entrySet()) {\n        if (HttpStatus.isSuccess(code.getKey())) {\n          return responses.get(code.getKey());\n        }\n      }\n    }\n\n    if (HttpStatus.isSuccess(statusCode)) {\n      return responses.get(Status.OK.getStatusCode());\n    }\n\n    return defaultResponse;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\npublic class ProtoResponse {\n  private String typeName;\n\n  public String getTypeName() {\n    return typeName;\n  }\n\n  public void setTypeName(String typeName) {\n    this.typeName = typeName;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoToStringGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport java.util.List;\n\nimport com.google.common.base.Strings;\n\nimport io.protostuff.compiler.model.Enum;\nimport io.protostuff.compiler.model.EnumConstant;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Import;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.Proto;\nimport io.protostuff.compiler.model.Service;\nimport io.protostuff.compiler.model.ServiceMethod;\n\npublic class ProtoToStringGenerator {\n  private final Proto proto;\n\n  public ProtoToStringGenerator(Proto proto) {\n    this.proto = proto;\n  }\n\n  public String protoToString() {\n    StringBuilder sb = new StringBuilder();\n    appendLine(sb, \"syntax = \\\"%s\\\";\", proto.getSyntax());\n    for (Import importValue : proto.getImports()) {\n      appendLine(sb, \"import \\\"%s\\\";\", importValue.getValue());\n    }\n    appendLine(sb, \"package %s;\\n\", proto.getPackage().getValue());\n\n    for (Message message : proto.getMessages()) {\n      messageToString(message, sb);\n    }\n\n    for (Enum enumValue : proto.getEnums()) {\n      enumToString(enumValue, sb);\n    }\n\n    for (Service service : proto.getServices()) {\n      serviceToString(service, sb);\n    }\n    return sb.toString();\n  }\n\n  private void serviceToString(Service service, StringBuilder sb) {\n    appendLine(sb, \"service %s {\", service.getName());\n    for (ServiceMethod serviceMethod : service.getMethods()) {\n      commentsToString(serviceMethod.getCommentLines(), sb, 2);\n      appendLine(sb, \"  rpc %s (%s) returns (%s);\\n\", serviceMethod.getName(), serviceMethod.getArgTypeName(),\n          serviceMethod.getReturnTypeName());\n    }\n    if (!service.getMethods().isEmpty()) {\n      sb.setLength(sb.length() - 1);\n    }\n    appendLine(sb, \"}\");\n  }\n\n  protected void enumToString(Enum enumValue, StringBuilder sb) {\n    appendLine(sb, \"enum %s {\", enumValue.getName());\n    for (EnumConstant enumConstant : enumValue.getConstants()) {\n      appendLine(sb, \"  %s = %s;\", enumConstant.getName(), enumConstant.getValue());\n    }\n    sb.append(\"}\\n\\n\");\n  }\n\n  private void commentsToString(List<String> comments, StringBuilder sb, int padLeft) {\n    if (comments.isEmpty()) {\n      return;\n    }\n\n    String pad = Strings.repeat(\" \", padLeft) + \"//\";\n    for (String comment : comments) {\n      sb.append(pad);\n      appendLine(sb, comment);\n    }\n  }\n\n  private void messageToString(Message message, StringBuilder sb) {\n    commentsToString(message.getCommentLines(), sb, 0);\n    appendLine(sb, \"message %s {\", message.getName());\n    for (Field field : message.getFields()) {\n      sb.append(\"  \");\n      fieldToString(field, field.isRepeated(), sb);\n    }\n    appendLine(sb, \"}\\n\");\n  }\n\n  private void fieldToString(Field field, boolean repeated, StringBuilder sb) {\n    if (field.isMap()) {\n      fieldMapToString(field, sb);\n      return;\n    }\n\n    if (repeated) {\n      fieldRepeatedToString(field, sb);\n      return;\n    }\n\n    appendLine(sb, \"%s %s = %d;\", field.getTypeName(), field.getName(), field.getTag());\n  }\n\n  private void fieldRepeatedToString(Field field, StringBuilder sb) {\n    sb.append(\"repeated \");\n    fieldToString(field, false, sb);\n  }\n\n  private void fieldMapToString(Field field, StringBuilder sb) {\n    Message entryMessage = (Message) field.getType();\n    Field keyField = entryMessage.getField(1);\n    Field valueField = entryMessage.getField(2);\n\n    // map<string, string> name = 1;\n    appendLine(sb, \"map<%s, %s> %s = %d;\", keyField.getTypeName(), valueField.getTypeName(), field.getName(),\n        field.getTag());\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SchemaSwaggerTypeAdapter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport java.util.List;\n\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic class SchemaSwaggerTypeAdapter implements SwaggerTypeAdapter {\n  private final Schema<?> schema;\n\n  public SchemaSwaggerTypeAdapter(Schema<?> schema) {\n    this.schema = schema;\n  }\n\n  @Override\n  public String getRefType() {\n    return schema.get$ref();\n  }\n\n  @Override\n  public Schema<?> getArrayItem() {\n    return schema.getItems();\n  }\n\n  @Override\n  public Schema<?> getMapItem() {\n    return (Schema<?>) schema.getAdditionalProperties();\n  }\n\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public List<String> getEnum() {\n    return (List<String>) schema.getEnum();\n  }\n\n  @Override\n  public String getType() {\n    return schema.getType();\n  }\n\n  @Override\n  public String getFormat() {\n    return schema.getFormat();\n  }\n\n  @Override\n  public boolean isJavaLangObject() {\n    return \"object\".equals(getType());\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.hash.Hashing;\n\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.Proto;\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.PathItem;\nimport io.swagger.v3.oas.models.Paths;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.vertx.core.json.Json;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class SwaggerToProtoGenerator {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerToProtoGenerator.class);\n\n  private final String protoPackage;\n\n  private final OpenAPI swagger;\n\n  private final StringBuilder msgStringBuilder = new StringBuilder();\n\n  private final StringBuilder serviceBuilder = new StringBuilder();\n\n  private final Set<String> imports = new HashSet<>();\n\n  private final Set<String> messages = new HashSet<>();\n\n  private List<Runnable> pending = new ArrayList<>();\n\n  // not java package\n  // better to be: app_${app}.mid_{microservice}.sid_{schemaId}\n  public SwaggerToProtoGenerator(String protoPackage, OpenAPI swagger) {\n    this.protoPackage = escapePackageName(protoPackage);\n    this.swagger = swagger;\n  }\n\n  public Proto convert() {\n    convertDefinitions();\n    convertOperations();\n    do {\n      List<Runnable> oldPending = pending;\n      pending = new ArrayList<>();\n      for (Runnable runnable : oldPending) {\n        runnable.run();\n      }\n    } while (!pending.isEmpty());\n\n    return createProto();\n  }\n\n  public static String escapePackageName(String name) {\n    return name.replaceAll(\"[\\\\-:]\", \"_\");\n  }\n\n  public static String escapeMessageName(String name) {\n    return name.replaceAll(\"\\\\.\", \"_\");\n  }\n\n  public static boolean isValidEnum(String name) {\n    return !name.contains(\".\") && !name.contains(\"-\");\n  }\n\n  private void convertDefinitions() {\n    if (swagger.getComponents() == null || swagger.getComponents().getSchemas() == null) {\n      return;\n    }\n\n    for (Entry<String, Schema> entry : swagger.getComponents().getSchemas().entrySet()) {\n      convertDefinition(entry.getKey(), entry.getValue());\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void convertDefinition(String modelName, Schema model) {\n    Map<String, Schema> properties = model.getProperties();\n    if (properties == null) {\n      // it's a empty message\n      properties = Collections.emptyMap();\n    }\n\n    createMessage(modelName, properties);\n  }\n\n  private void createMessage(String protoName, Map<String, Schema> properties, String... annotations) {\n    if (!messages.add(protoName)) {\n      // already created\n      return;\n    }\n\n    for (String annotation : annotations) {\n      msgStringBuilder.append(\"//\");\n      appendLine(msgStringBuilder, annotation);\n    }\n    appendLine(msgStringBuilder, \"message %s {\", protoName);\n    int tag = 1;\n    for (Entry<String, Schema> entry : properties.entrySet()) {\n      Schema property = entry.getValue();\n      String propertyType = convertSwaggerType(property);\n\n      appendLine(msgStringBuilder, \"  %s %s = %d;\", propertyType, entry.getKey(), tag);\n      tag++;\n    }\n    appendLine(msgStringBuilder, \"}\");\n  }\n\n  private void addImports(Proto proto) {\n    imports.add(proto.getFilename());\n    for (Message message : proto.getMessages()) {\n      messages.add(message.getCanonicalName());\n    }\n  }\n\n  private String convertSwaggerType(Object swaggerType) {\n    if (swaggerType == null) {\n      // void\n      addImports(ProtoConst.EMPTY_PROTO);\n      return ProtoConst.EMPTY.getCanonicalName();\n    }\n\n    SwaggerTypeAdapter adapter = SwaggerTypeAdapter.create(swaggerType);\n    String type = tryFindEnumType(adapter.getEnum());\n    if (type != null) {\n      return type;\n    }\n\n    type = findBaseType(adapter.getType(), adapter.getFormat());\n    if (type != null) {\n      return type;\n    }\n\n    type = adapter.getRefType();\n    if (type != null) {\n      return type.substring(Components.COMPONENTS_SCHEMAS_REF.length());\n    }\n\n    Schema itemProperty = adapter.getArrayItem();\n    if (itemProperty != null) {\n      return \"repeated \" + convertArrayOrMapItem(itemProperty);\n    }\n\n    itemProperty = adapter.getMapItem();\n    if (itemProperty != null) {\n      return String.format(\"map<string, %s>\", convertArrayOrMapItem(itemProperty));\n    }\n\n    if (adapter.isJavaLangObject()) {\n      addImports(ProtoConst.ANY_PROTO);\n      return ProtoConst.ANY.getCanonicalName();\n    }\n\n    throw new IllegalStateException(String\n        .format(\"not support swagger type, class=%s, content=%s.\", swaggerType.getClass().getName(),\n            Json.encode(swaggerType)));\n  }\n\n  private String convertArrayOrMapItem(Schema itemProperty) {\n    SwaggerTypeAdapter itemAdapter = SwaggerTypeAdapter.create(itemProperty);\n    // List<List<>>, need to wrap\n    if (itemAdapter.getArrayItem() != null) {\n      String protoName = generateWrapPropertyName(List.class.getSimpleName(), itemAdapter.getArrayItem());\n      pending.add(() -> wrapPropertyToMessage(protoName, itemProperty));\n      return protoName;\n    }\n\n    // List<Map<>>, need to wrap\n    if (itemAdapter.getMapItem() != null) {\n      String protoName = generateWrapPropertyName(Map.class.getSimpleName(), itemAdapter.getMapItem());\n      pending.add(() -> wrapPropertyToMessage(protoName, itemProperty));\n      return protoName;\n    }\n\n    return convertSwaggerType(itemProperty);\n  }\n\n  private String generateWrapPropertyName(String prefix, Schema property) {\n    SwaggerTypeAdapter adapter = SwaggerTypeAdapter.create(property);\n    // List<List<>>, need to wrap\n    if (adapter.getArrayItem() != null) {\n      return generateWrapPropertyName(prefix + List.class.getSimpleName(), adapter.getArrayItem());\n    }\n\n    // List<Map<>>, need to wrap\n    if (adapter.getMapItem() != null) {\n      return generateWrapPropertyName(prefix + Map.class.getSimpleName(), adapter.getMapItem());\n    }\n\n    // message name cannot have . (package separator)\n    return prefix + StringUtils.capitalize(escapeMessageName(convertSwaggerType(adapter)));\n  }\n\n  private void wrapPropertyToMessage(String protoName, Schema property) {\n    createMessage(protoName, Collections.singletonMap(\"value\", property), ProtoConst.ANNOTATION_WRAP_PROPERTY);\n  }\n\n  private String tryFindEnumType(List<String> enums) {\n    if (enums != null && !enums.isEmpty()) {\n      String strEnums = enums.toString();\n      String enumName = \"Enum_\" + Hashing.sha256().hashString(strEnums, StandardCharsets.UTF_8);\n      pending.add(() -> createEnum(enumName, enums));\n      return enumName;\n    }\n    return null;\n  }\n\n  private void createEnum(String enumName, List<String> enums) {\n    if (!messages.add(enumName)) {\n      // already created\n      return;\n    }\n\n    appendLine(msgStringBuilder, \"enum %s {\", enumName);\n    for (int idx = 0; idx < enums.size(); idx++) {\n      if (isValidEnum(enums.get(idx))) {\n        appendLine(msgStringBuilder, \"  %s =%d;\", enums.get(idx), idx);\n      } else {\n        throw new IllegalStateException(\n            String.format(\"enum class [%s] name [%s] not supported by protobuffer.\", enumName, enums.get(idx)));\n      }\n    }\n    appendLine(msgStringBuilder, \"}\");\n  }\n\n  private String findBaseType(String swaggerType, String swaggerFmt) {\n    String key = swaggerType + \":\" + swaggerFmt;\n    return switch (key) {\n      case \"boolean:null\" -> \"bool\";\n      case \"integer:int32\" -> \"sint32\";\n      case \"integer:int64\" -> \"sint64\";\n      case \"integer:null\" -> \"string\";  // BigInteger like values\n      case \"number:double\" -> \"double\";\n      case \"number:float\" -> \"float\";\n      case \"number:null\" -> \"string\";  // BigDecimal like values\n      case \"string:null\" -> \"string\";\n      case \"string:byte\" -> \"bytes\";\n      case \"string:date\" -> \"int64\";\n      case \"string:date-time\" -> \"int64\";\n      case \"string:binary\" -> throw new IllegalArgumentException(\"proto buffer not support file upload/download\");\n      default -> null;\n    };\n  }\n\n  private void convertOperations() {\n    Paths paths = swagger.getPaths();\n    if (paths == null || paths.isEmpty()) {\n      return;\n    }\n\n    appendLine(serviceBuilder, \"service MainService {\");\n    for (PathItem path : paths.values()) {\n      for (Operation operation : path.readOperations()) {\n        if (isUpload(operation)) {\n          LOGGER.warn(\"Not support operation for highway {}.{}, {}\", this.protoPackage, operation.getOperationId(),\n              \"file upload not supported\");\n          continue;\n        } else if (isDownload(operation)) {\n          LOGGER.warn(\"Not support operation for highway {}.{}, {}\", this.protoPackage, operation.getOperationId(),\n              \"file download not supported\");\n          continue;\n        }\n        try {\n          convertOperation(operation);\n        } catch (Exception e) {\n          LOGGER.error(\"Not support operation for highway {}.{}\", this.protoPackage, operation.getOperationId(), e);\n        }\n      }\n    }\n\n    serviceBuilder.setLength(serviceBuilder.length() - 1);\n\n    appendLine(serviceBuilder, \"}\");\n  }\n\n  private boolean isUpload(Operation operation) {\n    return operation.getRequestBody() != null && operation.getRequestBody().getContent() != null\n        && operation.getRequestBody().getContent().get(MediaType.MULTIPART_FORM_DATA) != null;\n  }\n\n  private boolean isDownload(Operation operation) {\n    return operation.getResponses().get(SwaggerConst.SUCCESS_KEY) != null &&\n        operation.getResponses().get(SwaggerConst.SUCCESS_KEY).getContent() != null &&\n        operation.getResponses().get(SwaggerConst.SUCCESS_KEY).getContent().get(MediaType.MULTIPART_FORM_DATA)\n            != null;\n  }\n\n  private void convertOperation(Operation operation) {\n    ProtoMethod protoMethod = new ProtoMethod();\n    fillRequestType(operation, protoMethod);\n    fillResponseType(operation, protoMethod);\n\n    appendLine(serviceBuilder, \"  //%s%s\", ProtoConst.ANNOTATION_RPC, Json.encode(protoMethod));\n    appendLine(serviceBuilder, \"  rpc %s (%s) returns (%s);\\n\", operation.getOperationId(),\n        protoMethod.getArgTypeName(),\n        protoMethod.findResponse(Status.OK.getStatusCode()).getTypeName());\n  }\n\n  private void fillRequestType(Operation operation, ProtoMethod protoMethod) {\n    int parametersCount = parametersCount(operation);\n    if (parametersCount == 0) {\n      addImports(ProtoConst.EMPTY_PROTO);\n      protoMethod.setArgTypeName(ProtoConst.EMPTY.getCanonicalName());\n      return;\n    }\n\n    if (parametersCount == 1) {\n      String type = convertSwaggerType(oneSchema(operation));\n      if (messages.contains(type)) {\n        protoMethod.setArgTypeName(type);\n        return;\n      }\n    }\n\n    String wrapName = StringUtils.capitalize(operation.getOperationId()) + \"RequestWrap\";\n    createWrapArgs(wrapName, wrapSchema(operation));\n\n    protoMethod.setArgTypeName(wrapName);\n  }\n\n  private Map<String, Schema> wrapSchema(Operation operation) {\n    Map<String, Schema> properties = new LinkedHashMap<>();\n    if (operation.getParameters() != null) {\n      for (Parameter parameter : operation.getParameters()) {\n        properties.put(parameter.getName(), parameter.getSchema());\n      }\n    }\n    if (operation.getRequestBody() != null\n        && operation.getRequestBody().getContent().size() != 0) {\n      if (operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null) {\n        operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties()\n            .forEach((k, v) -> properties.put((String) k, (Schema) v));\n      } else {\n        properties.put((String) operation.getRequestBody().getExtensions().get(SwaggerConst.EXT_BODY_NAME),\n            operation.getRequestBody().getContent().get(\n                operation.getRequestBody().getContent().keySet().iterator().next()).getSchema());\n      }\n    }\n    return properties;\n  }\n\n  private Schema oneSchema(Operation operation) {\n    if (operation.getParameters() != null && operation.getParameters().size() == 1) {\n      return operation.getParameters().get(0).getSchema();\n    }\n    if (operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null) {\n      return (Schema) operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema()\n          .getProperties()\n          .values().iterator().next();\n    }\n    return operation.getRequestBody().getContent().get(\n        operation.getRequestBody().getContent().keySet().iterator().next()).getSchema();\n  }\n\n  private int parametersCount(Operation operation) {\n    int parameters = operation.getParameters() == null ? 0 : operation.getParameters().size();\n    if (operation.getRequestBody() != null) {\n      if (operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null) {\n        parameters = parameters + operation.getRequestBody()\n            .getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties().size();\n      } else if (operation.getRequestBody().getContent().size() != 0) {\n        parameters = parameters + 1;\n      }\n    }\n    return parameters;\n  }\n\n  private void fillResponseType(Operation operation, ProtoMethod protoMethod) {\n    for (Entry<String, ApiResponse> entry : operation.getResponses().entrySet()) {\n      Schema schema = null;\n      if (entry.getValue().getContent() != null &&\n          entry.getValue().getContent().size() != 0) {\n        schema = entry.getValue().getContent().get(\n            entry.getValue().getContent().keySet().iterator().next()).getSchema();\n      }\n      String type = convertSwaggerType(schema);\n      boolean wrapped = !messages.contains(type);\n\n      ProtoResponse protoResponse = new ProtoResponse();\n      protoResponse.setTypeName(type);\n\n      if (wrapped) {\n        String wrapName = StringUtils.capitalize(operation.getOperationId()) + \"ResponseWrap\" + entry.getKey();\n        wrapPropertyToMessage(wrapName, schema);\n\n        protoResponse.setTypeName(wrapName);\n      }\n      protoMethod.addResponse(entry.getKey(), protoResponse);\n    }\n  }\n\n  private void createWrapArgs(String wrapName, Map<String, Schema> properties) {\n    createMessage(wrapName, properties, ProtoConst.ANNOTATION_WRAP_ARGUMENTS);\n  }\n\n  protected Proto createProto() {\n    StringBuilder sb = new StringBuilder();\n    appendLine(sb, \"syntax = \\\"proto3\\\";\");\n    for (String importMsg : imports) {\n      appendLine(sb, \"import \\\"%s\\\";\", importMsg);\n    }\n    if (StringUtils.isNotEmpty(protoPackage)) {\n      sb.append(\"package \").append(protoPackage).append(\";\\n\");\n    }\n    sb.append(msgStringBuilder);\n    sb.append(serviceBuilder);\n\n    ProtoParser protoParser = new ProtoParser();\n    return protoParser.parseFromContent(sb.toString());\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerTypeAdapter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport java.util.List;\n\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic interface SwaggerTypeAdapter {\n  static SwaggerTypeAdapter create(Object swaggerType) {\n    if (swaggerType instanceof SwaggerTypeAdapter) {\n      return (SwaggerTypeAdapter) swaggerType;\n    }\n\n    if (swaggerType instanceof Schema<?>) {\n      return new SchemaSwaggerTypeAdapter((Schema<?>) swaggerType);\n    }\n\n    throw new IllegalStateException(\"not support swagger type: \" + swaggerType.getClass().getName());\n  }\n\n  String getRefType();\n\n  Schema<?> getArrayItem();\n\n  Schema<?> getMapItem();\n\n  List<String> getEnum();\n\n  String getType();\n\n  String getFormat();\n\n  boolean isJavaLangObject();\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/schema/SchemaToProtoGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema;\n\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\n\nimport com.google.common.hash.Hashing;\n\nimport io.protostuff.compiler.model.Proto;\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class SchemaToProtoGenerator {\n  record IdentifierRunnable(Schema<?> identifier, Runnable target)\n      implements Runnable {\n\n    @Override\n    public void run() {\n      this.target.run();\n    }\n\n    @Override\n    public boolean equals(Object o) {\n      if (this == o) {\n        return true;\n      }\n      if (o == null || getClass() != o.getClass()) {\n        return false;\n      }\n      IdentifierRunnable that = (IdentifierRunnable) o;\n      return SwaggerUtils.schemaEquals(identifier, that.identifier);\n    }\n\n    @Override\n    public int hashCode() {\n      return SwaggerUtils.schemaHashCode(identifier);\n    }\n  }\n\n  private final String protoPackage;\n\n  private final OpenAPI openAPI;\n\n  private final Schema<?> rootSchema;\n\n  private final String rootName;\n\n  private final Set<String> messages = new HashSet<>();\n\n  private final StringBuilder msgStringBuilder = new StringBuilder();\n\n  private List<Runnable> pending = new ArrayList<>();\n\n  public SchemaToProtoGenerator(String protoPackage, OpenAPI openAPI, Schema<?> rootSchema, String rootName) {\n    this.protoPackage = protoPackage;\n    this.openAPI = openAPI;\n    this.rootSchema = rootSchema;\n    this.rootName = rootName;\n  }\n\n  public Proto convert() {\n    createMessage(this.rootSchema);\n\n    int iteration = 0;\n    do {\n      List<Runnable> oldPending = pending;\n      pending = new ArrayList<>();\n      for (Runnable runnable : oldPending) {\n        runnable.run();\n      }\n      if (pending.size() >= oldPending.size()) {\n        iteration++;\n      }\n    } while (!pending.isEmpty() && iteration < 1000);\n\n    if (iteration == 1000) {\n      throw new IllegalArgumentException(\n          String.format(\"Failed to create schema %s. May be cyclic object.\", this.rootName));\n    }\n\n    Map<String, Schema> wrap = new HashMap<>(1);\n    wrap.put(\"value\", this.rootSchema);\n    createMessage(rootName, wrap, ProtoConst.ANNOTATION_WRAP_PROPERTY);\n\n    return createProto();\n  }\n\n  protected Proto createProto() {\n    StringBuilder sb = new StringBuilder();\n    appendLine(sb, \"syntax = \\\"proto3\\\";\");\n    if (StringUtils.isNotEmpty(protoPackage)) {\n      sb.append(\"package \").append(protoPackage).append(\";\\n\");\n    }\n    sb.append(msgStringBuilder);\n    ProtoParser protoParser = new ProtoParser();\n    return protoParser.parseFromContent(sb.toString());\n  }\n\n  private String findSchemaType(Schema<?> schema) {\n    @SuppressWarnings(\"unchecked\")\n    String type = tryFindEnumType((List<String>) schema.getEnum());\n    if (type != null) {\n      return type;\n    }\n\n    type = findBaseType(schema.getType(), schema.getFormat());\n    if (type != null) {\n      return type;\n    }\n\n    Schema<?> itemProperty = schema.getItems();\n    if (itemProperty != null) {\n      String containerType = findArrayOrMapItemType(itemProperty);\n      if (containerType != null) {\n        return \"repeated \" + containerType;\n      }\n      return null;\n    }\n\n    itemProperty = (Schema<?>) schema.getAdditionalProperties();\n    if (itemProperty != null) {\n      String containerType = findArrayOrMapItemType(itemProperty);\n      if (containerType != null) {\n        return String.format(\"map<string, %s>\", containerType);\n      }\n      return null;\n    }\n\n    type = schema.get$ref();\n    if (type != null) {\n      String typeName = type.substring(Components.COMPONENTS_SCHEMAS_REF.length());\n      Schema<?> refSchema = openAPI.getComponents().getSchemas().get(typeName);\n      if (refSchema == null) {\n        throw new IllegalArgumentException(\"not found ref in components \" + type);\n      }\n      if (StringUtils.isEmpty(refSchema.getName())) {\n        refSchema.setName(typeName);\n      }\n      return findSchemaType(refSchema);\n    }\n\n    return findObjectType(schema);\n  }\n\n  private String findObjectType(Schema<?> schema) {\n    String name = schema.getName();\n    if (messages.contains(name)) {\n      return name;\n    }\n    return null;\n  }\n\n  private void createEnum(String enumName, List<String> enums) {\n    if (!messages.add(enumName)) {\n      // already created\n      return;\n    }\n\n    appendLine(msgStringBuilder, \"enum %s {\", enumName);\n    for (int idx = 0; idx < enums.size(); idx++) {\n      if (isValidEnum(enums.get(idx))) {\n        appendLine(msgStringBuilder, \"  %s =%d;\", enums.get(idx), idx);\n      } else {\n        throw new IllegalStateException(\n            String.format(\"enum class [%s] name [%s] not supported by protobuffer.\", enumName, enums.get(idx)));\n      }\n    }\n    appendLine(msgStringBuilder, \"}\");\n  }\n\n  public static boolean isValidEnum(String name) {\n    return !name.contains(\".\") && !name.contains(\"-\");\n  }\n\n  private String tryFindEnumType(List<String> enums) {\n    if (enums != null && !enums.isEmpty()) {\n      String strEnums = enums.toString();\n      String enumName = \"Enum_\" + Hashing.sha256().hashString(strEnums, StandardCharsets.UTF_8);\n      pending.add(() -> createEnum(enumName, enums));\n      return enumName;\n    }\n    return null;\n  }\n\n  private String findBaseType(String swaggerType, String swaggerFmt) {\n    String key = swaggerType + \":\" + swaggerFmt;\n    return switch (key) {\n      case \"boolean:null\" -> \"bool\";\n      case \"integer:int32\" -> \"sint32\";\n      case \"integer:int64\" -> \"sint64\";\n      case \"integer:null\" -> \"string\";  // BigInteger like values\n      case \"number:double\" -> \"double\";\n      case \"number:float\" -> \"float\";\n      case \"number:null\" -> \"string\";  // BigDecimal like values\n      case \"string:null\" -> \"string\";\n      case \"string:byte\" -> \"bytes\";\n      case \"string:date\" -> \"int64\";\n      case \"string:date-time\" -> \"int64\";\n      case \"string:binary\" -> throw new IllegalArgumentException(\"proto buffer not support file upload/download\");\n      default -> null;\n    };\n  }\n\n  private String findArrayOrMapItemType(Schema<?> itemProperty) {\n    // List<List<>>, need to wrap\n    if (itemProperty.getItems() != null) {\n      return findWrapPropertyType(List.class.getSimpleName(), itemProperty.getItems());\n    }\n\n    // List<Map<>>, need to wrap\n    if (itemProperty.getAdditionalProperties() != null) {\n      return findWrapPropertyType(Map.class.getSimpleName(), (Schema<?>) itemProperty.getAdditionalProperties());\n    }\n\n    return findSchemaType(itemProperty);\n  }\n\n\n  private String findWrapPropertyType(String prefix, Schema<?> property) {\n    // List<List<>>, need to wrap\n    if (property.getItems() != null) {\n      return findWrapPropertyType(prefix + List.class.getSimpleName(), property.getItems());\n    }\n\n    // List<Map<>>, need to wrap\n    if (property.getAdditionalProperties() != null) {\n      return findWrapPropertyType(prefix + Map.class.getSimpleName(),\n          (Schema<?>) property.getAdditionalProperties());\n    }\n\n    String type = findSchemaType(property);\n    if (type == null) {\n      return null;\n    }\n\n    // message name cannot have . (package separator)\n    return prefix + StringUtils.capitalize(escapeMessageName(type));\n  }\n\n  public static String escapeMessageName(String name) {\n    return name.replaceAll(\"\\\\.\", \"_\");\n  }\n\n\n  private void wrapPropertyToMessage(String protoName, Schema<?> property) {\n    createMessage(protoName, Collections.singletonMap(\"value\", property), ProtoConst.ANNOTATION_WRAP_PROPERTY);\n  }\n\n  private void createMessage(String protoName, Map<String, Schema> properties, String... annotations) {\n    for (String annotation : annotations) {\n      msgStringBuilder.append(\"//\");\n      appendLine(msgStringBuilder, annotation);\n    }\n    appendLine(msgStringBuilder, \"message %s {\", protoName);\n    int tag = 1;\n    for (Entry<String, Schema> entry : properties.entrySet()) {\n      Schema property = entry.getValue();\n      String propertyType = findSchemaType(property);\n\n      appendLine(msgStringBuilder, \"  %s %s = %d;\", propertyType, entry.getKey(), tag);\n      tag++;\n    }\n    appendLine(msgStringBuilder, \"}\");\n  }\n\n  public void createMessage(Schema<?> schema) {\n    String ref = schema.get$ref();\n    if (ref != null) {\n      String typeName = ref.substring(Components.COMPONENTS_SCHEMAS_REF.length());\n      Schema<?> refSchema = openAPI.getComponents().getSchemas().get(typeName);\n      if (refSchema == null) {\n        throw new IllegalArgumentException(\"not found ref in components \" + ref);\n      }\n      if (StringUtils.isEmpty(refSchema.getName())) {\n        refSchema.setName(typeName);\n      }\n      createMessage(refSchema);\n      return;\n    }\n\n    boolean wait = false;\n\n    //array or map\n    if (isArrayOrMap(schema)) {\n      Schema<?> mapOrArrayItem = arrayOrMapItem(schema);\n      if (findSchemaType(mapOrArrayItem) == null) {\n        createMessageTask(mapOrArrayItem);\n        wait = true;\n      } else {\n        if (createMapOrArrayMessageTask(mapOrArrayItem, true, schema)) {\n          wait = true;\n        }\n      }\n    }\n\n    //object\n    if (schema.getProperties() != null) {\n      for (Entry<String, Schema> entry : schema.getProperties().entrySet()) {\n        if (findSchemaType(entry.getValue()) == null) {\n          createMessageTask(entry.getValue());\n          wait = true;\n        } else if (isArrayOrMap(entry.getValue())) {\n          if (createMapOrArrayMessageTask(arrayOrMapItem(entry.getValue()), false, null)) {\n            wait = true;\n          }\n        }\n      }\n    }\n\n    if (wait) {\n      IdentifierRunnable runnable = new IdentifierRunnable(schema, () -> createMessage(schema));\n      if (!pending.contains(runnable)) {\n        pending.add(runnable);\n      }\n      return;\n    }\n\n    if (findSchemaType(schema) != null) {\n      return;\n    }\n\n    messages.add(schema.getName());\n\n    appendLine(msgStringBuilder, \"message %s {\", schema.getName());\n    List<Map.Entry<String, Schema>> sortedProperties = new ArrayList<>(schema.getProperties().entrySet());\n    sortedProperties.sort(Comparator.comparing(Map.Entry::getKey));\n    int tag = 1;\n    for (Entry<String, Schema> entry : sortedProperties) {\n      Schema property = entry.getValue();\n      String propertyType = findSchemaType(property);\n\n      appendLine(msgStringBuilder, \"  %s %s = %d;\", propertyType, entry.getKey(), tag);\n      tag++;\n    }\n    appendLine(msgStringBuilder, \"}\");\n  }\n\n  private boolean isArrayOrMap(Schema<?> value) {\n    return value.getItems() != null || value.getAdditionalProperties() != null;\n  }\n\n  private Schema<?> arrayOrMapItem(Schema<?> schema) {\n    return schema.getItems() == null ?\n        (Schema<?>) schema.getAdditionalProperties() : schema.getItems();\n  }\n\n  private void createMessageTask(Schema<?> schema) {\n    IdentifierRunnable runnable = new IdentifierRunnable(schema, () -> createMessage(schema));\n    if (!pending.contains(runnable)) {\n      pending.add(runnable);\n    }\n  }\n\n  private boolean createMapOrArrayMessageTask(Schema<?> schema, boolean nested, Schema<?> owner) {\n    if (schema.getAdditionalProperties() != null) {\n      String protoName = findWrapPropertyType(Map.class.getSimpleName(),\n          (Schema<?>) schema.getAdditionalProperties());\n      if (messages.add(protoName)) {\n        pending.add(() -> wrapPropertyToMessage(protoName, schema));\n        createMessageTask((Schema<?>) schema.getAdditionalProperties());\n        return true;\n      }\n    }\n    if (schema.getItems() != null) {\n      String protoName = findWrapPropertyType(List.class.getSimpleName(), schema.getItems());\n      if (messages.add(protoName)) {\n        pending.add(() -> wrapPropertyToMessage(protoName, schema));\n        createMessageTask(schema.getItems());\n        return true;\n      }\n    }\n    if (nested) {\n      String protoName = owner.getAdditionalProperties() != null ?\n          findWrapPropertyType(Map.class.getSimpleName(), schema) :\n          findWrapPropertyType(List.class.getSimpleName(), schema);\n      if (messages.add(protoName)) {\n        pending.add(() -> wrapPropertyToMessage(protoName, owner));\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.codec.protobuf.utils;\n\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.codec.protobuf.internal.converter.SwaggerToProtoGenerator;\nimport org.apache.servicecomb.codec.protobuf.schema.SchemaToProtoGenerator;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\n\nimport io.protostuff.compiler.model.Proto;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\n/**\n * Manage swagger -> protoBuffer mappings.\n *\n * This class have the same lifecycle as MicroserviceMeta, so we need to create an instance\n * for each MicroserviceMeta.\n */\npublic class ScopedProtobufSchemaManager {\n  static class SchemaKey {\n    String schemaId;\n\n    String rootMessage;\n\n    Schema<?> schema;\n\n    int hashCode = -1;\n\n    SchemaKey(String schemaId, String rootMessage, Schema<?> schema) {\n      this.schemaId = schemaId;\n      this.rootMessage = rootMessage;\n      this.schema = schema;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n      if (this == o) {\n        return true;\n      }\n      if (o == null || getClass() != o.getClass()) {\n        return false;\n      }\n      SchemaKey other = (SchemaKey) o;\n      return StringUtils.equals(schemaId, other.schemaId) && StringUtils.equals(rootMessage, other.rootMessage)\n          && SwaggerUtils.schemaEquals(schema, other.schema);\n    }\n\n    @Override\n    public int hashCode() {\n      if (hashCode != -1) {\n        return hashCode;\n      }\n      hashCode = schemaId.hashCode() ^ rootMessage.hashCode() ^ SwaggerUtils.schemaHashCode(schema);\n      return hashCode;\n    }\n  }\n\n  // Because this class belongs to each SchemaMeta, the key is the schema id.\n  private final Map<String, ProtoMapper> mapperCache = new ConcurrentHashMapEx<>();\n\n  private final Map<SchemaKey, ProtoMapper> schemaMapperCache = new ConcurrentHashMapEx<>();\n\n  public ScopedProtobufSchemaManager() {\n\n  }\n\n  /**\n   * get the ProtoMapper from Swagger\n   */\n  public ProtoMapper getOrCreateProtoMapper(SchemaMeta schemaMeta) {\n    return mapperCache.computeIfAbsent(schemaMeta.getSchemaId(), key -> {\n      OpenAPI swagger = schemaMeta.getSwagger();\n      SwaggerToProtoGenerator generator = new SwaggerToProtoGenerator(schemaMeta.getMicroserviceQualifiedName(),\n          swagger);\n      Proto proto = generator.convert();\n      ProtoMapperFactory protoMapperFactory = new ProtoMapperFactory();\n      return protoMapperFactory.create(proto);\n    });\n  }\n\n  /**\n   * get the ProtoMapper from Schema\n   */\n  public ProtoMapper getOrCreateProtoMapper(OpenAPI openAPI, String schemaId, String rootMessageName,\n      Schema<?> schema) {\n    SchemaKey schemaKey = new SchemaKey(schemaId, rootMessageName, schema);\n    return schemaMapperCache.computeIfAbsent(schemaKey, key -> {\n      SchemaToProtoGenerator generator = new SchemaToProtoGenerator(\"scb.schema\", openAPI,\n          key.schema, rootMessageName);\n      Proto proto = generator.convert();\n      ProtoMapperFactory protoMapperFactory = new ProtoMapperFactory();\n      return protoMapperFactory.create(proto);\n    });\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/io/protostuff/runtime/model/ModelProtostuff.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage io.protostuff.runtime.model;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport io.protostuff.Tag;\n\npublic class ModelProtostuff {\n\n  @Tag(1)\n  private String destMicroservice;\n\n  @Tag(5)\n  private String schemaId;\n\n  @Tag(6)\n  private String operationName;\n\n  @Tag(7)\n  private Map<String, String> context;\n\n  @Tag(8)\n  private Map<String, User> userMap;\n\n  @Tag(9)\n  private List<String> list = new ArrayList<>();\n\n  @Tag(10)\n  private List<User> userList = new ArrayList<>();\n\n  //CHECKSTYLE:ON\n\n  public String getDestMicroservice() {\n    return destMicroservice;\n  }\n\n  public void setDestMicroservice(String destMicroservice) {\n    this.destMicroservice = destMicroservice;\n  }\n\n  public String getSchemaId() {\n    return schemaId;\n  }\n\n  public void setSchemaId(String schemaId) {\n    this.schemaId = schemaId;\n  }\n\n  public String getOperationName() {\n    return operationName;\n  }\n\n  public void setOperationName(String operationName) {\n    this.operationName = operationName;\n  }\n\n  public Map<String, String> getContext() {\n    return context;\n  }\n\n  public void setContext(Map<String, String> context) {\n    this.context = context;\n  }\n\n  public List<String> getList() {\n    return list;\n  }\n\n  public void setList(List<String> list) {\n    this.list = list;\n  }\n\n  public Map<String, User> getUserMap() {\n    return userMap;\n  }\n\n  public void setUserMap(Map<String, User> userMap) {\n    this.userMap = userMap;\n  }\n\n  public List<User> getUserList() {\n    return userList;\n  }\n\n  public void setUserList(List<User> userList) {\n    this.userList = userList;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/io/protostuff/runtime/model/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage io.protostuff.runtime.model;\n\npublic class User {\n  private String name;\n\n  public User(String name) {\n    this.name = name;\n  }\n\n  public User() {\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/definition/TestResponseRootDeserializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.definition;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.fasterxml.jackson.databind.type.SimpleType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport org.junit.jupiter.api.Test;\n\nclass Model {\n\n}\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class TestResponseRootDeserializer {\n  @Test\n  public void testNeedConvert() {\n    Assertions.assertEquals(SimpleType.constructUnsafe(Object.class), ProtoConst.OBJECT_TYPE);\n    Assertions.assertFalse(ResponseRootDeserializer.needConvert(1, TypeFactory.defaultInstance().constructType(int.class)));\n    Assertions.assertFalse(ResponseRootDeserializer.needConvert(1, TypeFactory.defaultInstance().constructType(Integer.class)));\n    Assertions.assertFalse(ResponseRootDeserializer\n            .needConvert(1, TypeFactory.defaultInstance().constructType(int.class)));\n    Assertions.assertFalse(ResponseRootDeserializer\n            .needConvert(1, TypeFactory.defaultInstance().constructType(Integer.class)));\n    Assertions.assertTrue(ResponseRootDeserializer\n            .needConvert(new HashMap<>(), TypeFactory.defaultInstance().constructType(Model.class)));\n    Assertions.assertFalse(ResponseRootDeserializer\n            .needConvert(new Model(), TypeFactory.defaultInstance().constructType(Model.class)));\n    Assertions.assertFalse(ResponseRootDeserializer\n            .needConvert(new Model(), TypeFactory.defaultInstance().constructType(Object.class)));\n    List<Model> modelList = new ArrayList<>();\n    List<Map> modelMapList = new ArrayList<>();\n    Assertions.assertTrue(ResponseRootDeserializer\n            .needConvert(modelMapList, TypeFactory.defaultInstance().constructType(new TypeReference<List<Model>>() {\n            })));\n    // This case should be false, however it is not exists in real applications, for simpler, take it true.\n    Assertions.assertTrue(ResponseRootDeserializer\n            .needConvert(modelList, TypeFactory.defaultInstance().constructType(new TypeReference<List<Model>>() {\n            })));\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestProtoToStringGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.protostuff.compiler.model.Proto;\nimport org.junit.jupiter.api.Test;\n\npublic class TestProtoToStringGenerator {\n  static final String content = \"syntax = \\\"proto3\\\";\\n\"\n      + \"import \\\"google/protobuf/any.proto\\\";\\n\"\n      + \"package org.apache.servicecomb.foundation.protobuf.internal.model;\\n\"\n      + \"\\n\"\n      + \"message Root {\\n\"\n      + \"  int32 int32 = 1;\\n\"\n      + \"  int64 int64 = 2;\\n\"\n      + \"  uint32 uint32 = 3;\\n\"\n      + \"  uint64 uint64 = 4;\\n\"\n      + \"  sint32 sint32 = 5;\\n\"\n      + \"  sint64 sint64 = 6;\\n\"\n      + \"  fixed32 fixed32 = 7;\\n\"\n      + \"  fixed64 fixed64 = 8;\\n\"\n      + \"  sfixed32 sfixed32 = 9;\\n\"\n      + \"  sfixed64 sfixed64 = 10;\\n\"\n      + \"  float floatValue = 11;\\n\"\n      + \"  double doubleValue = 12;\\n\"\n      + \"  bool bool = 13;\\n\"\n      + \"  string string = 14;\\n\"\n      + \"  bytes bytes = 15;\\n\"\n      + \"  Color color = 16;\\n\"\n      + \"  User user = 17;\\n\"\n      + \"  map<string, string> ssMap = 18;\\n\"\n      + \"  map<string, User> spMap = 19;\\n\"\n      + \"  repeated string sList = 20;\\n\"\n      + \"  repeated User pList = 21;\\n\"\n      + \"  google.protobuf.Any any = 22;\\n\"\n      + \"  repeated google.protobuf.Any anys = 23;\\n\"\n      + \"  Root typeRecursive = 24;\\n\"\n      + \"}\\n\"\n      + \"\\n\"\n      + \"message User {\\n\"\n      + \"  string name = 1;\\n\"\n      + \"  Root typeRecursive = 2;\\n\"\n      + \"}\\n\"\n      + \"\\n\"\n      + \"enum Color {\\n\"\n      + \"  RED = 0;\\n\"\n      + \"  YELLOW = 1;\\n\"\n      + \"  BLUE = 2;\\n\"\n      + \"}\\n\"\n      + \"\\n\"\n      + \"service Service {\\n\"\n      + \"  //comment\\n\"\n      + \"  rpc op1 (User) returns (Root);\\n\"\n      + \"\\n\"\n      + \"  rpc op2 (Root) returns (User);\\n\"\n      + \"}\\n\";\n\n  @Test\n  public void protoToString() {\n    ProtoParser protoParser = new ProtoParser();\n    Proto proto = protoParser.parseFromContent(content);\n    String newContent = new ProtoToStringGenerator(proto).protoToString();\n\n    Assertions.assertEquals(content, newContent);\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport java.io.IOException;\nimport java.time.LocalDate;\nimport java.time.temporal.ChronoField;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer;\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;\nimport org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;\nimport org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchemaPojo;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.MicroserviceVersionsMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Empty;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.People;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n/**\n * SchemaMetaCodec test cases. This test cases covers POJO invoker and producer.\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class TestSchemaMetaCodec {\n\n  private SchemaMeta providerSchemaMeta;\n\n  private SchemaMeta consumerSchemaMeta;\n\n  @BeforeEach\n  public void setUp() {\n    ProtobufManager.clear();\n  }\n\n  private void mockSchemaMeta(String schemaId, AbstractSwaggerGenerator swaggerGenerator, Object producerInstance)\n      throws Exception {\n    MicroserviceVersionsMeta microserviceVersionsMeta = Mockito.mock(MicroserviceVersionsMeta.class);\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getExecutorManager()).thenReturn(executorManager);\n\n    MicroserviceMeta providerMicroserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    Mockito.when(providerMicroserviceMeta.getScbEngine()).thenReturn(scbEngine);\n    Mockito.when(providerMicroserviceMeta.getMicroserviceVersionsMeta()).thenReturn(microserviceVersionsMeta);\n    Mockito.when(providerMicroserviceMeta.getMicroserviceName()).thenReturn(\"test\");\n    Mockito.when(providerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID)).thenReturn(null);\n\n    MicroserviceMeta consumerMicroserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    Mockito.when(consumerMicroserviceMeta.getScbEngine()).thenReturn(scbEngine);\n    Mockito.when(consumerMicroserviceMeta.getMicroserviceVersionsMeta()).thenReturn(microserviceVersionsMeta);\n    Mockito.when(consumerMicroserviceMeta.getMicroserviceName()).thenReturn(\"test\");\n    Mockito.when(consumerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID)).thenReturn(null);\n    SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();\n    SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(producerInstance);\n    providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, schemaId, swaggerProducer.getSwagger());\n    for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {\n      OperationMeta operationMeta = providerSchemaMeta.ensureFindOperation(producerOperation.getOperationId());\n      operationMeta.setSwaggerProducerOperation(producerOperation);\n    }\n\n    consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, schemaId, swaggerProducer.getSwagger());\n  }\n\n  @Test\n  public void testProtoSchemaOperationUserSpringMVC() throws Exception {\n    mockSchemaMeta(\"ProtoSchema\", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());\n    testProtoSchemaOperationUserImpl();\n  }\n\n  @Test\n  public void testProtoSchemaOperationUserPOJO() throws Exception {\n    mockSchemaMeta(\"ProtoSchemaPojo\", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());\n    testProtoSchemaOperationUserImpl();\n  }\n\n  private Invocation mockInvocation(String operation, InvocationType invocationType) {\n    OperationMeta operationMeta;\n    boolean isProvider;\n    Invocation invocation = Mockito.mock(Invocation.class);\n    InvocationRuntimeType invocationRuntimeType;\n\n    if (InvocationType.CONSUMER == invocationType) {\n      operationMeta = consumerSchemaMeta.getOperations().get(operation);\n      isProvider = false;\n      Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);\n      invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();\n    } else {\n      operationMeta = providerSchemaMeta.getOperations().get(operation);\n      isProvider = true;\n      Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);\n      invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();\n    }\n\n    MicroserviceMeta microserviceMeta = operationMeta.getMicroserviceMeta();\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(invocation.getInvocationRuntimeType())\n        .thenReturn(invocationRuntimeType);\n    Mockito.when(invocation.findResponseType(200))\n        .thenReturn(invocationRuntimeType.findResponseType(200));\n    Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);\n    Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);\n\n    Mockito.when(invocation.isProducer()).thenReturn(isProvider);\n    return invocation;\n  }\n\n  private void testProtoSchemaOperationUserImpl() throws IOException {\n    Invocation consumerInvocation = mockInvocation(\"user\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"user\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    User user = new User();\n    user.name = \"user\";\n    User friend = new User();\n    friend.name = \"friend\";\n    List<User> friends = new ArrayList<>();\n    friends.add(friend);\n    user.friends = friends;\n    byte[] values;\n\n    // request message\n    Map<String, Object> args = new HashMap<>();\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    user.friends = friends;\n    args.put(\"user\", user);\n    values = requestSerializer.serialize(args);\n\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);\n    Assertions.assertEquals(user.name, ((User) decodedUserArgs.get(\"user\")).name);\n    Assertions.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get(\"user\")).friends.get(0).name);\n\n    // write request map (pojo)\n    args = new HashMap<>();\n    Map<String, Object> userMap = new HashMap<>();\n    userMap.put(\"name\", \"user\");\n    Map<String, Object> friendMap = new HashMap<>();\n    friendMap.put(\"name\", \"friend\");\n    List<Map<String, Object>> friendsList = new ArrayList<>();\n    friendsList.add(friendMap);\n    userMap.put(\"friends\", friendsList);\n    args.put(\"user\", userMap);\n    values = requestSerializer.serialize(args);\n\n    decodedUserArgs = requestDeserializer.deserialize(values);\n    Assertions.assertEquals(user.name, ((User) decodedUserArgs.get(\"user\")).name);\n    Assertions.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get(\"user\")).friends.get(0).name);\n\n    // response message\n    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);\n    values = responseSerializer.serialize(user);\n    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);\n    User decodedUser = (User) responseDeserializer\n        .deserialize(values, TypeFactory.defaultInstance().constructType(User.class));\n    Assertions.assertEquals(user.name, decodedUser.name);\n    Assertions.assertEquals(user.friends.get(0).name, decodedUser.friends.get(0).name);\n\n    user.friends = new ArrayList<>();\n    values = responseSerializer.serialize(user);\n    decodedUser = (User) responseDeserializer\n        .deserialize(values, TypeFactory.defaultInstance().constructType(User.class));\n    Assertions.assertEquals(user.name, decodedUser.name);\n    // proto buffer encode and decode empty list to be null\n    Assertions.assertNull(decodedUser.friends);\n  }\n\n  @Test\n  public void testProtoSchemaOperationmapUserSpringMVC() throws Exception {\n    mockSchemaMeta(\"ProtoSchema\", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());\n    testProtoSchemaOperationmapUserImpl(false);\n  }\n\n  @Test\n  public void testProtoSchemaOperationmapUserPOJO() throws Exception {\n    mockSchemaMeta(\"ProtoSchemaPojo\", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());\n    testProtoSchemaOperationmapUserImpl(true);\n  }\n\n  private void testProtoSchemaOperationmapUserImpl(boolean isPojo) throws IOException {\n    Invocation consumerInvocation = mockInvocation(\"mapUser\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"mapUser\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    User user = new User();\n    user.name = \"user\";\n    User friend = new User();\n    friend.name = \"friend\";\n    List<User> friends = new ArrayList<>();\n    friends.add(friend);\n    user.friends = friends;\n    byte[] values;\n    Map<String, User> userMap = new HashMap<>();\n    userMap.put(\"test\", user);\n\n    // request message\n    Map<String, Object> args = new HashMap<>();\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    user.friends = friends;\n    args.put(\"users\", userMap);\n    if (isPojo) {\n      Map<String, Object> swaggerArgs = new HashMap<>(1);\n      swaggerArgs.put(\"listListUserBody\", args);\n      values = requestSerializer.serialize(swaggerArgs);\n    } else {\n      values = requestSerializer.serialize(args);\n    }\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);\n    if (isPojo) {\n      decodedUserArgs = (Map<String, Object>) decodedUserArgs.get(\"mapUserBody\");\n      Assertions.assertEquals(user.name,\n          ((Map<String, Map<String, Object>>) decodedUserArgs.get(\"users\")).get(\"test\").get(\"name\"));\n      Assertions.assertEquals(user.friends.get(0).name,\n          ((List<Map<String, Object>>) ((Map<String, Map<String, Object>>) decodedUserArgs.get(\"users\")).get(\"test\")\n              .get(\"friends\")).get(0).get(\"name\"));\n    } else {\n      Assertions.assertEquals(user.name, ((Map<String, User>) decodedUserArgs.get(\"users\")).get(\"test\").name);\n      Assertions.assertEquals(user.friends.get(0).name,\n          ((Map<String, User>) decodedUserArgs.get(\"users\")).get(\"test\").friends.get(0).name);\n    }\n    // response message\n    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);\n    values = responseSerializer.serialize(userMap);\n    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);\n    Map<String, User> decodedUser = (Map<String, User>) responseDeserializer.deserialize(values,\n        TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, User.class));\n    Assertions.assertEquals(user.name, decodedUser.get(\"test\").name);\n    Assertions.assertEquals(user.friends.get(0).name, decodedUser.get(\"test\").friends.get(0).name);\n\n    user.friends = new ArrayList<>();\n    values = responseSerializer.serialize(userMap);\n    decodedUser = (Map<String, User>) responseDeserializer.deserialize(values,\n        TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, User.class));\n    Assertions.assertEquals(user.name, decodedUser.get(\"test\").name);\n    // proto buffer encode and decode empty list to be null\n    Assertions.assertNull(decodedUser.get(\"test\").friends);\n  }\n\n  @Test\n  public void testProtoSchemaOperationBaseSpringMVC() throws Exception {\n    mockSchemaMeta(\"ProtoSchema\", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());\n    testProtoSchemaOperationBaseImpl(false);\n  }\n\n  @Test\n  public void testProtoSchemaOperationBasePOJO() throws Exception {\n    mockSchemaMeta(\"ProtoSchemaPojo\", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());\n    testProtoSchemaOperationBaseImpl(true);\n  }\n\n  private void testProtoSchemaOperationBaseImpl(boolean isPojo) throws IOException {\n    Invocation consumerInvocation = mockInvocation(\"base\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"base\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    byte[] values;\n\n    // request message\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    boolean boolValue = true;\n    int iValue = 20;\n    long lValue = 30L;\n    float fValue = 40f;\n    double dValue = 50D;\n    String sValue = \"hello\";\n    int[] iArray = new int[] {60, 70};\n    Color color = Color.BLUE;\n    LocalDate localDate = LocalDate.of(2019, 10, 1);\n    Date date = new Date();\n    Empty empty = new Empty();\n    Map<String, Object> args = new HashMap<>();\n    args.put(\"boolValue\", boolValue);\n    args.put(\"iValue\", iValue);\n    args.put(\"lValue\", lValue);\n    args.put(\"fValue\", fValue);\n    args.put(\"dValue\", dValue);\n    args.put(\"sValue\", sValue);\n    args.put(\"iArray\", iArray);\n    args.put(\"color\", color);\n    args.put(\"localDate\", localDate);\n    args.put(\"date\", date);\n    args.put(\"empty\", empty);\n    if (isPojo) {\n      Map<String, Object> swaggerArgs = new HashMap<>();\n      swaggerArgs.put(\"baseBody\", args);\n      values = requestSerializer.serialize(swaggerArgs);\n    } else {\n      values = requestSerializer.serialize(args);\n    }\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedSwaggerArgs = requestDeserializer.deserialize(values);\n    Map<String, Object> decodedArgs;\n    if (isPojo) {\n      Assertions.assertEquals(1, decodedSwaggerArgs.size());\n      decodedArgs = (Map<String, Object>) decodedSwaggerArgs.get(\"baseBody\");\n    } else {\n      decodedArgs = decodedSwaggerArgs;\n    }\n    Assertions.assertEquals(boolValue, decodedArgs.get(\"boolValue\"));\n    Assertions.assertEquals(iValue, decodedArgs.get(\"iValue\"));\n    Assertions.assertEquals(lValue, decodedArgs.get(\"lValue\"));\n    Assertions.assertEquals(fValue, decodedArgs.get(\"fValue\"));\n    Assertions.assertEquals(dValue, decodedArgs.get(\"dValue\"));\n    if (isPojo) {\n      Assertions.assertEquals(2, ((List<Integer>) decodedArgs.get(\"iArray\")).size());\n      Assertions.assertEquals(60, (((List<Integer>) decodedArgs.get(\"iArray\")).get(0).intValue()));\n      Assertions.assertEquals(70, (((List<Integer>) decodedArgs.get(\"iArray\")).get(1).intValue()));\n      Assertions.assertEquals(color.ordinal(), decodedArgs.get(\"color\"));\n      Assertions.assertEquals(date.getTime(), decodedArgs.get(\"date\"));\n      Assertions.assertEquals(localDate.getLong(ChronoField.EPOCH_DAY), decodedArgs.get(\"localDate\"));\n      Assertions.assertTrue(((Map) decodedArgs.get(\"empty\")).isEmpty());\n    } else {\n      Assertions.assertArrayEquals(iArray, (int[]) decodedArgs.get(\"iArray\"));\n      Assertions.assertEquals(color, decodedArgs.get(\"color\"));\n      Assertions.assertEquals(date, decodedArgs.get(\"date\"));\n      Assertions.assertTrue(decodedArgs.get(\"localDate\") instanceof LocalDate);\n      Assertions.assertEquals(localDate, decodedArgs.get(\"localDate\"));\n      Assertions.assertTrue(decodedArgs.get(\"empty\") instanceof Empty);\n    }\n\n    // default value testing\n    args.put(\"boolValue\", false);\n    args.put(\"iValue\", 0);\n    args.put(\"lValue\", 0L);\n    args.put(\"fValue\", 0F);\n    args.put(\"dValue\", 0D);\n    args.put(\"sValue\", null);\n    args.put(\"iArray\", new int[0]);\n    args.put(\"color\", null);\n    args.put(\"localDate\", null);\n    args.put(\"date\", null);\n    args.put(\"empty\", null);\n    values = requestSerializer.serialize(args);\n    decodedArgs = requestDeserializer.deserialize(values);\n    Assertions.assertNull(decodedArgs.get(\"boolValue\"));\n    Assertions.assertNull(decodedArgs.get(\"iValue\"));\n    Assertions.assertNull(decodedArgs.get(\"lValue\"));\n    Assertions.assertNull(decodedArgs.get(\"fValue\"));\n    Assertions.assertNull(decodedArgs.get(\"dValue\"));\n    Assertions.assertNull(decodedArgs.get(\"iArray\"));\n    Assertions.assertNull(decodedArgs.get(\"color\"));\n    Assertions.assertNull(decodedArgs.get(\"localDate\"));\n    Assertions.assertNull(decodedArgs.get(\"date\"));\n    Assertions.assertNull(decodedArgs.get(\"empty\"));\n\n    // response message\n    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);\n    values = responseSerializer.serialize(30);\n    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);\n    Object decodedValue = responseDeserializer\n        .deserialize(values, TypeFactory.defaultInstance().constructType(int.class));\n    Assertions.assertEquals(30, (int) decodedValue);\n  }\n\n  @Test\n  public void testProtoSchemaOperationlistListUserSpringMVC() throws Exception {\n    mockSchemaMeta(\"ProtoSchema\", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());\n    testProtoSchemaOperationlistListUserImpl(false);\n  }\n\n  @Test\n  public void testProtoSchemaOperationlistListUserPOJO() throws Exception {\n    mockSchemaMeta(\"ProtoSchemaPojo\", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());\n    testProtoSchemaOperationlistListUserImpl(true);\n  }\n\n  private void testProtoSchemaOperationlistListUserImpl(boolean isPojo) throws IOException {\n    Invocation consumerInvocation = mockInvocation(\"listListUser\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"listListUser\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    byte[] values;\n\n    // request message\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    User user = new User();\n    user.name = \"user\";\n    User friend = new User();\n    friend.name = \"friend\";\n    List<User> friends = new ArrayList<>();\n    friends.add(friend);\n    user.friends = friends;\n    List<User> users = new ArrayList<>();\n    users.add(user);\n    List<List<User>> listOfUsers = new ArrayList<>();\n    listOfUsers.add(users);\n    Map<String, Object> args = new HashMap<>();\n    args.put(\"value\", listOfUsers);\n\n    if (isPojo) {\n      Map<String, Object> swaggerArgs = new HashMap<>();\n      swaggerArgs.put(\"listListUserBody\", args);\n      values = requestSerializer.serialize(swaggerArgs);\n    } else {\n      values = requestSerializer.serialize(args);\n    }\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedSwaggerArgs = requestDeserializer.deserialize(values);\n    Map<String, Object> decodedArgs;\n    if (isPojo) {\n      Assertions.assertEquals(1, decodedSwaggerArgs.size());\n      decodedArgs = (Map<String, Object>) decodedSwaggerArgs.get(\"listListUserBody\");\n    } else {\n      decodedArgs = decodedSwaggerArgs;\n    }\n    List<List<?>> listOfUsersRaw = (List<List<?>>) decodedArgs.get(\"value\");\n    Assertions.assertEquals(1, listOfUsersRaw.size());\n    List<?> mapUsersRaw = (List<?>) listOfUsersRaw.get(0);\n    Assertions.assertEquals(1, mapUsersRaw.size());\n    if (isPojo) {\n      Map<String, Object> userMap = (Map<String, Object>) mapUsersRaw.get(0);\n      Assertions.assertEquals(\"user\", userMap.get(\"name\"));\n      // proto buffer encode and decode empty list to be null\n      friends = (List<User>) userMap.get(\"friends\");\n      Map<String, Object> friendMap = (Map<String, Object>) friends.get(0);\n      Assertions.assertEquals(\"friend\", friendMap.get(\"name\"));\n    } else {\n      user = (User) mapUsersRaw.get(0);\n      Assertions.assertEquals(\"user\", user.name);\n      // proto buffer encode and decode empty list to be null\n      Assertions.assertEquals(\"friend\", user.friends.get(0).name);\n    }\n  }\n\n  @Test\n  public void testProtoSchemaOperationObjSpringMVC() throws Exception {\n    mockSchemaMeta(\"ProtoSchema\", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());\n    testProtoSchemaOperationObjImpl(false);\n  }\n\n  @Test\n  public void testProtoSchemaOperationObjPOJO() throws Exception {\n    mockSchemaMeta(\"ProtoSchemaPojo\", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());\n    testProtoSchemaOperationObjImpl(true);\n  }\n\n  private void testProtoSchemaOperationObjImpl(boolean isPojo) throws IOException {\n    Invocation consumerInvocation = mockInvocation(\"obj\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"obj\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    byte[] values;\n\n    // request message\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    Map<String, Object> args = new HashMap<>();\n    args.put(\"value\", 2);\n\n    values = requestSerializer.serialize(args);\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedArgs = requestDeserializer.deserialize(values);\n    int result = (int) decodedArgs.get(\"value\");\n    Assertions.assertEquals(2, result);\n\n    User user = new User();\n    user.name = \"user\";\n    User friend = new User();\n    friend.name = \"friend\";\n    List<User> friends = new ArrayList<>();\n    friends.add(friend);\n    user.friends = friends;\n    args.put(\"value\", user);\n    values = requestSerializer.serialize(args);\n    decodedArgs = requestDeserializer.deserialize(values);\n    Map<String, Object> userMap = (Map<String, Object>) decodedArgs.get(\"value\");\n    Assertions.assertEquals(\"user\", userMap.get(\"name\"));\n    // proto buffer encode and decode empty list to be null\n    friends = (List<User>) userMap.get(\"friends\");\n    Map<String, Object> friendMap = (Map<String, Object>) friends.get(0);\n    Assertions.assertEquals(\"friend\", friendMap.get(\"name\"));\n\n    args.clear();\n    People people = new People();\n    people.name = \"user\";\n    People pFriend = new People();\n    pFriend.name = \"friend\";\n    List<People> pFriends = new ArrayList<>();\n    pFriends.add(pFriend);\n    people.friends = pFriends;\n    args.put(\"value\", people);\n    values = requestSerializer.serialize(args);\n    decodedArgs = requestDeserializer.deserialize(values);\n    people = (People) decodedArgs.get(\"value\");\n    Assertions.assertEquals(\"user\", people.name);\n    // proto buffer encode and decode empty list to be null\n    Assertions.assertEquals(\"friend\", people.friends.get(0).name);\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer;\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;\nimport org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.MicroserviceVersionsMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Empty;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n/**\n * SchemaMetaCodec test cases. This test cases covers RestTemplate invoker and producer.\n */\npublic class TestSchemaMetaCodecRestTemplate {\n\n  private SchemaMeta providerSchemaMeta;\n\n  private SchemaMeta consumerSchemaMeta;\n\n  @BeforeEach\n  public void setUp() {\n    ProtobufManager.clear();\n    MicroserviceVersionsMeta microserviceVersionsMeta = Mockito.mock(MicroserviceVersionsMeta.class);\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getExecutorManager()).thenReturn(executorManager);\n\n    MicroserviceMeta providerMicroserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    Mockito.when(providerMicroserviceMeta.getScbEngine()).thenReturn(scbEngine);\n    Mockito.when(providerMicroserviceMeta.getMicroserviceVersionsMeta()).thenReturn(microserviceVersionsMeta);\n    Mockito.when(providerMicroserviceMeta.getMicroserviceName()).thenReturn(\"test\");\n    Mockito.when(providerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID)).thenReturn(null);\n\n    MicroserviceMeta consumerMicroserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    Mockito.when(consumerMicroserviceMeta.getScbEngine()).thenReturn(scbEngine);\n    Mockito.when(consumerMicroserviceMeta.getMicroserviceVersionsMeta()).thenReturn(microserviceVersionsMeta);\n    Mockito.when(consumerMicroserviceMeta.getMicroserviceName()).thenReturn(\"test\");\n    Mockito.when(consumerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID)).thenReturn(null);\n\n    SpringmvcSwaggerGenerator swaggerGenerator = new SpringmvcSwaggerGenerator(ProtoSchema.class);\n    SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();\n\n    SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(new ProtoSchema());\n    providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, \"ProtoSchema\", swaggerProducer.getSwagger());\n\n    for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {\n      OperationMeta operationMeta = providerSchemaMeta.ensureFindOperation(producerOperation.getOperationId());\n      operationMeta.setSwaggerProducerOperation(producerOperation);\n    }\n\n    consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, \"ProtoSchema\", swaggerProducer.getSwagger());\n  }\n\n  private Invocation mockInvocation(String operation, InvocationType invocationType) {\n    OperationMeta operationMeta;\n    boolean isProvider;\n    Invocation invocation = Mockito.mock(Invocation.class);\n    InvocationRuntimeType invocationRuntimeType;\n\n    if (InvocationType.CONSUMER == invocationType) {\n      operationMeta = consumerSchemaMeta.getOperations().get(operation);\n      isProvider = false;\n      Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);\n      invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();\n    } else {\n      operationMeta = providerSchemaMeta.getOperations().get(operation);\n      isProvider = true;\n      Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);\n      invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();\n    }\n\n    MicroserviceMeta microserviceMeta = operationMeta.getMicroserviceMeta();\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(invocation.getInvocationRuntimeType())\n        .thenReturn(invocationRuntimeType);\n    Mockito.when(invocation.findResponseType(200))\n        .thenReturn(invocationRuntimeType.findResponseType(200));\n    Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);\n    Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);\n\n    Mockito.when(invocation.isProducer()).thenReturn(isProvider);\n    return invocation;\n  }\n\n  @Test\n  public void testProtoSchemaOperationUser() throws Exception {\n    Invocation consumerInvocation = mockInvocation(\"user\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"user\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    User user = new User();\n    user.name = \"user\";\n    User friend = new User();\n    friend.name = \"friend\";\n    List<User> friends = new ArrayList<>();\n    friends.add(friend);\n    user.friends = friends;\n    byte[] values;\n\n    // request message\n    Map<String, Object> args = new HashMap<>();\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    user.friends = friends;\n    args.put(\"user\", user);\n    values = requestSerializer.serialize(args);\n\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);\n    Assertions.assertEquals(user.name, ((User) decodedUserArgs.get(\"user\")).name);\n    Assertions.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get(\"user\")).friends.get(0).name);\n\n    // response message\n    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);\n    values = responseSerializer.serialize(user);\n    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);\n    User decodedUser = (User) responseDeserializer\n        .deserialize(values, TypeFactory.defaultInstance().constructType(User.class));\n    Assertions.assertEquals(user.name, decodedUser.name);\n    Assertions.assertEquals(user.friends.get(0).name, decodedUser.friends.get(0).name);\n\n    user.friends = new ArrayList<>();\n    values = responseSerializer.serialize(user);\n    decodedUser = (User) responseDeserializer\n        .deserialize(values, TypeFactory.defaultInstance().constructType(User.class));\n    Assertions.assertEquals(user.name, decodedUser.name);\n    // proto buffer encode and decode empty list to be null\n    Assertions.assertNull(decodedUser.friends);\n  }\n\n  @Test\n  @SuppressWarnings({\"rawtypes\", \"unchecked\"})\n  public void testProtoSchemaOperationBase() throws Exception {\n    Invocation consumerInvocation = mockInvocation(\"base\", InvocationType.CONSUMER);\n    Invocation providerInvocation = mockInvocation(\"base\", InvocationType.PROVIDER);\n\n    OperationProtobuf providerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(providerInvocation);\n    OperationProtobuf consumerOperationProtobuf = ProtobufManager\n        .getOrCreateOperation(consumerInvocation);\n    byte[] values;\n\n    // request message\n    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();\n    boolean boolValue = true;\n    int iValue = 20;\n    long lValue = 30L;\n    float fValue = 40f;\n    double dValue = 50D;\n    String sValue = \"hello\";\n    int[] iArray = new int[] {60, 70};\n    Color color = Color.BLUE;\n    LocalDate localDate = LocalDate.of(2019, 10, 1);\n    Date date = new Date();\n    Empty empty = new Empty();\n    Map<String, Object> args = new HashMap<>();\n    args.put(\"boolValue\", boolValue);\n    args.put(\"iValue\", iValue);\n    args.put(\"lValue\", lValue);\n    args.put(\"fValue\", fValue);\n    args.put(\"dValue\", dValue);\n    args.put(\"sValue\", sValue);\n    args.put(\"iArray\", iArray);\n    args.put(\"color\", color);\n    args.put(\"localDate\", localDate);\n    args.put(\"date\", date);\n    args.put(\"empty\", empty);\n    values = requestSerializer.serialize(args);\n    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> decodedArgs = requestDeserializer.deserialize(values);\n    Assertions.assertEquals(boolValue, decodedArgs.get(\"boolValue\"));\n    Assertions.assertEquals(iValue, decodedArgs.get(\"iValue\"));\n    Assertions.assertEquals(lValue, decodedArgs.get(\"lValue\"));\n    Assertions.assertEquals(fValue, decodedArgs.get(\"fValue\"));\n    Assertions.assertEquals(dValue, decodedArgs.get(\"dValue\"));\n    Assertions.assertArrayEquals(iArray, (int[]) decodedArgs.get(\"iArray\"));\n    Assertions.assertEquals(color, decodedArgs.get(\"color\"));\n    Assertions.assertEquals(date, decodedArgs.get(\"date\"));\n    Assertions.assertTrue(decodedArgs.get(\"localDate\") instanceof LocalDate);\n    Assertions.assertEquals(localDate, decodedArgs.get(\"localDate\"));\n    Assertions.assertTrue(decodedArgs.get(\"empty\") instanceof Empty);\n\n    // default value testing\n    args.put(\"boolValue\", false);\n    args.put(\"iValue\", 0);\n    args.put(\"lValue\", 0L);\n    args.put(\"fValue\", 0F);\n    args.put(\"dValue\", 0D);\n    args.put(\"sValue\", null);\n    args.put(\"iArray\", new int[0]);\n    args.put(\"color\", null);\n    args.put(\"localDate\", null);\n    args.put(\"date\", null);\n    args.put(\"empty\", null);\n    values = requestSerializer.serialize(args);\n    decodedArgs = requestDeserializer.deserialize(values);\n    Assertions.assertNull(decodedArgs.get(\"boolValue\"));\n    Assertions.assertNull(decodedArgs.get(\"iValue\"));\n    Assertions.assertNull(decodedArgs.get(\"lValue\"));\n    Assertions.assertNull(decodedArgs.get(\"fValue\"));\n    Assertions.assertNull(decodedArgs.get(\"dValue\"));\n    Assertions.assertNull(decodedArgs.get(\"iArray\"));\n    Assertions.assertNull(decodedArgs.get(\"color\"));\n    Assertions.assertNull(decodedArgs.get(\"localDate\"));\n    Assertions.assertNull(decodedArgs.get(\"date\"));\n    Assertions.assertNull(decodedArgs.get(\"empty\"));\n\n    // response message\n    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);\n    values = responseSerializer.serialize(30);\n    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);\n    Object decodedValue = responseDeserializer\n        .deserialize(values, TypeFactory.defaultInstance().constructType(int.class));\n    Assertions.assertEquals(30, (int) decodedValue);\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSwaggerToProtoGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter;\n\nimport java.io.IOException;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;\nimport org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.protostuff.compiler.model.Proto;\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class TestSwaggerToProtoGenerator {\n  @Test\n  public void convert() throws IOException {\n    URL url = TestSwaggerToProtoGenerator.class.getClassLoader().getResource(\"ProtoSchema.proto\");\n    String protoContent = IOUtils.toString(url, StandardCharsets.UTF_8);\n    int idx = protoContent.indexOf(\"syntax = \");\n    protoContent = protoContent.substring(idx);\n\n    SpringmvcSwaggerGenerator swaggerGenerator = new SpringmvcSwaggerGenerator(ProtoSchema.class);\n    OpenAPI swagger = swaggerGenerator.generate();\n\n    SwaggerToProtoGenerator generator = new SwaggerToProtoGenerator(\"a.b\", swagger);\n    Proto proto = generator.convert();\n\n    Assertions.assertEquals(protoContent.replaceAll(\"\\r\\n\", \"\\n\"),\n        new ProtoToStringGenerator(proto).protoToString().replaceAll(\"\\r\\n\", \"\\n\"));\n  }\n\n  @Test\n  public void testEscape() {\n    Assertions.assertEquals(\"hello_my_service\", SwaggerToProtoGenerator.escapeMessageName(\"hello.my.service\"));\n    Assertions.assertEquals(\"hello_my_service\", SwaggerToProtoGenerator.escapeMessageName(\"hello_my_service\"));\n    Assertions.assertEquals(\"hello.my_service\", SwaggerToProtoGenerator.escapePackageName(\"hello.my-service\"));\n    Assertions.assertEquals(\"hello.test.test\", SwaggerToProtoGenerator.escapePackageName(\"hello.test.test\"));\n    Assertions.assertEquals(\"hello_my.test.test\", SwaggerToProtoGenerator.escapePackageName(\"hello:my.test.test\"));\n    Assertions.assertFalse(SwaggerToProtoGenerator.isValidEnum(\"hello.test.test\"));\n    Assertions.assertFalse(SwaggerToProtoGenerator.isValidEnum(\"hello.my-service\"));\n    Assertions.assertTrue(SwaggerToProtoGenerator.isValidEnum(\"My_ENum\"));\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/FieldNeedWrap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter.model;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\npublic class FieldNeedWrap {\n  public List<List<User>> listListUser;\n\n  public List<Map<String, User>> listMapUser;\n\n  public Map<String, List<User>> mapListUser;\n\n  public Map<String, Map<String, User>> mapMapUser;\n\n  public List<List<List<User>>> listListListUser;\n\n  public List<List<Map<String, User>>> listListMapUser;\n\n  public List<Map<String, List<User>>> listMapListUser;\n\n  public List<Map<String, Map<String, User>>> listMapMapUser;\n\n  public Map<String, Map<String, List<User>>> mapMapListUser;\n\n  public Map<String, Map<String, Map<String, User>>> mapMapMapUser;\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter.model;\n\n\nimport java.time.LocalDate;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Empty;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport jakarta.ws.rs.core.MediaType;\n\n@RequestMapping(path = \"/\")\npublic class ProtoSchema implements ProtoSchemaIntf {\n  @ApiResponses(value = {\n      @ApiResponse(responseCode = \"444\", content = @Content(schema = @Schema(implementation = Color.class)), description = \"xxx\")})\n  @GetMapping(path = \"/base\")\n  public int base(boolean boolValue, int iValue, long lValue, float fValue, double dValue, String sValue, int[] iArray,\n      Color color,\n      LocalDate localDate, Date date, @RequestBody Empty empty) {\n    return 0;\n  }\n\n  @GetMapping(path = \"/bytes\")\n  public byte[] bytes(@RequestBody byte[] value) {\n    return null;\n  }\n\n  @GetMapping(path = \"/colorBody\")\n  public Color colorBody(@RequestBody Color color) {\n    return null;\n  }\n\n  @GetMapping(path = \"/obj\")\n  public Object obj(@RequestBody Object value) {\n    return null;\n  }\n\n  @GetMapping(path = \"/user\")\n  public User user(@RequestBody User user) {\n    return null;\n  }\n\n  @GetMapping(path = \"/userWrapInProtobuf\")\n  public User userWrapInProtobuf(@RequestBody User user, int ivalue) {\n    return null;\n  }\n\n  @GetMapping(path = \"/listObj\")\n  public List<Object> listObj(@RequestBody List<Object> objs) {\n    return null;\n  }\n\n  @GetMapping(path = \"/listUser\")\n  public List<User> listUser(@RequestBody List<User> users) {\n    return null;\n  }\n\n  @GetMapping(path = \"/mapUser\")\n  public Map<String, User> mapUser(@RequestBody Map<String, User> users) {\n    return null;\n  }\n\n  @GetMapping(path = \"/mapObj\")\n  public Map<String, Object> mapObj(@RequestBody Map<String, Object> objs) {\n    return null;\n  }\n\n  @GetMapping(path = \"/ref\")\n  public Ref2 ref(@RequestBody Ref1 ref) {\n    return null;\n  }\n\n  @GetMapping(path = \"/noParamVoid\")\n  public void noParamVoid() {\n  }\n\n  @PostMapping(path = \"/listListString\")\n  public List<List<String>> listListString(@RequestBody List<List<String>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listListUser\")\n  public List<List<User>> listListUser(@RequestBody List<List<User>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listMapString\")\n  public List<Map<String, String>> listMapString(@RequestBody List<Map<String, String>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listMapUser\")\n  public List<Map<String, User>> listMapUser(@RequestBody List<Map<String, User>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/mapListString\")\n  public Map<String, List<String>> mapListString(@RequestBody Map<String, List<String>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/mapListUser\")\n  public Map<String, List<User>> mapListUser(@RequestBody Map<String, List<User>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/mapMapString\")\n  public Map<String, Map<String, String>> mapMapString(@RequestBody Map<String, Map<String, String>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/mapMapUser\")\n  public Map<String, Map<String, User>> mapMapUser(@RequestBody Map<String, Map<String, User>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listListListString\")\n  public List<List<List<String>>> listListListString(@RequestBody List<List<List<String>>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listListMapString\")\n  public List<List<Map<String, String>>> listListMapString(@RequestBody List<List<Map<String, String>>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listMapListString\")\n  public List<Map<String, List<String>>> listMapListString(@RequestBody List<Map<String, List<String>>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/listMapMapString\")\n  public List<Map<String, Map<String, String>>> listMapMapString(\n      @RequestBody List<Map<String, Map<String, String>>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/mapMapListString\")\n  public Map<String, Map<String, List<String>>> mapMapListString(\n      @RequestBody Map<String, Map<String, List<String>>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/mapMapMapString\")\n  public Map<String, Map<String, Map<String, String>>> mapMapMapString(\n      @RequestBody Map<String, Map<String, Map<String, String>>> value) {\n    return value;\n  }\n\n  @PostMapping(path = \"/fieldNeedWrap\")\n  public FieldNeedWrap fieldNeedWrap(@RequestBody FieldNeedWrap fieldNeedWrap) {\n    return fieldNeedWrap;\n  }\n\n  @PostMapping(path = \"/testTextPlain\", consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_PLAIN)\n  public String testTextPlain(@RequestBody String fieldNeedWrap) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter.model;\n\n\nimport java.time.LocalDate;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Empty;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\npublic interface ProtoSchemaIntf {\n  int base(boolean boolValue, int iValue, long lValue, float fValue, double dValue, String sValue, int[] iArray,\n      Color color,\n      LocalDate localDate, Date date, Empty empty);\n\n  byte[] bytes(byte[] value);\n\n\n  Color colorBody(Color color);\n\n\n  Object obj(Object value);\n\n\n  User user(User user);\n\n  User userWrapInProtobuf(User user, int ivalue);\n\n\n  List<Object> listObj(List<Object> objs);\n\n  List<User> listUser(List<User> users);\n\n\n  Map<String, User> mapUser(Map<String, User> users);\n\n  Map<String, Object> mapObj(Map<String, Object> objs);\n\n  Ref2 ref(Ref1 ref);\n\n\n  void noParamVoid();\n\n  List<List<String>> listListString(List<List<String>> value);\n\n\n  List<List<User>> listListUser(List<List<User>> value);\n\n\n  List<Map<String, String>> listMapString(List<Map<String, String>> value);\n\n\n  List<Map<String, User>> listMapUser(List<Map<String, User>> value);\n\n\n  Map<String, List<String>> mapListString(Map<String, List<String>> value);\n\n\n  Map<String, List<User>> mapListUser(Map<String, List<User>> value);\n\n  Map<String, Map<String, String>> mapMapString(Map<String, Map<String, String>> value);\n\n\n  Map<String, Map<String, User>> mapMapUser(Map<String, Map<String, User>> value);\n\n\n  List<List<List<String>>> listListListString(List<List<List<String>>> value);\n\n\n  List<List<Map<String, String>>> listListMapString(List<List<Map<String, String>>> value);\n\n  List<Map<String, List<String>>> listMapListString(List<Map<String, List<String>>> value);\n\n\n  List<Map<String, Map<String, String>>> listMapMapString(\n      List<Map<String, Map<String, String>>> value);\n\n\n  Map<String, Map<String, List<String>>> mapMapListString(\n      Map<String, Map<String, List<String>>> value);\n\n  Map<String, Map<String, Map<String, String>>> mapMapMapString(\n      Map<String, Map<String, Map<String, String>>> value);\n\n  FieldNeedWrap fieldNeedWrap(FieldNeedWrap fieldNeedWrap);\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaPojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter.model;\n\n\nimport java.time.LocalDate;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Empty;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\n\npublic class ProtoSchemaPojo implements ProtoSchemaIntf {\n  @ApiResponses(value = {\n      @ApiResponse(responseCode = \"444\", content = @Content(schema = @Schema(implementation = Color.class)), description = \"xxx\")})\n  public int base(boolean boolValue, int iValue, long lValue, float fValue, double dValue, String sValue, int[] iArray,\n      Color color,\n      LocalDate localDate, Date date, Empty empty) {\n    return 0;\n  }\n\n  public byte[] bytes(byte[] value) {\n    return null;\n  }\n\n\n  public Color colorBody(Color color) {\n    return null;\n  }\n\n\n  public Object obj(Object value) {\n    return null;\n  }\n\n\n  public User user(User user) {\n    return null;\n  }\n\n\n  public User userWrapInProtobuf(User user, int ivalue) {\n    return null;\n  }\n\n\n  public List<Object> listObj(List<Object> objs) {\n    return null;\n  }\n\n  public List<User> listUser(List<User> users) {\n    return null;\n  }\n\n\n  public Map<String, User> mapUser(Map<String, User> users) {\n    return null;\n  }\n\n  public Map<String, Object> mapObj(Map<String, Object> objs) {\n    return null;\n  }\n\n  public Ref2 ref(Ref1 ref) {\n    return null;\n  }\n\n\n  public void noParamVoid() {\n  }\n\n\n  public List<List<String>> listListString(List<List<String>> value) {\n    return value;\n  }\n\n\n  public List<List<User>> listListUser(List<List<User>> value) {\n    return value;\n  }\n\n\n  public List<Map<String, String>> listMapString(List<Map<String, String>> value) {\n    return value;\n  }\n\n\n  public List<Map<String, User>> listMapUser(List<Map<String, User>> value) {\n    return value;\n  }\n\n\n  public Map<String, List<String>> mapListString(Map<String, List<String>> value) {\n    return value;\n  }\n\n\n  public Map<String, List<User>> mapListUser(Map<String, List<User>> value) {\n    return value;\n  }\n\n\n  public Map<String, Map<String, String>> mapMapString(Map<String, Map<String, String>> value) {\n    return value;\n  }\n\n\n  public Map<String, Map<String, User>> mapMapUser(Map<String, Map<String, User>> value) {\n    return value;\n  }\n\n\n  public List<List<List<String>>> listListListString(List<List<List<String>>> value) {\n    return value;\n  }\n\n\n  public List<List<Map<String, String>>> listListMapString(List<List<Map<String, String>>> value) {\n    return value;\n  }\n\n  public List<Map<String, List<String>>> listMapListString(List<Map<String, List<String>>> value) {\n    return value;\n  }\n\n\n  public List<Map<String, Map<String, String>>> listMapMapString(\n      List<Map<String, Map<String, String>>> value) {\n    return value;\n  }\n\n\n  public Map<String, Map<String, List<String>>> mapMapListString(\n      Map<String, Map<String, List<String>>> value) {\n    return value;\n  }\n\n  public Map<String, Map<String, Map<String, String>>> mapMapMapString(\n      Map<String, Map<String, Map<String, String>>> value) {\n    return value;\n  }\n\n  public FieldNeedWrap fieldNeedWrap(FieldNeedWrap fieldNeedWrap) {\n    return fieldNeedWrap;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter.model;\n\npublic class Ref1 {\n  public Ref2 ref;\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.internal.converter.model;\n\npublic class Ref2 {\n  public Ref1 ref;\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/TestSchemaCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\nimport java.math.BigDecimal;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.codec.protobuf.schema.model.DeptInfo;\nimport org.apache.servicecomb.codec.protobuf.schema.model.SchemaService;\nimport org.apache.servicecomb.codec.protobuf.schema.model.ScoreInfo;\nimport org.apache.servicecomb.codec.protobuf.schema.model.UserInfo;\nimport org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\nimport org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.NumberSchema;\nimport io.swagger.v3.oas.models.media.ObjectSchema;\nimport io.swagger.v3.oas.models.media.StringSchema;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class TestSchemaCodec {\n  ScopedProtobufSchemaManager manager = new ScopedProtobufSchemaManager();\n\n  @Test\n  public void test_string_schema_codec() throws Exception {\n    OpenAPI openAPI = new OpenAPI();\n    StringSchema schema = new StringSchema();\n    ProtoMapper protoMapper = manager.getOrCreateProtoMapper(openAPI, \"test\", \"input\", schema);\n    RootSerializer serializer = protoMapper.getSerializerSchemaManager()\n        .createRootSerializer(protoMapper.getProto().getMessage(\"input\"),\n            String.class);\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"value\", \"abcdefg\");\n    byte[] result = serializer.serialize(arguments);\n    RootDeserializer<PropertyWrapper<String>> deserializer = protoMapper.getDeserializerSchemaManager()\n        .createRootDeserializer(protoMapper.getProto().getMessage(\"input\"), String.class);\n    PropertyWrapper<String> deserializedResult = deserializer.deserialize(result);\n    assertEquals(\"abcdefg\", deserializedResult.getValue());\n  }\n\n  @Test\n  public void test_number_schema_codec() throws Exception {\n    OpenAPI openAPI = new OpenAPI();\n    NumberSchema schema = new NumberSchema();\n    ProtoMapper protoMapper = manager.getOrCreateProtoMapper(openAPI, \"test\", \"input\", schema);\n    RootSerializer serializer = protoMapper.getSerializerSchemaManager()\n        .createRootSerializer(protoMapper.getProto().getMessage(\"input\"),\n            BigDecimal.class);\n    Map<String, Object> arguments = new HashMap<>();\n    BigDecimal number = new BigDecimal(10);\n    arguments.put(\"value\", number);\n    byte[] result = serializer.serialize(arguments);\n    RootDeserializer<PropertyWrapper<BigDecimal>> deserializer = protoMapper.getDeserializerSchemaManager()\n        .createRootDeserializer(protoMapper.getProto().getMessage(\"input\"), BigDecimal.class);\n    PropertyWrapper<BigDecimal> deserializedResult = deserializer.deserialize(result);\n    assertEquals(number, deserializedResult.getValue());\n  }\n\n  public static class User {\n    public String name;\n  }\n\n  @Test\n  public void test_object_schema_codec() throws Exception {\n    OpenAPI openAPI = new OpenAPI();\n\n    ObjectSchema schema = new ObjectSchema();\n    schema.setName(\"User\");\n    schema.addProperty(\"name\", new StringSchema());\n    openAPI.setComponents(new Components());\n    openAPI.getComponents().addSchemas(\"User\", schema);\n\n    ObjectSchema ref = new ObjectSchema();\n    ref.set$ref(Components.COMPONENTS_SCHEMAS_REF + \"User\");\n\n    ProtoMapper protoMapper = manager.getOrCreateProtoMapper(openAPI, \"test\", \"input\", ref);\n    RootSerializer serializer = protoMapper.getSerializerSchemaManager()\n        .createRootSerializer(protoMapper.getProto().getMessage(\"input\"),\n            User.class);\n    Map<String, Object> arguments = new HashMap<>();\n    User user = new User();\n    user.name = \"abcdefg\";\n    arguments.put(\"value\", user);\n    byte[] result = serializer.serialize(arguments);\n    RootDeserializer<PropertyWrapper<User>> deserializer = protoMapper.getDeserializerSchemaManager()\n        .createRootDeserializer(protoMapper.getProto().getMessage(\"input\"), User.class);\n    PropertyWrapper<User> deserializedResult = deserializer.deserialize(result);\n    assertEquals(\"abcdefg\", deserializedResult.getValue().name);\n  }\n\n  @Test\n  public void test_springmvc_model_schema_codec_correct() throws Exception {\n    SpringmvcSwaggerGenerator generator = new SpringmvcSwaggerGenerator(SchemaService.class);\n    OpenAPI openAPI = generator.generate();\n\n    ProtoMapper protoMapper = manager.getOrCreateProtoMapper(openAPI, \"schemaService\", \"input\",\n        openAPI.getPaths().get(\"/testUserInfo\").getPost()\n            .getRequestBody().getContent().get(MediaType.APPLICATION_JSON)\n            .getSchema());\n    RootSerializer serializer = protoMapper.getSerializerSchemaManager()\n        .createRootSerializer(protoMapper.getProto().getMessage(\"input\"),\n            UserInfo.class);\n    Map<String, Object> arguments = new HashMap<>();\n    UserInfo userInfo = new UserInfo();\n    DeptInfo deptInfo = new DeptInfo();\n    deptInfo.setCode(\"123\");\n    ScoreInfo scoreInfo = new ScoreInfo();\n    scoreInfo.setType(233);\n    deptInfo.setScores(List.of(scoreInfo));\n    userInfo.setSubDeptInfos(List.of(deptInfo));\n    arguments.put(\"value\", userInfo);\n    byte[] result = serializer.serialize(arguments);\n    RootDeserializer<PropertyWrapper<UserInfo>> deserializer = protoMapper.getDeserializerSchemaManager()\n        .createRootDeserializer(protoMapper.getProto().getMessage(\"input\"), UserInfo.class);\n    PropertyWrapper<UserInfo> deserializedResult = deserializer.deserialize(result);\n    assertEquals(1, deserializedResult.getValue().getSubDeptInfos().size());\n    assertEquals(\"123\", deserializedResult.getValue().getSubDeptInfos().get(0).getCode());\n    assertEquals(233, deserializedResult.getValue().getSubDeptInfos().get(0).getScores().get(0).getType());\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/TestSchemaToProtoGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\nimport org.apache.servicecomb.codec.protobuf.internal.converter.ProtoToStringGenerator;\nimport org.apache.servicecomb.codec.protobuf.schema.model.SchemaService;\nimport org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;\nimport org.assertj.core.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\n\nimport io.protostuff.compiler.model.Proto;\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.ObjectSchema;\nimport io.swagger.v3.oas.models.media.StringSchema;\nimport jakarta.ws.rs.core.MediaType;\n\n//CHECKSTYLE:OFF\n@SuppressWarnings(\"unused\")\npublic class TestSchemaToProtoGenerator {\n  @Test\n  public void test_string_schema_is_correct() {\n    OpenAPI openAPI = new OpenAPI();\n    StringSchema schema = new StringSchema();\n    SchemaToProtoGenerator generator =\n        new SchemaToProtoGenerator(\"test.string\", openAPI, schema, \"input\");\n    Proto proto = generator.convert();\n    assertEquals(\"\"\"\n        syntax = \"proto3\";\n        package test.string;\n\n        //@WrapProperty\n        message input {\n          string value = 1;\n        }\n        \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n  }\n\n  @Test\n  public void test_object_schema_is_correct() {\n    OpenAPI openAPI = new OpenAPI();\n\n    ObjectSchema schema = new ObjectSchema();\n    schema.setName(\"User\");\n    schema.addProperty(\"name\", new StringSchema());\n    openAPI.setComponents(new Components());\n    openAPI.getComponents().addSchemas(\"User\", schema);\n\n    ObjectSchema ref = new ObjectSchema();\n    ref.set$ref(Components.COMPONENTS_SCHEMAS_REF + \"User\");\n\n    SchemaToProtoGenerator generator =\n        new SchemaToProtoGenerator(\"test.object\", openAPI, ref, \"input\");\n    Proto proto = generator.convert();\n    assertEquals(\"\"\"\n        syntax = \"proto3\";\n        package test.object;\n\n        message User {\n          string name = 1;\n        }\n\n        //@WrapProperty\n        message input {\n          User value = 1;\n        }\n        \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n  }\n\n  static class Model {\n    public String name;\n\n    public int age;\n  }\n\n  interface SpringMvcSchema {\n    @PostMapping(\"/testInt\")\n    int testInt(@RequestBody int param);\n\n    @PostMapping(\"/testModel\")\n    Model testModel(@RequestBody Model model);\n  }\n\n  @Test\n  public void test_springmvc_int_schema_correct() {\n    SpringmvcSwaggerGenerator generator = new SpringmvcSwaggerGenerator(SpringMvcSchema.class);\n    OpenAPI openAPI = generator.generate();\n\n    SchemaToProtoGenerator protoGenerator =\n        new SchemaToProtoGenerator(\"test.int\", openAPI,\n            openAPI.getPaths().get(\"/testInt\").getPost()\n                .getRequestBody().getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"testIntRequest\");\n    Proto proto = protoGenerator.convert();\n    assertEquals(\"\"\"\n        syntax = \"proto3\";\n        package test.int;\n\n        //@WrapProperty\n        message testIntRequest {\n          sint32 value = 1;\n        }\n        \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n\n    protoGenerator =\n        new SchemaToProtoGenerator(\"test.int\", openAPI,\n            openAPI.getPaths().get(\"/testInt\").getPost()\n                .getResponses().get(\"200\").getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"testIntResponse\");\n    proto = protoGenerator.convert();\n    assertEquals(\"\"\"\n        syntax = \"proto3\";\n        package test.int;\n\n        //@WrapProperty\n        message testIntResponse {\n          sint32 value = 1;\n        }\n        \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n  }\n\n\n  @Test\n  public void test_springmvc_model_schema_correct() {\n    SpringmvcSwaggerGenerator generator = new SpringmvcSwaggerGenerator(SpringMvcSchema.class);\n    OpenAPI openAPI = generator.generate();\n\n    SchemaToProtoGenerator protoGenerator =\n        new SchemaToProtoGenerator(\"test.model\", openAPI,\n            openAPI.getPaths().get(\"/testModel\").getPost()\n                .getRequestBody().getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"testModelRequest\");\n    Proto proto = protoGenerator.convert();\n    assertEquals(\"\"\"\n        syntax = \"proto3\";\n        package test.model;\n\n        message Model {\n          sint32 age = 1;\n          string name = 2;\n        }\n\n        //@WrapProperty\n        message testModelRequest {\n          Model value = 1;\n        }\n        \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n\n    protoGenerator =\n        new SchemaToProtoGenerator(\"test.model\", openAPI,\n            openAPI.getPaths().get(\"/testModel\").getPost()\n                .getResponses().get(\"200\").getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"testIntResponse\");\n    proto = protoGenerator.convert();\n    assertEquals(\"\"\"\n        syntax = \"proto3\";\n        package test.model;\n\n        message Model {\n          sint32 age = 1;\n          string name = 2;\n        }\n\n        //@WrapProperty\n        message testIntResponse {\n          Model value = 1;\n        }\n        \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n  }\n\n  @Test\n  public void testNestedModelCorrect() {\n    SpringmvcSwaggerGenerator generator = new SpringmvcSwaggerGenerator(SchemaService.class);\n    OpenAPI openAPI = generator.generate();\n    SchemaToProtoGenerator protoGenerator =\n        new SchemaToProtoGenerator(\"test.model\", openAPI,\n            openAPI.getPaths().get(\"/testUserInfo\").getPost()\n                .getRequestBody().getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"request\");\n    Proto proto = protoGenerator.convert();\n    assertEquals(\"\"\"\n       syntax = \"proto3\";\n       package test.model;\n\n       //@WrapProperty\n       message MapString {\n         map<string, string> value = 1;\n       }\n\n       //@WrapProperty\n       message ListListString {\n         repeated ListString value = 1;\n       }\n\n       //@WrapProperty\n       message ListString {\n         repeated string value = 1;\n       }\n\n       message ScoreInfo {\n         sint32 type = 1;\n       }\n\n       message DeptInfo {\n         string code = 1;\n         string name = 2;\n         repeated ScoreInfo scores = 3;\n       }\n\n       message UserInfo {\n         repeated MapString extraInfos = 1;\n         repeated ListListString nestedLists = 2;\n         repeated DeptInfo subDeptInfos = 3;\n       }\n\n       //@WrapProperty\n       message ListScoreInfo {\n         repeated ScoreInfo value = 1;\n       }\n\n       //@WrapProperty\n       message ListDeptInfo {\n         repeated DeptInfo value = 1;\n       }\n\n       //@WrapProperty\n       message request {\n         UserInfo value = 1;\n       }\n       \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n  }\n\n  @Test\n  public void testListMapTypeCorrect() {\n    SpringmvcSwaggerGenerator generator = new SpringmvcSwaggerGenerator(SchemaService.class);\n    OpenAPI openAPI = generator.generate();\n    SchemaToProtoGenerator protoGenerator =\n        new SchemaToProtoGenerator(\"test.model\", openAPI,\n            openAPI.getPaths().get(\"/testListType\").getPost()\n                .getRequestBody().getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"request\");\n    Proto proto = protoGenerator.convert();\n    assertEquals(\"\"\"\n       syntax = \"proto3\";\n       package test.model;\n\n       message ScoreInfo {\n         sint32 type = 1;\n       }\n\n       message DeptInfo {\n         string code = 1;\n         string name = 2;\n         repeated ScoreInfo scores = 3;\n       }\n\n       //@WrapProperty\n       message ListScoreInfo {\n         repeated ScoreInfo value = 1;\n       }\n\n       //@WrapProperty\n       message ListDeptInfo {\n         repeated DeptInfo value = 1;\n       }\n\n       //@WrapProperty\n       message request {\n         repeated DeptInfo value = 1;\n       }\n       \"\"\".trim(), new ProtoToStringGenerator(proto).protoToString().trim());\n  }\n\n  @Test\n  public void testCyclicModelWrong() {\n    SpringmvcSwaggerGenerator generator = new SpringmvcSwaggerGenerator(SchemaService.class);\n    OpenAPI openAPI = generator.generate();\n    SchemaToProtoGenerator protoGenerator =\n        new SchemaToProtoGenerator(\"test.model\", openAPI,\n            openAPI.getPaths().get(\"/testCyclic\").getPost()\n                .getRequestBody().getContent().get(MediaType.APPLICATION_JSON)\n                .getSchema(), \"request\");\n    IllegalArgumentException throwable = Assertions.catchThrowableOfType(() -> protoGenerator.convert(),\n        IllegalArgumentException.class);\n    assertEquals(\"Failed to create schema request. May be cyclic object.\", throwable.getMessage());\n  }\n}\n//CHECKSTYLE:ON\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/model/CyclicInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema.model;\n\npublic class CyclicInfo {\n  private String name;\n  private CyclicInfo child;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public CyclicInfo getChild() {\n    return child;\n  }\n\n  public void setChild(CyclicInfo child) {\n    this.child = child;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/model/DeptInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema.model;\n\nimport java.util.List;\n\npublic class DeptInfo {\n  private String name;\n\n  private String code;\n\n  private List<ScoreInfo> scores;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getCode() {\n    return code;\n  }\n\n  public void setCode(String code) {\n    this.code = code;\n  }\n\n  public List<ScoreInfo> getScores() {\n    return scores;\n  }\n\n  public void setScores(List<ScoreInfo> scores) {\n    this.scores = scores;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/model/SchemaService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema.model;\n\nimport java.util.List;\n\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping(\"/schemaService\")\npublic class SchemaService {\n  @PostMapping(\"testUserInfo\")\n  public void testUserInfo(@RequestBody UserInfo request) {\n  }\n\n  @PostMapping(\"testListType\")\n  public void testListType(@RequestBody List<DeptInfo> request) {\n  }\n\n  @PostMapping(\"testCyclic\")\n  public void testCyclic(@RequestBody CyclicInfo request) {\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/model/ScoreInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema.model;\n\npublic class ScoreInfo {\n  private Integer type;\n\n  public Integer getType() {\n    return type;\n  }\n\n  public void setType(Integer type) {\n    this.type = type;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/schema/model/UserInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.codec.protobuf.schema.model;\n\nimport java.util.List;\nimport java.util.Map;\n\npublic class UserInfo {\n  private List<DeptInfo> subDeptInfos;\n\n  private List<Map<String, String>> extraInfos;\n\n  private List<List<List<String>>> nestedLists;\n\n  public List<DeptInfo> getSubDeptInfos() {\n    return subDeptInfos;\n  }\n\n  public void setSubDeptInfos(List<DeptInfo> subDeptInfos) {\n    this.subDeptInfos = subDeptInfos;\n  }\n\n  public List<Map<String, String>> getExtraInfos() {\n    return extraInfos;\n  }\n\n  public void setExtraInfos(List<Map<String, String>> extraInfos) {\n    this.extraInfos = extraInfos;\n  }\n\n  public List<List<List<String>>> getNestedLists() {\n    return nestedLists;\n  }\n\n  public void setNestedLists(List<List<List<String>>> nestedLists) {\n    this.nestedLists = nestedLists;\n  }\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/proto/ModelProtobuf.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\npackage proto;\n\noption java_package = \"io.protostuff.runtime.model\";\noption java_outer_classname = \"ModelProtobuf\";\n\nmessage User{\n\tstring name = 1;\n}\n\nmessage RequestHeader{\n\tstring destMicroservice = 1;\n\tint32 msgType = 2;\n\tint32 flags = 3;\n\tstring schemaId = 5;\n\tstring operationName = 6;\n\tmap<string, string> cseContext = 7;\n\tmap<string, User> userMap = 8;\n\trepeated string list = 9;\n\trepeated User userList = 10;\n}\n"
  },
  {
    "path": "common/common-protobuf/src/test/resources/ProtoSchema.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\nimport \"google/protobuf/empty.proto\";\nimport \"google/protobuf/any.proto\";\npackage a.b;\n\nmessage Empty {\n}\n\nmessage FieldNeedWrap {\n  repeated ListUser listListUser = 1;\n  repeated MapUser listMapUser = 2;\n  map<string, ListUser> mapListUser = 3;\n  map<string, MapUser> mapMapUser = 4;\n  repeated ListListUser listListListUser = 5;\n  repeated ListMapUser listListMapUser = 6;\n  repeated MapListUser listMapListUser = 7;\n  repeated MapMapUser listMapMapUser = 8;\n  map<string, MapListUser> mapMapListUser = 9;\n  map<string, MapMapUser> mapMapMapUser = 10;\n}\n\nmessage User {\n  string name = 1;\n  repeated User friends = 2;\n}\n\nmessage Ref1 {\n  Ref2 ref = 1;\n}\n\nmessage Ref2 {\n  Ref1 ref = 1;\n}\n\n//@WrapArguments\nmessage BaseRequestWrap {\n  bool boolValue = 1;\n  sint32 iValue = 2;\n  sint64 lValue = 3;\n  float fValue = 4;\n  double dValue = 5;\n  string sValue = 6;\n  repeated sint32 iArray = 7;\n  Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 color = 8;\n  int64 localDate = 9;\n  int64 date = 10;\n  Empty empty = 11;\n}\n\n//@WrapProperty\nmessage BaseResponseWrap200 {\n  sint32 value = 1;\n}\n\n//@WrapProperty\nmessage BaseResponseWrap444 {\n  Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 value = 1;\n}\n\n//@WrapArguments\nmessage BytesRequestWrap {\n  bytes value = 1;\n}\n\n//@WrapProperty\nmessage BytesResponseWrap200 {\n  bytes value = 1;\n}\n\n//@WrapArguments\nmessage ColorBodyRequestWrap {\n  Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 color = 1;\n}\n\n//@WrapProperty\nmessage ColorBodyResponseWrap200 {\n  Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 value = 1;\n}\n\n//@WrapArguments\nmessage ListListListStringRequestWrap {\n  repeated ListListString value = 1;\n}\n\n//@WrapProperty\nmessage ListListListStringResponseWrap200 {\n  repeated ListListString value = 1;\n}\n\n//@WrapArguments\nmessage ListListMapStringRequestWrap {\n  repeated ListMapString value = 1;\n}\n\n//@WrapProperty\nmessage ListListMapStringResponseWrap200 {\n  repeated ListMapString value = 1;\n}\n\n//@WrapArguments\nmessage ListListStringRequestWrap {\n  repeated ListString value = 1;\n}\n\n//@WrapProperty\nmessage ListListStringResponseWrap200 {\n  repeated ListString value = 1;\n}\n\n//@WrapArguments\nmessage ListListUserRequestWrap {\n  repeated ListUser value = 1;\n}\n\n//@WrapProperty\nmessage ListListUserResponseWrap200 {\n  repeated ListUser value = 1;\n}\n\n//@WrapArguments\nmessage ListMapListStringRequestWrap {\n  repeated MapListString value = 1;\n}\n\n//@WrapProperty\nmessage ListMapListStringResponseWrap200 {\n  repeated MapListString value = 1;\n}\n\n//@WrapArguments\nmessage ListMapMapStringRequestWrap {\n  repeated MapMapString value = 1;\n}\n\n//@WrapProperty\nmessage ListMapMapStringResponseWrap200 {\n  repeated MapMapString value = 1;\n}\n\n//@WrapArguments\nmessage ListMapStringRequestWrap {\n  repeated MapString value = 1;\n}\n\n//@WrapProperty\nmessage ListMapStringResponseWrap200 {\n  repeated MapString value = 1;\n}\n\n//@WrapArguments\nmessage ListMapUserRequestWrap {\n  repeated MapUser value = 1;\n}\n\n//@WrapProperty\nmessage ListMapUserResponseWrap200 {\n  repeated MapUser value = 1;\n}\n\n//@WrapArguments\nmessage ListObjRequestWrap {\n  repeated google.protobuf.Any objs = 1;\n}\n\n//@WrapProperty\nmessage ListObjResponseWrap200 {\n  repeated google.protobuf.Any value = 1;\n}\n\n//@WrapArguments\nmessage ListUserRequestWrap {\n  repeated User users = 1;\n}\n\n//@WrapProperty\nmessage ListUserResponseWrap200 {\n  repeated User value = 1;\n}\n\n//@WrapArguments\nmessage MapListStringRequestWrap {\n  map<string, ListString> value = 1;\n}\n\n//@WrapProperty\nmessage MapListStringResponseWrap200 {\n  map<string, ListString> value = 1;\n}\n\n//@WrapArguments\nmessage MapListUserRequestWrap {\n  map<string, ListUser> value = 1;\n}\n\n//@WrapProperty\nmessage MapListUserResponseWrap200 {\n  map<string, ListUser> value = 1;\n}\n\n//@WrapArguments\nmessage MapMapListStringRequestWrap {\n  map<string, MapListString> value = 1;\n}\n\n//@WrapProperty\nmessage MapMapListStringResponseWrap200 {\n  map<string, MapListString> value = 1;\n}\n\n//@WrapArguments\nmessage MapMapMapStringRequestWrap {\n  map<string, MapMapString> value = 1;\n}\n\n//@WrapProperty\nmessage MapMapMapStringResponseWrap200 {\n  map<string, MapMapString> value = 1;\n}\n\n//@WrapArguments\nmessage MapMapStringRequestWrap {\n  map<string, MapString> value = 1;\n}\n\n//@WrapProperty\nmessage MapMapStringResponseWrap200 {\n  map<string, MapString> value = 1;\n}\n\n//@WrapArguments\nmessage MapMapUserRequestWrap {\n  map<string, MapUser> value = 1;\n}\n\n//@WrapProperty\nmessage MapMapUserResponseWrap200 {\n  map<string, MapUser> value = 1;\n}\n\n//@WrapArguments\nmessage MapObjRequestWrap {\n  map<string, google.protobuf.Any> objs = 1;\n}\n\n//@WrapProperty\nmessage MapObjResponseWrap200 {\n  map<string, google.protobuf.Any> value = 1;\n}\n\n//@WrapArguments\nmessage MapUserRequestWrap {\n  map<string, User> users = 1;\n}\n\n//@WrapProperty\nmessage MapUserResponseWrap200 {\n  map<string, User> value = 1;\n}\n\n//@WrapArguments\nmessage TestTextPlainRequestWrap {\n  string fieldNeedWrap = 1;\n}\n\n//@WrapProperty\nmessage TestTextPlainResponseWrap200 {\n  string value = 1;\n}\n\n//@WrapArguments\nmessage UserWrapInProtobufRequestWrap {\n  sint32 ivalue = 1;\n  User user = 2;\n}\n\n//@WrapProperty\nmessage ListUser {\n  repeated User value = 1;\n}\n\n//@WrapProperty\nmessage MapUser {\n  map<string, User> value = 1;\n}\n\n//@WrapProperty\nmessage ListListUser {\n  repeated ListUser value = 1;\n}\n\n//@WrapProperty\nmessage ListMapUser {\n  repeated MapUser value = 1;\n}\n\n//@WrapProperty\nmessage MapListUser {\n  map<string, ListUser> value = 1;\n}\n\n//@WrapProperty\nmessage MapMapUser {\n  map<string, MapUser> value = 1;\n}\n\n//@WrapProperty\nmessage ListListString {\n  repeated ListString value = 1;\n}\n\n//@WrapProperty\nmessage ListMapString {\n  repeated MapString value = 1;\n}\n\n//@WrapProperty\nmessage ListString {\n  repeated string value = 1;\n}\n\n//@WrapProperty\nmessage MapListString {\n  map<string, ListString> value = 1;\n}\n\n//@WrapProperty\nmessage MapMapString {\n  map<string, MapString> value = 1;\n}\n\n//@WrapProperty\nmessage MapString {\n  map<string, string> value = 1;\n}\n\nenum Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 {\n  RED = 0;\n  YELLOW = 1;\n  BLUE = 2;\n}\n\nservice MainService {\n  //@Rpc{\"argTypeName\":\"BaseRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"BaseResponseWrap200\"},\"444\":{\"typeName\":\"BaseResponseWrap444\"}}}\n  rpc base (BaseRequestWrap) returns (BaseResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"BytesRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"BytesResponseWrap200\"}}}\n  rpc bytes (BytesRequestWrap) returns (BytesResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ColorBodyRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ColorBodyResponseWrap200\"}}}\n  rpc colorBody (ColorBodyRequestWrap) returns (ColorBodyResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"FieldNeedWrap\",\"responses\":{\"200\":{\"typeName\":\"FieldNeedWrap\"}}}\n  rpc fieldNeedWrap (FieldNeedWrap) returns (FieldNeedWrap);\n\n  //@Rpc{\"argTypeName\":\"ListListListStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListListListStringResponseWrap200\"}}}\n  rpc listListListString (ListListListStringRequestWrap) returns (ListListListStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListListMapStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListListMapStringResponseWrap200\"}}}\n  rpc listListMapString (ListListMapStringRequestWrap) returns (ListListMapStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListListStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListListStringResponseWrap200\"}}}\n  rpc listListString (ListListStringRequestWrap) returns (ListListStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListListUserRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListListUserResponseWrap200\"}}}\n  rpc listListUser (ListListUserRequestWrap) returns (ListListUserResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListMapListStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListMapListStringResponseWrap200\"}}}\n  rpc listMapListString (ListMapListStringRequestWrap) returns (ListMapListStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListMapMapStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListMapMapStringResponseWrap200\"}}}\n  rpc listMapMapString (ListMapMapStringRequestWrap) returns (ListMapMapStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListMapStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListMapStringResponseWrap200\"}}}\n  rpc listMapString (ListMapStringRequestWrap) returns (ListMapStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListMapUserRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListMapUserResponseWrap200\"}}}\n  rpc listMapUser (ListMapUserRequestWrap) returns (ListMapUserResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListObjRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListObjResponseWrap200\"}}}\n  rpc listObj (ListObjRequestWrap) returns (ListObjResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"ListUserRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"ListUserResponseWrap200\"}}}\n  rpc listUser (ListUserRequestWrap) returns (ListUserResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapListStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapListStringResponseWrap200\"}}}\n  rpc mapListString (MapListStringRequestWrap) returns (MapListStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapListUserRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapListUserResponseWrap200\"}}}\n  rpc mapListUser (MapListUserRequestWrap) returns (MapListUserResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapMapListStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapMapListStringResponseWrap200\"}}}\n  rpc mapMapListString (MapMapListStringRequestWrap) returns (MapMapListStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapMapMapStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapMapMapStringResponseWrap200\"}}}\n  rpc mapMapMapString (MapMapMapStringRequestWrap) returns (MapMapMapStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapMapStringRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapMapStringResponseWrap200\"}}}\n  rpc mapMapString (MapMapStringRequestWrap) returns (MapMapStringResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapMapUserRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapMapUserResponseWrap200\"}}}\n  rpc mapMapUser (MapMapUserRequestWrap) returns (MapMapUserResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapObjRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapObjResponseWrap200\"}}}\n  rpc mapObj (MapObjRequestWrap) returns (MapObjResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"MapUserRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"MapUserResponseWrap200\"}}}\n  rpc mapUser (MapUserRequestWrap) returns (MapUserResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"google.protobuf.Empty\",\"responses\":{\"200\":{\"typeName\":\"google.protobuf.Empty\"}}}\n  rpc noParamVoid (google.protobuf.Empty) returns (google.protobuf.Empty);\n\n  //@Rpc{\"argTypeName\":\"google.protobuf.Any\",\"responses\":{\"200\":{\"typeName\":\"google.protobuf.Any\"}}}\n  rpc obj (google.protobuf.Any) returns (google.protobuf.Any);\n\n  //@Rpc{\"argTypeName\":\"Ref1\",\"responses\":{\"200\":{\"typeName\":\"Ref2\"}}}\n  rpc ref (Ref1) returns (Ref2);\n\n  //@Rpc{\"argTypeName\":\"TestTextPlainRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"TestTextPlainResponseWrap200\"}}}\n  rpc testTextPlain (TestTextPlainRequestWrap) returns (TestTextPlainResponseWrap200);\n\n  //@Rpc{\"argTypeName\":\"User\",\"responses\":{\"200\":{\"typeName\":\"User\"}}}\n  rpc user (User) returns (User);\n\n  //@Rpc{\"argTypeName\":\"UserWrapInProtobufRequestWrap\",\"responses\":{\"200\":{\"typeName\":\"User\"}}}\n  rpc userWrapInProtobuf (UserWrapInProtobufRequestWrap) returns (User);\n}\n"
  },
  {
    "path": "common/common-rest/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>common</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>common-rest</artifactId>\n  <name>Java Chassis::Common::Rest</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-protobuf</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/CommonRestConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodec;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecCsv;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecMulti;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecPipes;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecSsv;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecs;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecsUtils;\nimport org.apache.servicecomb.common.rest.filter.inner.RestServerCodecFilter;\nimport org.apache.servicecomb.common.rest.filter.inner.WebSocketServerCodecFilter;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class CommonRestConfiguration {\n  @Bean\n  public QueryCodecCsv scbQueryCodecCsv() {\n    return new QueryCodecCsv();\n  }\n\n  @Bean\n  public QueryCodecSsv scbQueryCodecSsv() {\n    return new QueryCodecSsv();\n  }\n\n  @Bean\n  public QueryCodecPipes scbQueryCodecPipes() {\n    return new QueryCodecPipes();\n  }\n\n  @Bean\n  public QueryCodecMulti scbQueryCodecMulti() {\n    return new QueryCodecMulti();\n  }\n\n  @Bean\n  public QueryCodecsUtils scbQueryCodecsUtils(QueryCodecs queryCodecs) {\n    return new QueryCodecsUtils(queryCodecs);\n  }\n\n  @Bean\n  public RestServerCodecFilter scbRestServerCodecFilter() {\n    return new RestServerCodecFilter();\n  }\n\n  @Bean\n  public WebSocketServerCodecFilter scbWebSocketServerCodecFilter() {\n    return new WebSocketServerCodecFilter();\n  }\n\n  @Bean\n  public QueryCodecs scbQueryCodecs(List<QueryCodec> orderedCodecs) {\n    return new QueryCodecs(orderedCodecs);\n  }\n\n  @Bean\n  public RestEngineSchemaListener scbRestEngineSchemaListener() {\n    return new RestEngineSchemaListener();\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/EdgeServerWebSocketInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\n\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class EdgeServerWebSocketInvocationCreator extends ProviderServerWebSocketInvocationCreator {\n  private final String microserviceName;\n\n  protected MicroserviceReferenceConfig microserviceReferenceConfig;\n\n  protected final String path;\n\n  public EdgeServerWebSocketInvocationCreator(String microserviceName, String path,\n      Endpoint endpoint, ServerWebSocket webSocket) {\n    super(null, endpoint, webSocket);\n    this.microserviceName = microserviceName;\n    this.path = path;\n  }\n\n  @Override\n  public CompletableFuture<Invocation> createAsync() {\n    return createMicroserviceReferenceConfig()\n        .thenCompose(v -> super.createAsync());\n  }\n\n  protected CompletableFuture<Void> createMicroserviceReferenceConfig() {\n    return SCBEngine.getInstance()\n        .getOrCreateReferenceConfigAsync(microserviceName)\n        .thenAccept(mrc -> {\n          this.microserviceReferenceConfig = mrc;\n          this.microserviceMeta = mrc.getMicroserviceMeta();\n        });\n  }\n\n  @Override\n  protected OperationLocator locateOperation(ServicePathManager servicePathManager) {\n    return servicePathManager.consumerLocateOperation(path, HttpMethod.POST.name());\n  }\n\n  @Override\n  protected Invocation createInstance() {\n    ReferenceConfig referenceConfig = microserviceReferenceConfig\n        .createReferenceConfig(restOperationMeta.getOperationMeta());\n\n    Invocation invocation = InvocationFactory.forConsumer(referenceConfig,\n        restOperationMeta.getOperationMeta(),\n        restOperationMeta.getOperationMeta().buildBaseConsumerRuntimeType(),\n        null);\n    invocation.setSync(false);\n    invocation.setEdge();\n    invocation.setEndpoint(endpoint); // ensure transport name is correct\n\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/HttpTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.swagger.invocation.context.TransportContext;\n\npublic class HttpTransportContext implements TransportContext {\n  private final HttpServletRequestEx requestEx;\n\n  private final HttpServletResponseEx responseEx;\n\n  public HttpTransportContext(HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {\n    this.requestEx = requestEx;\n    this.responseEx = responseEx;\n  }\n\n  public HttpServletRequestEx getRequestEx() {\n    return requestEx;\n  }\n\n  public HttpServletResponseEx getResponseEx() {\n    return responseEx;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/ProviderServerWebSocketInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\n\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class ProviderServerWebSocketInvocationCreator extends ServerWebSocketInvocationCreator {\n  public ProviderServerWebSocketInvocationCreator(MicroserviceMeta microserviceMeta,\n      Endpoint endpoint, ServerWebSocket webSocket) {\n    super(microserviceMeta, endpoint, webSocket);\n  }\n\n  @Override\n  protected void initTransportContext(Invocation invocation) {\n    WebSocketTransportContext transportContext = new WebSocketTransportContext(websocket);\n    invocation.setTransportContext(transportContext);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.commons.lang3.SystemUtils;\n\npublic final class RestConst {\n  private RestConst() {\n  }\n\n  public static final String REST_CLIENT_REQUEST_PATH = \"rest-client-request-path\";\n\n  public static final String SWAGGER_REST_OPERATION = \"swaggerRestOperation\";\n\n  public static final String REST = \"rest\";\n\n  public static final String SCHEME = \"cse\";\n\n  public static final String SCHEME_NEW = \"servicecomb\";\n\n  public static final String URI_PREFIX = SCHEME + \"://\";\n\n  public static final String URI_PREFIX_NEW = SCHEME_NEW + \"://\";\n\n  // in HttpServletRequest attribute\n  public static final String PATH_PARAMETERS = \"servicecomb-paths\";\n\n  // in HttpServletRequest attribute\n  public static final String BODY_PARAMETER = \"servicecomb-body\";\n\n  //in invocation response\n  public static final String INVOCATION_HANDLER_RESPONSE = \"servicecomb-invocation-handler-response\";\n\n  //in invocation response\n  public static final String INVOCATION_HANDLER_PROCESSOR = \"servicecomb-invocation-handler-processor\";\n\n  //in invocation response\n  public static final String INVOCATION_HANDLER_REQUESTCLIENT = \"servicecomb-invocation-handler-requestclient\";\n\n  public static final String REST_PRODUCER_INVOCATION = \"servicecomb-rest-producer-invocation\";\n\n  public static final String REST_INVOCATION_CONTEXT = \"servicecomb-rest-invocation-context\";\n\n  public static final String REST_REQUEST = \"servicecomb-rest-request\";\n\n  public static final String CONSUMER_HEADER = \"servicecomb-rest-consumer-header\";\n\n  public static final String READ_STREAM_PART = \"servicecomb-readStreamPart\";\n\n  public static final String UPLOAD_DIR = \"servicecomb.uploads.directory\";\n\n  public static final String UPLOAD_DEFAULT_DIR = SystemUtils.JAVA_IO_TMPDIR;\n\n  // limit of one upload file, only available for servlet rest transport\n  public static final String UPLOAD_MAX_FILE_SIZE = \"servicecomb.uploads.maxFileSize\";\n\n  // limit of upload request body\n  public static final String UPLOAD_MAX_SIZE = \"servicecomb.uploads.maxSize\";\n\n  // the size threshold after which files will be written to disk\n  // only available for servlet rest transport\n  public static final String UPLOAD_FILE_SIZE_THRESHOLD = \"servicecomb.uploads.fileSizeThreshold\";\n\n  public static final String PROVIDER_SCAN_REST_CONTROLLER = \"servicecomb.provider.rest.scanRestController\";\n\n  public static final String PRINT_CODEC_ERROR_MESSGAGE = \"servicecomb.codec.printErrorMessage\";\n\n  public static final String HEADER_CONTEXT_MAPPER = \"servicecomb.context.headerContextMapper\";\n\n  public static final String QUERY_CONTEXT_MAPPER = \"servicecomb.context.queryContextMapper\";\n\n  public static final String DECODE_INVOCATION_CONTEXT = \"servicecomb.context.decodeInvocationContext\";\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestEngineSchemaListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine.CreateMicroserviceMetaEvent;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.foundation.common.event.EnableExceptionPropagation;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic class RestEngineSchemaListener implements BootListener {\n  @Override\n  public int getOrder() {\n    return -10000;\n  }\n\n  @Override\n  public void onBeforeRegistry(BootEvent event) {\n    createServicePathManager(event.getScbEngine().getProducerMicroserviceMeta())\n        .buildProducerPaths();\n    event.getScbEngine().getEventBus().register(this);\n  }\n\n  @EnableExceptionPropagation\n  @Subscribe\n  public void onCreateMicroserviceMetaEvent(CreateMicroserviceMetaEvent event) {\n    MicroserviceMeta microserviceMeta = event.getMicroserviceMeta();\n    createServicePathManager(microserviceMeta);\n  }\n\n  private ServicePathManager createServicePathManager(MicroserviceMeta microserviceMeta) {\n    // already connect ServicePathManager and MicroserviceMeta instance\n    // no need to save ServicePathManager instance again\n    return new ServicePathManager(microserviceMeta);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport static jakarta.ws.rs.core.Response.Status.NOT_FOUND;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.NOT_DEFINED_ANY_SCHEMA;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.config.YAMLUtil;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.json.Json;\n\npublic abstract class RestProducerInvocationCreator implements InvocationCreator {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestVertxProducerInvocationCreator.class);\n\n  protected MicroserviceMeta microserviceMeta;\n\n  protected final Endpoint endpoint;\n\n  protected final HttpServletRequestEx requestEx;\n\n  protected final HttpServletResponseEx responseEx;\n\n  protected RestOperationMeta restOperationMeta;\n\n  protected ProduceProcessor produceProcessor;\n\n  public RestProducerInvocationCreator(MicroserviceMeta microserviceMeta, Endpoint endpoint,\n      HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {\n    this.microserviceMeta = microserviceMeta;\n    this.endpoint = endpoint;\n    this.requestEx = requestEx;\n    this.responseEx = responseEx;\n  }\n\n  @Override\n  public CompletableFuture<Invocation> createAsync() {\n    initRestOperation();\n\n    Invocation invocation = createInstance();\n    initInvocationContext(invocation);\n    addParameterContext(invocation);\n    initTransportContext(invocation);\n\n    invocation.addLocalContext(RestConst.REST_REQUEST, requestEx);\n\n    return CompletableFuture.completedFuture(invocation);\n  }\n\n  protected Invocation createInstance() {\n    return InvocationFactory.forProvider(endpoint, restOperationMeta.getOperationMeta(), null);\n  }\n\n  protected void initInvocationContext(Invocation invocation) {\n    if (!LegacyPropertyFactory.getBooleanProperty(RestConst.DECODE_INVOCATION_CONTEXT, true)) {\n      return;\n    }\n\n    String strCseContext = requestEx.getHeader(CoreConst.CSE_CONTEXT);\n    if (StringUtils.isEmpty(strCseContext)) {\n      return;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    Map<String, String> invocationContext = Json.decodeValue(strCseContext, Map.class);\n    invocation.mergeContext(invocationContext);\n  }\n\n  protected void addParameterContext(Invocation invocation) {\n    String headerContextMapper = LegacyPropertyFactory\n        .getStringProperty(RestConst.HEADER_CONTEXT_MAPPER);\n    String queryContextMapper = LegacyPropertyFactory\n        .getStringProperty(RestConst.QUERY_CONTEXT_MAPPER);\n\n    Map<String, Object> headerContextMappers;\n    if (headerContextMapper != null) {\n      headerContextMappers = YAMLUtil.yaml2Properties(headerContextMapper);\n    } else {\n      headerContextMappers = new HashMap<>();\n    }\n\n    Map<String, Object> queryContextMappers;\n    if (queryContextMapper != null) {\n      queryContextMappers = YAMLUtil.yaml2Properties(queryContextMapper);\n    } else {\n      queryContextMappers = new HashMap<>();\n    }\n\n    headerContextMappers.forEach((k, v) -> {\n      if (v instanceof String && requestEx.getHeader(k) != null) {\n        invocation.addContext((String) v, requestEx.getHeader(k));\n      }\n    });\n    queryContextMappers.forEach((k, v) -> {\n      if (v instanceof String && requestEx.getParameter(k) != null) {\n        invocation.addContext((String) v, requestEx.getParameter(k));\n      }\n    });\n  }\n\n  protected abstract void initTransportContext(Invocation invocation);\n\n  protected void initRestOperation() {\n    OperationLocator locator = locateOperation(microserviceMeta);\n    requestEx.setAttribute(RestConst.PATH_PARAMETERS, locator.getPathVarMap());\n    restOperationMeta = locator.getOperation();\n  }\n\n  protected OperationLocator locateOperation(MicroserviceMeta microserviceMeta) {\n    ServicePathManager servicePathManager = ServicePathManager.getServicePathManager(microserviceMeta);\n    if (servicePathManager == null) {\n      LOGGER.error(\"No schema defined for {}:{}.\", this.microserviceMeta.getAppId(),\n          this.microserviceMeta.getMicroserviceName());\n      throw Exceptions.create(NOT_FOUND, NOT_DEFINED_ANY_SCHEMA, NOT_FOUND.getReasonPhrase());\n    }\n\n    return locateOperation(servicePathManager);\n  }\n\n  protected OperationLocator locateOperation(ServicePathManager servicePathManager) {\n    return servicePathManager.producerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationFlow.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;\nimport org.apache.servicecomb.common.rest.filter.inner.RestServerCodecFilter;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.core.invocation.ProducerInvocationFlow;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class RestProducerInvocationFlow extends ProducerInvocationFlow {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestProducerInvocationFlow.class);\n\n  private static final ProduceProcessor DEFAULT_PRODUCE_PROCESSOR = ProduceProcessorManager.INSTANCE\n      .findDefaultProcessor();\n\n  public RestProducerInvocationFlow(InvocationCreator invocationCreator,\n      HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {\n    super(invocationCreator, requestEx, responseEx);\n  }\n\n  @Override\n  protected Invocation sendCreateInvocationException(Throwable throwable) {\n    try {\n      Response response = Exceptions.toProducerResponse(null, throwable);\n      RestServerCodecFilter.encodeResponse(null, response, DEFAULT_PRODUCE_PROCESSOR, responseEx);\n    } catch (Throwable e) {\n      LOGGER.error(\"Failed to send response when prepare invocation failed, request uri:{}\",\n          requestEx.getRequestURI(), e);\n    }\n\n    endResponse(null);\n    return null;\n  }\n\n  @Override\n  protected void endResponse(Invocation invocation, Response response) {\n    invocation.getInvocationStageTrace().startProviderSendResponse();\n\n    endResponse(invocation);\n  }\n\n  private void endResponse(Invocation invocation) {\n    try {\n      responseEx.endResponse();\n    } catch (Throwable flushException) {\n      LOGGER.error(\"Failed to flush rest response, operation:{}, request uri:{}\",\n          invocation == null ? \"NA\" :\n              invocation.getMicroserviceQualifiedName(), requestEx.getRequestURI(), flushException);\n    }\n\n    try {\n      requestEx.getAsyncContext().complete();\n    } catch (Throwable completeException) {\n      LOGGER.error(\"Failed to complete async rest response, operation:{}, request uri:{}\",\n          invocation == null ? \"NA\" :\n              invocation.getMicroserviceQualifiedName(), requestEx.getRequestURI(), completeException);\n    }\n\n    if (invocation != null) {\n      invocation.getInvocationStageTrace().finishProviderSendResponse();\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestVertxProducerInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RestVertxProducerInvocationCreator extends RestProducerInvocationCreator {\n  private final RoutingContext routingContext;\n\n  public RestVertxProducerInvocationCreator(RoutingContext routingContext,\n      MicroserviceMeta microserviceMeta, Endpoint endpoint,\n      HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {\n    super(microserviceMeta, endpoint, requestEx, responseEx);\n    this.routingContext = routingContext;\n  }\n\n  @Override\n  protected void initTransportContext(Invocation invocation) {\n    VertxHttpTransportContext transportContext = new VertxHttpTransportContext(routingContext, requestEx, responseEx);\n    invocation.setTransportContext(transportContext);\n    routingContext.put(RestConst.REST_INVOCATION_CONTEXT, invocation);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/ServerWebSocketInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport static jakarta.ws.rs.core.Response.Status.NOT_FOUND;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.NOT_DEFINED_ANY_SCHEMA;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.config.YAMLUtil;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.ServerWebSocket;\nimport io.vertx.core.json.Json;\n\npublic abstract class ServerWebSocketInvocationCreator implements InvocationCreator {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestVertxProducerInvocationCreator.class);\n\n  protected MicroserviceMeta microserviceMeta;\n\n  protected final Endpoint endpoint;\n\n  protected final ServerWebSocket websocket;\n\n  protected RestOperationMeta restOperationMeta;\n\n  public ServerWebSocketInvocationCreator(MicroserviceMeta microserviceMeta, Endpoint endpoint,\n      ServerWebSocket websocket) {\n    this.microserviceMeta = microserviceMeta;\n    this.endpoint = endpoint;\n    this.websocket = websocket;\n  }\n\n  @Override\n  public CompletableFuture<Invocation> createAsync() {\n    initRestOperation();\n\n    Invocation invocation = createInstance();\n    initInvocationContext(invocation);\n    addParameterContext(invocation);\n    initTransportContext(invocation);\n\n    return CompletableFuture.completedFuture(invocation);\n  }\n\n  protected Invocation createInstance() {\n    return InvocationFactory.forProvider(endpoint, restOperationMeta.getOperationMeta(), null);\n  }\n\n  protected void initInvocationContext(Invocation invocation) {\n    if (!LegacyPropertyFactory.getBooleanProperty(RestConst.DECODE_INVOCATION_CONTEXT, true)) {\n      return;\n    }\n\n    String strCseContext = websocket.headers().get(CoreConst.CSE_CONTEXT);\n    if (StringUtils.isEmpty(strCseContext)) {\n      return;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    Map<String, String> invocationContext = Json.decodeValue(strCseContext, Map.class);\n    invocation.mergeContext(invocationContext);\n  }\n\n  // No queries for websocket\n  protected void addParameterContext(Invocation invocation) {\n    String headerContextMapper = LegacyPropertyFactory\n        .getStringProperty(RestConst.HEADER_CONTEXT_MAPPER);\n\n    Map<String, Object> headerContextMappers;\n    if (headerContextMapper != null) {\n      headerContextMappers = YAMLUtil.yaml2Properties(headerContextMapper);\n    } else {\n      headerContextMappers = new HashMap<>();\n    }\n\n    headerContextMappers.forEach((k, v) -> {\n      if (v instanceof String && websocket.headers().get(k) != null) {\n        invocation.addContext((String) v, websocket.headers().get(k));\n      }\n    });\n  }\n\n  protected abstract void initTransportContext(Invocation invocation);\n\n  protected void initRestOperation() {\n    OperationLocator locator = locateOperation(microserviceMeta);\n    restOperationMeta = locator.getOperation();\n  }\n\n  protected OperationLocator locateOperation(MicroserviceMeta microserviceMeta) {\n    ServicePathManager servicePathManager = ServicePathManager.getServicePathManager(microserviceMeta);\n    if (servicePathManager == null) {\n      LOGGER.error(\"No schema defined for {}:{}.\", this.microserviceMeta.getAppId(),\n          this.microserviceMeta.getMicroserviceName());\n      throw Exceptions.create(NOT_FOUND, NOT_DEFINED_ANY_SCHEMA, NOT_FOUND.getReasonPhrase());\n    }\n\n    return locateOperation(servicePathManager);\n  }\n\n  protected OperationLocator locateOperation(ServicePathManager servicePathManager) {\n    return servicePathManager.producerLocateOperation(websocket.path(), HttpMethod.POST.name());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/UploadConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport org.springframework.core.env.Environment;\n\nimport jakarta.servlet.MultipartConfigElement;\n\npublic class UploadConfig {\n  private final Environment environment;\n\n  public UploadConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  /**\n   * null means not support upload\n   */\n  public String getLocation() {\n    return environment.getProperty(RestConst.UPLOAD_DIR, RestConst.UPLOAD_DEFAULT_DIR);\n  }\n\n  /**\n   * limit of one upload file, only available for servlet rest transport\n   */\n  public long getMaxFileSize() {\n    return environment.getProperty(RestConst.UPLOAD_MAX_FILE_SIZE, long.class, -1L);\n  }\n\n  /**\n   * limit of upload request body\n   */\n  public long getMaxSize() {\n    return environment.getProperty(RestConst.UPLOAD_MAX_SIZE, long.class, -1L);\n  }\n\n\n  /**\n   * the size threshold after which files will be written to disk, only available for servlet rest transport\n   */\n  public int getFileSizeThreshold() {\n    return environment.getProperty(RestConst.UPLOAD_FILE_SIZE_THRESHOLD, int.class, 0);\n  }\n\n  public MultipartConfigElement toMultipartConfigElement() {\n    return new MultipartConfigElement(\n        getLocation(),\n        getMaxFileSize(),\n        getMaxSize(),\n        getFileSizeThreshold());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/VertxHttpTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.swagger.invocation.context.VertxTransportContext;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class VertxHttpTransportContext extends HttpTransportContext implements VertxTransportContext {\n  private final RoutingContext routingContext;\n\n  private final Context vertxContext;\n\n  public VertxHttpTransportContext(RoutingContext routingContext, HttpServletRequestEx requestEx,\n      HttpServletResponseEx responseEx) {\n    super(requestEx, responseEx);\n\n    this.routingContext = routingContext;\n    this.vertxContext = Vertx.currentContext();\n  }\n\n  public RoutingContext getRoutingContext() {\n    return routingContext;\n  }\n\n  @Override\n  public Context getVertxContext() {\n    return vertxContext;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/WebSocketTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.swagger.invocation.context.TransportContext;\n\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class WebSocketTransportContext implements TransportContext {\n  private final ServerWebSocket serverWebSocket;\n\n  public WebSocketTransportContext(ServerWebSocket serverWebSocket) {\n    this.serverWebSocket = serverWebSocket;\n  }\n\n  public ServerWebSocket getServerWebSocket() {\n    return this.serverWebSocket;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestClientRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\n\n/**\n * vertx的HttpClientRequest没有getHeader的能力\n * 在写cookie参数时，没办法多次添加cookie，所以只能进行接口包装\n */\npublic interface RestClientRequest {\n  void write(Buffer bodyBuffer);\n\n  Future<Void> end();\n\n  void addCookie(String name, String value);\n\n  void putHeader(String name, String value);\n\n  MultiMap getHeaders();\n\n  void addForm(String name, Object value);\n\n  Buffer getBodyBuffer() throws Exception;\n\n  void attach(String name, Object partOrList);\n\n  HttpClientRequest getHttpClientRequest();\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic final class RestCodec {\n  private RestCodec() {\n  }\n\n  public static void argsToRest(Map<String, Object> args, RestOperationMeta restOperation,\n      RestClientRequest clientRequest) throws Exception {\n    int paramSize = restOperation.getParamList().size();\n    if (paramSize == 0) {\n      return;\n    }\n\n    for (int idx = 0; idx < paramSize; idx++) {\n      RestParam param = restOperation.getParamList().get(idx);\n      param.getParamProcessor().setValue(clientRequest, args.get(param.getParamName()));\n    }\n  }\n\n  public static Map<String, Object> restToArgs(HttpServletRequest request,\n      RestOperationMeta restOperation) throws InvocationException {\n    List<RestParam> paramList = restOperation.getParamList();\n\n    Map<String, Object> paramValues = new HashMap<>();\n    for (RestParam param : paramList) {\n      try {\n        paramValues.put(param.getParamName(), param.getParamProcessor().getValue(request));\n      } catch (Exception e) {\n        String message = String\n            .format(\"Parameter is not valid for operation [%s]. Parameter is [%s]. Processor is [%s]. Message is [%s].\",\n                restOperation.getOperationMeta().getMicroserviceQualifiedName(),\n                param.getParamName(),\n                param.getParamProcessor().getProcessorType(),\n                e.getMessage());\n        throw new InvocationException(Status.BAD_REQUEST, new CommonExceptionData(message), e);\n      }\n    }\n\n    return paramValues;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.utils.AbstractRestObjectMapper;\nimport org.apache.servicecomb.foundation.common.utils.RestObjectMapper;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\nimport com.fasterxml.jackson.databind.Module;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\n/**\n * Manage RestObjectMapper instances. Give users an option to specify custom mappers.\n */\npublic class RestObjectMapperFactory {\n  private static AbstractRestObjectMapper defaultMapper = new RestObjectMapper();\n\n  private static final AbstractRestObjectMapper viewMapper = new RestObjectMapper();\n\n  private static AbstractRestObjectMapper consumerWriterMapper = defaultMapper;\n\n  static {\n    registerModules(defaultMapper);\n    registerModules(viewMapper);\n  }\n\n  private static void registerModules(ObjectMapper mapper) {\n    // not use mapper.findAndRegisterModules()\n    // because we need to sort modules, so that customers can override our default module\n    List<Module> modules = SPIServiceUtils.getOrLoadSortedService(Module.class);\n    mapper.registerModules(modules.toArray(new Module[0]));\n  }\n\n  public static AbstractRestObjectMapper getConsumerWriterMapper() {\n    return consumerWriterMapper;\n  }\n\n  public static AbstractRestObjectMapper getRestObjectMapper() {\n    return defaultMapper;\n  }\n\n  public static AbstractRestObjectMapper getRestViewMapper() {\n    return viewMapper;\n  }\n\n  public static void setConsumerWriterMapper(AbstractRestObjectMapper customMapper) {\n    registerModules(customMapper);\n    consumerWriterMapper = customMapper;\n  }\n\n  public static void setDefaultRestObjectMapper(AbstractRestObjectMapper customMapper) {\n    registerModules(customMapper);\n    defaultMapper = customMapper;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.HeaderProcessorCreator.HeaderProcessor;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic interface HeaderCodec {\n  static String encodeValue(Object value) throws UnsupportedEncodingException {\n    return URLEncoder.encode(value.toString(), StandardCharsets.UTF_8.name());\n  }\n\n  // can not be replaced by value.toString() because of date serialize\n  static String convertToString(Object value) throws Exception {\n    return RestObjectMapperFactory.getRestObjectMapper().convertToString(value);\n  }\n\n  String getCodecName();\n\n  void encode(RestClientRequest clientRequest, String name, Object value) throws Exception;\n\n  Object decode(HeaderProcessor processor, HttpServletRequest request);\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecCsv.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\npublic class HeaderCodecCsv extends HeaderCodecWithDelimiter {\n  public static final String CODEC_NAME = \"form:0\";\n\n  public static final String DELIMITER = \",\";\n\n  public HeaderCodecCsv() {\n    super(CODEC_NAME, DELIMITER, DELIMITER);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecMulti.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.HeaderProcessorCreator.HeaderProcessor;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class HeaderCodecMulti implements HeaderCodec {\n  public static final String NAME = \"form:1\";\n\n  @Override\n  public String getCodecName() {\n    return NAME;\n  }\n\n  @Override\n  public void encode(RestClientRequest clientRequest, String name, Object value) throws Exception {\n    if (null == value) {\n      // if value is empty, header should not be set to clientRequest to avoid NullPointerException in Netty.\n      return;\n    }\n    if (!(value instanceof Collection<?>)) {\n      throw new InvocationException(Status.BAD_REQUEST,\n          new CommonExceptionData(\"Array type of header should be Collection\"));\n    }\n    for (Object item : ((Collection<?>) value)) {\n      clientRequest.putHeader(name,\n          RestObjectMapperFactory.getConsumerWriterMapper().convertToString(item));\n    }\n  }\n\n  @Override\n  public Object decode(HeaderProcessor processor, HttpServletRequest request) {\n    Enumeration<String> headerValues = request.getHeaders(processor.getParameterPath());\n    if (headerValues == null) {\n      //Even if the paramPath does not exist, headerValues won't be null at now\n      return null;\n    }\n    return processor.convertValue(Collections.list(headerValues), processor.getTargetType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecPipes.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\npublic class HeaderCodecPipes extends HeaderCodecWithDelimiter {\n  public static final String CODEC_NAME = \"pipeDelimited:0\";\n\n  public static final String JOIN_DELIMITER = \"|\";\n\n  public static final String SPLIT_DELIMITER = \"\\\\|\";\n\n  public HeaderCodecPipes() {\n    super(CODEC_NAME, JOIN_DELIMITER, SPLIT_DELIMITER);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecSimple.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.HeaderProcessorCreator.HeaderProcessor;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic class HeaderCodecSimple implements HeaderCodec {\n  public static final String NAME = \"simple\";\n\n  @Override\n  public String getCodecName() {\n    return NAME;\n  }\n\n  @Override\n  public void encode(RestClientRequest clientRequest, String name, Object value) throws Exception {\n    if (null == value) {\n      // if value is empty, header should not be set to clientRequest to avoid NullPointerException in Netty.\n      return;\n    }\n    clientRequest.putHeader(name,\n        RestObjectMapperFactory.getConsumerWriterMapper().convertToString(value));\n  }\n\n  @Override\n  public Object decode(HeaderProcessor processor, HttpServletRequest request) {\n    Object value = request.getHeader(processor.getParameterPath());\n    if (value == null) {\n      value = processor.checkRequiredAndDefaultValue();\n    }\n    return processor.convertValue(value, processor.getTargetType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecSsv.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\npublic class HeaderCodecSsv extends HeaderCodecWithDelimiter {\n  public static final String CODEC_NAME = \"spaceDelimited:0\";\n\n  public static final String DELIMITER = \" \";\n\n  public HeaderCodecSsv() {\n    super(CODEC_NAME, DELIMITER, DELIMITER);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecWithDelimiter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.StringJoiner;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.HeaderProcessorCreator.HeaderProcessor;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic abstract class HeaderCodecWithDelimiter implements HeaderCodec {\n  private final String name;\n\n  private final String joinDelimiter;\n\n  private final String splitDelimiter;\n\n  public HeaderCodecWithDelimiter(String name, String joinDelimiter, String splitDelimiter) {\n    this.name = name;\n    this.joinDelimiter = joinDelimiter;\n    this.splitDelimiter = splitDelimiter;\n  }\n\n\n  @Override\n  public String getCodecName() {\n    return name;\n  }\n\n  @Override\n  public void encode(RestClientRequest clientRequest, String name, Object value) throws Exception {\n    if (null == value) {\n      // if value is empty, header should not be set to clientRequest to avoid NullPointerException in Netty.\n      return;\n    }\n    if (!(value instanceof Collection<?>)) {\n      throw new InvocationException(Status.BAD_REQUEST,\n          new CommonExceptionData(\"Array type of header should be Collection\"));\n    }\n    clientRequest.putHeader(name, join((Collection<?>) value));\n  }\n\n  protected String join(Collection<?> values) throws Exception {\n    StringJoiner joiner = new StringJoiner(joinDelimiter);\n    for (Object value : values) {\n      String strValue = RestObjectMapperFactory.getConsumerWriterMapper().convertToString(value);\n      joiner.add(strValue);\n    }\n\n    return joiner.toString();\n  }\n\n  @Override\n  public Object decode(HeaderProcessor processor, HttpServletRequest request) {\n    String headerValues = request.getHeader(processor.getParameterPath());\n    if (headerValues == null) {\n      headerValues = (String) processor.checkRequiredAndDefaultValue();\n    }\n\n    return processor.convertValue(List.of(headerValues.split(splitDelimiter)), processor.getTargetType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/header/HeaderCodecsUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.header;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.Parameter.StyleEnum;\n\npublic class HeaderCodecsUtils {\n  private static final Map<String, HeaderCodec> CODECS;\n\n  static {\n    CODECS = new HashMap<>();\n    CODECS.put(HeaderCodecSimple.NAME, new HeaderCodecSimple());\n    CODECS.put(HeaderCodecMulti.NAME, new HeaderCodecMulti());\n    CODECS.put(HeaderCodecCsv.CODEC_NAME, new HeaderCodecCsv());\n    CODECS.put(HeaderCodecPipes.CODEC_NAME, new HeaderCodecPipes());\n    CODECS.put(HeaderCodecSsv.CODEC_NAME, new HeaderCodecSsv());\n  }\n\n  private HeaderCodecsUtils() {\n  }\n\n  public static HeaderCodec find(Parameter.StyleEnum styleEnum, Boolean explode) {\n    return CODECS.get(formatName(styleEnum, explode));\n  }\n\n  private static String formatName(StyleEnum styleEnum, Boolean explode) {\n    if (styleEnum == null) {\n      return HeaderCodecSimple.NAME;\n    }\n    return styleEnum + \":\" +\n        (explode != null && explode ? \"1\" : \"0\");\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/AbstractParamProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.google.common.base.Defaults;\n\npublic abstract class AbstractParamProcessor implements ParamValueProcessor {\n  protected String paramPath;\n\n  // for consumer, targetType should be null\n  protected JavaType targetType;\n\n  protected Object defaultValue;\n\n  protected boolean required = false;\n\n  public Object getDefaultValue() {\n    return defaultValue;\n  }\n\n  public AbstractParamProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {\n    this.paramPath = paramPath;\n    this.targetType = targetType;\n    this.defaultValue = defaultValue;\n    this.required = required;\n    if (defaultValue == null &&\n        targetType != null && targetType.getRawClass().isPrimitive()) {\n      this.defaultValue = Defaults.defaultValue(targetType.getRawClass());\n    }\n  }\n\n  @Override\n  public String getParameterPath() {\n    return paramPath;\n  }\n\n  public JavaType getTargetType() {\n    return targetType;\n  }\n\n  public boolean isRequired() {\n    return required;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Type;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.http.entity.ContentType;\nimport org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectReader;\nimport com.fasterxml.jackson.databind.exc.MismatchedInputException;\nimport com.fasterxml.jackson.databind.type.SimpleType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.buffer.impl.BufferImpl;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class BodyProcessorCreator implements ParamValueProcessorCreator<RequestBody> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(BodyProcessorCreator.class);\n\n  public static final String REQUEST_BODY_NAME = \"X_REQUEST\";\n\n  public static final String EXT_ID = \"protobuf\";\n\n  public static final String PARAM_TYPE = \"body\";\n\n  private static final JavaType OBJECT_TYPE = SimpleType.constructUnsafe(Object.class);\n\n  private static final Object LOCK = new Object();\n\n  // This configuration is used for temporary use only.\n  // Do not use it if you are sure how it works. And may be deleted in the future.\n  public static final String PARAM_DECODE_AS_OBJECT = \"servicecomb.rest.parameter.decodeAsObject\";\n\n  public static final String PARAM_DEFAULT_REQUEST_ENCODING = \"servicecomb.rest.parameter.default-request-encoding\";\n\n  private static Boolean decodeAsObject;\n\n  private static String defaultRequestEncoding;\n\n  public static class BodyProcessor implements ParamValueProcessor {\n    // Producer target type. For consumer, is null.\n    protected JavaType targetType;\n\n    protected Class<?> serialViewClass;\n\n    protected boolean isRequired;\n\n    protected OpenAPI openAPI;\n\n    protected ScopedProtobufSchemaManager scopedProtobufSchemaManager;\n\n    protected List<String> supportedContentTypes = new ArrayList<>();\n\n    protected OperationMeta operationMeta;\n\n    protected RequestBody requestBody;\n\n    public BodyProcessor(OperationMeta operationMeta, JavaType targetType, RequestBody requestBody) {\n      this.requestBody = requestBody;\n      if (!StringUtils.isEmpty((String) this.requestBody.getExtensions()\n          .get(SwaggerConst.EXT_JSON_VIEW))) {\n        try {\n          this.serialViewClass = Class.forName((String) this.requestBody.getExtensions()\n              .get(SwaggerConst.EXT_JSON_VIEW));\n        } catch (Throwable e) {\n          //ignore\n          LOGGER.warn(\"Failed to create body processor {}, annotation @JsonView may be invalid\", serialViewClass, e);\n        }\n      }\n\n      this.targetType = targetType;\n      this.isRequired = this.requestBody.getRequired() != null && this.requestBody.getRequired();\n      if (this.requestBody.getContent() != null) {\n        supportedContentTypes.addAll(this.requestBody.getContent().keySet());\n      }\n\n      if (operationMeta != null) {\n        this.operationMeta = operationMeta;\n        this.openAPI = operationMeta.getSchemaMeta().getSwagger();\n        if (supportedContentTypes.contains(SwaggerConst.PROTOBUF_TYPE)) {\n          this.scopedProtobufSchemaManager = getOrCreateScopedProtobufSchemaManager(\n              operationMeta.getMicroserviceMeta());\n        }\n      }\n    }\n\n    private ScopedProtobufSchemaManager getOrCreateScopedProtobufSchemaManager(MicroserviceMeta microserviceMeta) {\n      ScopedProtobufSchemaManager scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);\n      if (scopedProtobufSchemaManager == null) {\n        synchronized (LOCK) {\n          scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);\n          if (scopedProtobufSchemaManager == null) {\n            scopedProtobufSchemaManager = new ScopedProtobufSchemaManager();\n            microserviceMeta.putExtData(EXT_ID, scopedProtobufSchemaManager);\n          }\n        }\n      }\n      return scopedProtobufSchemaManager;\n    }\n\n    @Override\n    public Class<?> getSerialViewClass() {\n      return serialViewClass;\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) throws Exception {\n      Object result = getValueImpl(request);\n      if (result == null && this.isRequired) {\n        throw new InvocationException(Status.BAD_REQUEST, \"Body parameter is required.\");\n      }\n      return result;\n    }\n\n    private Object getValueImpl(HttpServletRequest request) throws IOException {\n      Object body = request.getAttribute(RestConst.BODY_PARAMETER);\n      if (body != null) {\n        return convertValue(body, targetType);\n      }\n\n      // edge support convert from form-data or x-www-form-urlencoded to json automatically\n      String contentType = validContentType(request.getContentType());\n\n      // support RFC 7231, ignore case for content-type\n      if (StringUtils.equalsIgnoreCase(contentType, MediaType.MULTIPART_FORM_DATA)\n          || StringUtils.equalsIgnoreCase(contentType, MediaType.APPLICATION_FORM_URLENCODED)) {\n        return convertValue(request.getParameterMap(), targetType);\n      }\n\n      // for standard HttpServletRequest, getInputStream will never return null\n      // but for mocked HttpServletRequest, maybe get a null\n      //  like org.apache.servicecomb.provider.springmvc.reference.ClientToHttpServletRequest\n      InputStream inputStream = request.getInputStream();\n      if (inputStream == null) {\n        return null;\n      }\n\n      if (StringUtils.equalsIgnoreCase(contentType, MediaType.APPLICATION_JSON)) {\n        try {\n          ObjectReader reader = serialViewClass != null\n              ? RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)\n              : RestObjectMapperFactory.getRestObjectMapper().reader();\n          if (decodeAsObject()) {\n            return reader.forType(OBJECT_TYPE).readValue(inputStream);\n          }\n          return reader.forType(targetType == null ? OBJECT_TYPE : targetType)\n              .readValue(inputStream);\n        } catch (MismatchedInputException e) {\n          // there is no way to detect InputStream is empty, so have to catch the exception\n          if (!isRequired && e.getMessage().contains(\"No content to map due to end-of-input\")) {\n            LOGGER.info(\"Empty content and required is false, taken as null\");\n            return null;\n          }\n          throw e;\n        }\n      }\n\n      if (StringUtils.equalsIgnoreCase(contentType, SwaggerConst.PROTOBUF_TYPE)) {\n        ProtoMapper protoMapper = scopedProtobufSchemaManager\n            .getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),\n                REQUEST_BODY_NAME,\n                requestBody.getContent().get(SwaggerConst.PROTOBUF_TYPE).getSchema());\n        RootDeserializer<PropertyWrapper<Object>> deserializer = protoMapper.getDeserializerSchemaManager()\n            .createRootDeserializer(protoMapper.getProto().getMessage(REQUEST_BODY_NAME),\n                targetType == null ? OBJECT_TYPE : targetType);\n        PropertyWrapper<Object> result = deserializer.deserialize(inputStream.readAllBytes());\n        return result.getValue();\n      }\n\n      if (StringUtils.equalsIgnoreCase(contentType, MediaType.TEXT_PLAIN)) {\n        try {\n          if (targetType != null && String.class.equals(targetType.getRawClass())) {\n            return IOUtils.toString(inputStream, StandardCharsets.UTF_8);\n          }\n          ObjectReader reader = serialViewClass != null\n              ? RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)\n              : RestObjectMapperFactory.getRestObjectMapper().reader();\n          if (decodeAsObject()) {\n            return reader.forType(OBJECT_TYPE).readValue(inputStream);\n          }\n          return reader.forType(targetType == null ? OBJECT_TYPE : targetType)\n              .readValue(inputStream);\n        } catch (MismatchedInputException e) {\n          // there is no way to detect InputStream is empty, so have to catch the exception\n          if (!isRequired && e.getMessage().contains(\"No content to map due to end-of-input\")) {\n            LOGGER.info(\"Empty content and required is false, taken as null\");\n            return null;\n          }\n          throw e;\n        }\n      }\n\n      throw new IllegalArgumentException(String.format(\"operation %s not support content-type %s\",\n          operationMeta.getSchemaQualifiedName(), contentType));\n    }\n\n    private String validContentType(String type) {\n      if (StringUtils.isEmpty(type)) {\n        if (supportedContentTypes.size() == 0) {\n          throw new IllegalArgumentException(\"operation do not have any content type support.\");\n        }\n        if (supportedContentTypes.contains(clientEncodingDefault())) {\n          return clientEncodingDefault();\n        }\n        return supportedContentTypes.get(0);\n      }\n      ContentType contentType = ContentType.parse(type);\n      return contentType.getMimeType();\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      String userContentType = clientRequest.getHeaders().get(HttpHeaders.CONTENT_TYPE);\n      String contentType = validContentType(userContentType);\n      if (StringUtils.isEmpty(userContentType)) {\n        clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, contentType);\n      }\n      if (arg != null) {\n        Buffer buffer = createBodyBuffer(contentType, arg);\n        clientRequest.write(buffer);\n      }\n    }\n\n    /**\n     * Serialize body object into body buffer, according to the Content-Type.\n     */\n    private Buffer createBodyBuffer(String contentType, Object arg) throws IOException {\n      if (MediaType.APPLICATION_JSON.equals(contentType)) {\n        try (BufferOutputStream output = new BufferOutputStream()) {\n          RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output, arg);\n          return output.getBuffer();\n        }\n      }\n\n      if (SwaggerConst.PROTOBUF_TYPE.equals(contentType)) {\n        ProtoMapper protoMapper = scopedProtobufSchemaManager\n            .getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),\n                REQUEST_BODY_NAME,\n                requestBody.getContent().get(SwaggerConst.PROTOBUF_TYPE).getSchema());\n        RootSerializer serializer = protoMapper.getSerializerSchemaManager()\n            .createRootSerializer(protoMapper.getProto().getMessage(REQUEST_BODY_NAME),\n                Object.class);\n        Map<String, Object> bodyArg = new HashMap<>(1);\n        bodyArg.put(\"value\", arg);\n        return new BufferImpl().appendBytes(serializer.serialize(bodyArg));\n      }\n\n      // For text/plain\n      try (BufferOutputStream output = new BufferOutputStream()) {\n        if (arg instanceof String) {\n          output.write(((String) arg).getBytes(StandardCharsets.UTF_8));\n        } else {\n          RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output, arg);\n        }\n        return output.getBuffer();\n      }\n    }\n\n    @Override\n    public String getParameterPath() {\n      return \"\";\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAM_TYPE;\n    }\n  }\n\n  public static class RawJsonBodyProcessor implements ParamValueProcessor {\n    protected JavaType targetType;\n\n    protected Class<?> serialViewClass;\n\n    protected boolean isRequired;\n\n    public RawJsonBodyProcessor(JavaType targetType, boolean isRequired) {\n      this(targetType, null, isRequired);\n    }\n\n    public RawJsonBodyProcessor(JavaType targetType, String serialViewClass, boolean isRequired) {\n      if (!StringUtils.isEmpty(serialViewClass)) {\n        try {\n          this.serialViewClass = Class.forName(serialViewClass);\n        } catch (Throwable e) {\n          //ignore\n          LOGGER.warn(\"Failed to create body processor {}, annotation @JsonView may be invalid\", serialViewClass, e);\n        }\n      }\n      this.targetType = targetType;\n      this.isRequired = isRequired;\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) throws Exception {\n      Object body = request.getAttribute(RestConst.BODY_PARAMETER);\n      if (body != null) {\n        return convertValue(body, targetType);\n      }\n\n      InputStream inputStream = request.getInputStream();\n      if (inputStream == null) {\n        return null;\n      }\n\n      return IOUtils.toString(inputStream, StandardCharsets.UTF_8);\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      if (arg instanceof String) {\n        clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);\n        clientRequest.write(Buffer.buffer((String) arg));\n        return;\n      }\n\n      throw new IllegalArgumentException(\"@RawJsonRequestBody only supports string type.\");\n    }\n\n    @Override\n    public String getParameterPath() {\n      return \"\";\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAM_TYPE;\n    }\n  }\n\n  public BodyProcessorCreator() {\n    ParamValueProcessorCreatorManager.INSTANCE.register(PARAM_TYPE, this);\n  }\n\n  @Override\n  public ParamValueProcessor create(OperationMeta operationMeta, String parameterName,\n      RequestBody parameter, Type genericParamType) {\n    JavaType targetType =\n        genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);\n    boolean rawJson = SwaggerUtils.isRawJsonType(parameter);\n    if (rawJson) {\n      return new RawJsonBodyProcessor(targetType, (String) parameter.getExtensions()\n          .get(SwaggerConst.EXT_JSON_VIEW),\n          parameter.getRequired() != null && parameter.getRequired());\n    }\n\n    return new BodyProcessor(operationMeta, targetType, parameter);\n  }\n\n  private static boolean decodeAsObject() {\n    if (decodeAsObject == null) {\n      decodeAsObject = LegacyPropertyFactory\n          .getBooleanProperty(PARAM_DECODE_AS_OBJECT, false);\n    }\n    return decodeAsObject;\n  }\n\n  private static String clientEncodingDefault() {\n    if (defaultRequestEncoding == null) {\n      defaultRequestEncoding = LegacyPropertyFactory\n          .getStringProperty(PARAM_DEFAULT_REQUEST_ENCODING, MediaType.APPLICATION_JSON);\n    }\n    return defaultRequestEncoding;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\nimport java.util.Objects;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class CookieProcessorCreator implements ParamValueProcessorCreator<Parameter> {\n  public static final String PARAMTYPE = \"cookie\";\n\n  public static class CookieProcessor extends AbstractParamProcessor {\n    public CookieProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {\n      super(paramPath, targetType, defaultValue, required);\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) {\n      Cookie[] cookies = request.getCookies();\n      Object value = null;\n      if (cookies == null || cookies.length == 0) {\n        value = checkRequiredAndDefaultValue();\n        return convertValue(value, targetType);\n      }\n\n      for (Cookie cookie : cookies) {\n        if (Objects.equals(paramPath, cookie.getName())) {\n          value = cookie.getValue();\n          break;\n        }\n      }\n      if (value == null) {\n        value = checkRequiredAndDefaultValue();\n      }\n      return convertValue(value, targetType);\n    }\n\n    private Object checkRequiredAndDefaultValue() {\n      if (isRequired()) {\n        throw new InvocationException(Status.BAD_REQUEST, \"Parameter is required.\");\n      }\n      return getDefaultValue();\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      clientRequest.addCookie(paramPath,\n          RestObjectMapperFactory.getConsumerWriterMapper().convertToString(arg));\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAMTYPE;\n    }\n  }\n\n  public CookieProcessorCreator() {\n    ParamValueProcessorCreatorManager.INSTANCE.register(PARAMTYPE, this);\n  }\n\n  @Override\n  public ParamValueProcessor create(OperationMeta operationMeta,\n      String parameterName, Parameter parameter, Type genericParamType) {\n    JavaType targetType =\n        genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);\n    return new CookieProcessor(parameterName, targetType, parameter.getSchema().getDefault(),\n        parameter.getRequired() != null && parameter.getRequired());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/FormProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.MediaType;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.Response.Status;\n\n@SuppressWarnings(\"unchecked\")\npublic class FormProcessorCreator implements ParamValueProcessorCreator<RequestBody> {\n  public static final String PARAMTYPE = \"formData\";\n\n  public static class FormProcessor extends AbstractParamProcessor {\n    private final boolean repeatedType;\n\n    public FormProcessor(String paraName, RequestBody formParameter, String mediaType, JavaType targetType) {\n      super(paraName, targetType,\n          formParameter.getContent().get(mediaType).getSchema().getDefault(),\n          formParameter.getRequired() != null && formParameter.getRequired());\n\n      this.repeatedType = formParameter.getContent().get(mediaType)\n          .getSchema().getProperties().get(paraName) instanceof ArraySchema;\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) {\n      Map<String, Object> forms = (Map<String, Object>) request.getAttribute(RestConst.BODY_PARAMETER);\n      if (forms != null && !forms.isEmpty()) {\n        return convertValue(forms.get(paramPath), targetType);\n      }\n\n      if (repeatedType) {\n        //Even if the paramPath does not exist, it won't be null at now\n        return convertValue(request.getParameterValues(paramPath), targetType);\n      }\n\n      Object value = request.getParameter(paramPath);\n      if (value == null) {\n        value = checkRequiredAndDefaultValue();\n      }\n      return convertValue(value, targetType);\n    }\n\n    private Object checkRequiredAndDefaultValue() {\n      if (isRequired()) {\n        throw new InvocationException(Status.BAD_REQUEST, \"Parameter is required.\");\n      }\n      return getDefaultValue();\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) {\n      clientRequest.addForm(paramPath, arg);\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAMTYPE;\n    }\n  }\n\n  public FormProcessorCreator() {\n    ParamValueProcessorCreatorManager.INSTANCE.register(PARAMTYPE, this);\n  }\n\n  @Override\n  public ParamValueProcessor create(OperationMeta operationMeta,\n      String paramName, RequestBody parameter, Type genericParamType) {\n    JavaType targetType =\n        genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);\n\n    if (isPart(parameter, paramName)) {\n      return new PartProcessor(paramName, parameter, genericParamType);\n    }\n    String mediaType = SwaggerConst.FORM_MEDIA_TYPE;\n    if (parameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE) != null) {\n      mediaType = SwaggerConst.FILE_MEDIA_TYPE;\n    }\n    return new FormProcessor(paramName, parameter, mediaType, targetType);\n  }\n\n  private boolean isPart(RequestBody parameter, String paramName) {\n    MediaType file = parameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE);\n    if (file != null) {\n      Schema<?> schema = (Schema<?>) file.getSchema().getProperties().get(paramName);\n      if (schema instanceof ArraySchema) {\n        return \"string\".equals(schema.getItems().getType()) &&\n            \"binary\".equals(schema.getItems().getFormat());\n      } else {\n        return (\"string\".equals(schema.getType()) && \"binary\".equals(schema.getFormat()));\n      }\n    }\n    return false;\n  }\n\n  public static class PartProcessor extends AbstractParamProcessor {\n    private static final Type partListType = ParameterizedTypeUtil.make(List.class, Part.class);\n\n    // key is target type\n    private static final Map<Type, Converter> partsToTargetConverters = SPIServiceUtils.getSortedService(\n            Converter.class)\n        .stream()\n        .filter(c -> partListType.equals(c.getSrcType()))\n        .collect(Collectors.toMap(Converter::getTargetType, Function.identity()));\n\n    // key is target type\n    private static final Map<Type, Converter> partToTargetConverters = SPIServiceUtils.getSortedService(Converter.class)\n        .stream()\n        .filter(c -> c.getSrcType() instanceof Class && Part.class.isAssignableFrom((Class<?>) c.getSrcType()))\n        .collect(Collectors.toMap(Converter::getTargetType, Function.identity()));\n\n    private final boolean repeatedType;\n\n    private Converter converter;\n\n    PartProcessor(String paramName, RequestBody formParameter, Type genericParamType) {\n      super(paramName, null,\n          formParameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE).getSchema().getDefault(),\n          formParameter.getRequired() != null && formParameter.getRequired());\n\n      this.repeatedType = formParameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE)\n          .getSchema().getProperties().get(paramName) instanceof ArraySchema;\n      initConverter(genericParamType);\n    }\n\n    private void initConverter(Type genericParamType) {\n      if (repeatedType) {\n        initRepeatedConverter(genericParamType);\n        return;\n      }\n\n      initNormalConverter(genericParamType);\n    }\n\n    private void initNormalConverter(Type genericParamType) {\n      if (genericParamType instanceof JavaType) {\n        genericParamType = ((JavaType) genericParamType).getRawClass();\n      }\n      converter = partToTargetConverters.get(genericParamType);\n    }\n\n    private void initRepeatedConverter(Type genericParamType) {\n      if (genericParamType instanceof JavaType) {\n        genericParamType = ParameterizedTypeUtil.make(((JavaType) genericParamType).getRawClass(),\n            ((JavaType) genericParamType).getContentType());\n      }\n      converter = partsToTargetConverters.get(genericParamType);\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) throws Exception {\n      if (repeatedType) {\n        // get all parts\n        List<Part> parts = request.getParts()\n            .stream()\n            .filter(part -> part.getName().equals(paramPath))\n            .collect(Collectors.toList());\n        return convertValue(converter, parts);\n      }\n\n      return convertValue(converter, request.getPart(paramPath));\n    }\n\n    public Object convertValue(Converter converter, Object value) {\n      if (value == null || converter == null) {\n        return value;\n      }\n\n      return converter.convert(value);\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      clientRequest.attach(paramPath, arg);\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAMTYPE;\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.header.HeaderCodec;\nimport org.apache.servicecomb.common.rest.codec.header.HeaderCodecsUtils;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.parameters.HeaderParameter;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.Parameter.StyleEnum;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class HeaderProcessorCreator implements ParamValueProcessorCreator<Parameter> {\n  public static final String PARAMTYPE = \"header\";\n\n  public static class HeaderProcessor extends AbstractParamProcessor {\n    // This configuration is used for temporary use only. Do not use it if you are sure how it works. And may be deleted in future.\n    private final boolean ignoreRequiredCheck = LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.parameter.header.ignoreRequiredCheck\", false);\n\n    private final HeaderCodec headerCodec;\n\n    public HeaderProcessor(HeaderParameter headerParameter, JavaType targetType) {\n      super(headerParameter.getName(), targetType, headerParameter.getSchema().getDefault(),\n          headerParameter.getRequired() != null && headerParameter.getRequired());\n\n      if ((headerParameter.getSchema() instanceof ArraySchema) && headerParameter.getStyle() == null) {\n        // compatible to default settings\n        this.headerCodec = HeaderCodecsUtils.find(StyleEnum.FORM, true);\n      } else {\n        this.headerCodec = HeaderCodecsUtils.find(headerParameter.getStyle(), headerParameter.getExplode());\n      }\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) {\n      return headerCodec.decode(this, request);\n    }\n\n    public Object checkRequiredAndDefaultValue() {\n      if (!ignoreRequiredCheck && isRequired()) {\n        throw new InvocationException(Status.BAD_REQUEST, \"Parameter is required.\");\n      }\n      return getDefaultValue();\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      headerCodec.encode(clientRequest, paramPath, arg);\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAMTYPE;\n    }\n  }\n\n  public HeaderProcessorCreator() {\n    ParamValueProcessorCreatorManager.INSTANCE.register(PARAMTYPE, this);\n  }\n\n  @Override\n  public ParamValueProcessor create(OperationMeta operationMeta,\n      String parameterName, Parameter parameter, Type genericParamType) {\n    JavaType targetType =\n        genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);\n    return new HeaderProcessor((HeaderParameter) parameter, targetType);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic interface ParamValueProcessor {\n  Object getValue(HttpServletRequest request) throws Exception;\n\n  void setValue(RestClientRequest clientRequest, Object arg) throws Exception;\n\n  default Object convertValue(Object value, JavaType targetType) {\n    if (value == null || targetType == null) {\n      return value;\n    }\n    if (getSerialViewClass() != null) {\n      return RestObjectMapperFactory.getRestViewMapper().setConfig(\n          RestObjectMapperFactory.getRestViewMapper().getDeserializationConfig().withView(getSerialViewClass()))\n          .convertValue(value, targetType);\n    }\n    return RestObjectMapperFactory.getRestObjectMapper()\n        .convertValue(value, targetType);\n  }\n\n  String getParameterPath();\n\n  String getProcessorType();\n\n  default Class<?> getSerialViewClass() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.core.definition.OperationMeta;\n\npublic interface ParamValueProcessorCreator<T> {\n  default ParamValueProcessor create(OperationMeta operationMeta, String paramName, T parameter,\n      Type genericParamType) {\n    throw new IllegalStateException(\"not implemented\");\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessorCreatorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport org.apache.servicecomb.foundation.common.RegisterManager;\n\npublic final class ParamValueProcessorCreatorManager extends RegisterManager<String, ParamValueProcessorCreator> {\n  private static final String NAME = \"param value processor mgr\";\n\n  public static final ParamValueProcessorCreatorManager INSTANCE = new ParamValueProcessorCreatorManager();\n\n  static {\n    new PathProcessorCreator();\n    new QueryProcessorCreator();\n    new FormProcessorCreator();\n    new HeaderProcessorCreator();\n    new CookieProcessorCreator();\n    new BodyProcessorCreator();\n  }\n\n  private ParamValueProcessorCreatorManager() {\n    super(NAME);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/PathProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.springframework.util.StringUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic class PathProcessorCreator implements ParamValueProcessorCreator<Parameter> {\n  public static final String PARAMTYPE = \"path\";\n\n  public static class PathProcessor extends AbstractParamProcessor {\n    public PathProcessor(String paramPath, JavaType targetType, Object defaultValue, boolean required) {\n      super(paramPath, targetType, defaultValue, required);\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) {\n      @SuppressWarnings(\"unchecked\")\n      Map<String, String> pathVarMap = (Map<String, String>) request.getAttribute(RestConst.PATH_PARAMETERS);\n      if (pathVarMap == null) {\n        return null;\n      }\n\n      String value = pathVarMap.get(paramPath);\n      if (value == null) {\n        return null;\n      }\n      return convertValue(StringUtils.uriDecode(value, StandardCharsets.UTF_8), targetType);\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      // path不需要set\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAMTYPE;\n    }\n  }\n\n  public PathProcessorCreator() {\n    ParamValueProcessorCreatorManager.INSTANCE.register(PARAMTYPE, this);\n  }\n\n  @Override\n  public ParamValueProcessor create(OperationMeta operationMeta,\n      String parameterName, Parameter parameter, Type genericParamType) {\n    JavaType targetType =\n        genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);\n    return new PathProcessor(parameterName, targetType, parameter.getSchema().getDefault(), true);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodec;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodecsUtils;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\n@SuppressWarnings(\"unchecked\")\npublic class QueryProcessorCreator implements ParamValueProcessorCreator<Parameter> {\n  public static final String PARAMTYPE = \"query\";\n\n  public static class QueryProcessor extends AbstractParamProcessor {\n    // This configuration is used for temporary use only. Do not use it if you are sure how it works. And may be deleted in future.\n    private final boolean emptyAsNull = LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", false);\n\n    // This configuration is used for temporary use only. Do not use it if you are sure how it works. And may be deleted in future.\n    private final boolean ignoreDefaultValue = LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", false);\n\n    // This configuration is used for temporary use only. Do not use it if you are sure how it works. And may be deleted in future.\n    private final boolean ignoreRequiredCheck = LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", false);\n\n    private final boolean repeatedType;\n\n    private final QueryCodec queryCodec;\n\n    public QueryProcessor(QueryParameter queryParameter, JavaType targetType) {\n      super(queryParameter.getName(), targetType, queryParameter.getSchema().getDefault(),\n          queryParameter.getRequired() != null && queryParameter.getRequired());\n\n      this.repeatedType = queryParameter.getSchema() instanceof ArraySchema;\n      this.queryCodec = QueryCodecsUtils.find(queryParameter.getStyle(), queryParameter.getExplode());\n    }\n\n    @Override\n    public Object getValue(HttpServletRequest request) {\n      return queryCodec.decode(this, request);\n    }\n\n    public Object getAndCheckParameter(HttpServletRequest request) {\n      Object value = request.getParameter(paramPath);\n\n      // compatible to SpringMVC @RequestParam. BODY_PARAMETER is only set for SpringMVC.\n      if (value == null) {\n        Map<String, Object> forms = (Map<String, Object>) request.getAttribute(RestConst.BODY_PARAMETER);\n        value = (forms == null || forms.get(paramPath) == null)\n            ? null : forms.get(paramPath);\n      }\n\n      // make some old systems happy\n      if (emptyAsNull && \"\".equals(value)) {\n        value = null;\n      }\n\n      return value != null ? value : checkRequiredAndDefaultValue();\n    }\n\n    private Object checkRequiredAndDefaultValue() {\n      if (!ignoreRequiredCheck && isRequired()) {\n        throw new InvocationException(Status.BAD_REQUEST,\n            String.format(\"Parameter %s is required.\", paramPath));\n      }\n      Object defaultValue = getDefaultValue();\n      if (!ignoreDefaultValue && defaultValue != null) {\n        return defaultValue;\n      }\n\n      return null;\n    }\n\n    @Override\n    public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {\n      // query不需要set\n    }\n\n    @Override\n    public String getProcessorType() {\n      return PARAMTYPE;\n    }\n\n    public QueryCodec getQueryCodec() {\n      return queryCodec;\n    }\n\n    public boolean isRepeatedType() {\n      return repeatedType;\n    }\n\n    public Object convertValue(Object value) {\n      return convertValue(value, targetType);\n    }\n  }\n\n  public QueryProcessorCreator() {\n    ParamValueProcessorCreatorManager.INSTANCE.register(PARAMTYPE, this);\n  }\n\n  @Override\n  public ParamValueProcessor create(OperationMeta operationMeta,\n      String parameterName, Parameter parameter, Type genericParamType) {\n    JavaType targetType =\n        genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);\n    return new QueryProcessor((QueryParameter) parameter, targetType);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceEventStreamProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport jakarta.ws.rs.core.MediaType;\n\npublic class ProduceEventStreamProcessor implements ProduceProcessor {\n  private int writeIndex = 0;\n\n  @Override\n  public String getName() {\n    return MediaType.SERVER_SENT_EVENTS;\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n\n  @Override\n  public void doEncodeResponse(OutputStream output, Object result) throws Exception {\n    String buffer = \"id: \" + (writeIndex++) + \"\\n\"\n        + \"data: \"\n        + RestObjectMapperFactory.getRestObjectMapper().writeValueAsString(result)\n        + \"\\n\\n\";\n    output.write(buffer.getBytes(StandardCharsets.UTF_8));\n  }\n\n  @Override\n  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {\n    String buffer = new String(input.readAllBytes(), StandardCharsets.UTF_8);\n    for (String line : buffer.split(\"\\n\")) {\n      if (line.startsWith(\"data: \")) {\n        return RestObjectMapperFactory.getRestObjectMapper().readValue(line.substring(5), type);\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic class ProduceJsonProcessor implements ProduceProcessor {\n\n  private Class<?> serializationView;\n\n  @Override\n  public String getSerializationView() {\n    return serializationView == null ? ProduceProcessor.super.getSerializationView()\n        : serializationView.getName();\n  }\n\n  @Override\n  public void setSerializationView(Class<?> serializationView) {\n    if (serializationView == null) {\n      return;\n    }\n    this.serializationView = serializationView;\n  }\n\n  @Override\n  public String getName() {\n    return MediaType.APPLICATION_JSON;\n  }\n\n  @Override\n  public void doEncodeResponse(OutputStream output, Object result) throws Exception {\n    if (serializationView == null) {\n      RestObjectMapperFactory.getRestObjectMapper().writeValue(output, result);\n      return;\n    }\n    RestObjectMapperFactory.getRestObjectMapper().writerWithView(serializationView).writeValue(output, result);\n  }\n\n  @Override\n  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {\n    if (serializationView == null) {\n      return RestObjectMapperFactory.getRestObjectMapper().readValue(input, type);\n    }\n    return RestObjectMapperFactory.getRestObjectMapper().readerWithView(serializationView)\n        .forType(type).readValue(input);\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic interface ProduceProcessor {\n  String getName();\n\n  int getOrder();\n\n  default String getSerializationView() {\n    return ProduceProcessorManager.DEFAULT_SERIAL_CLASS;\n  }\n\n  default void setSerializationView(Class<?> serializationView) {\n    // do nothing default\n  }\n\n  default void encodeResponse(OutputStream output, Object result) throws Exception {\n    if (result == null) {\n      return;\n    }\n\n    doEncodeResponse(output, result);\n  }\n\n  void doEncodeResponse(OutputStream output, Object result) throws Exception;\n\n  default Buffer encodeResponse(Object result) throws Exception {\n    if (null == result) {\n      return null;\n    }\n\n    try (BufferOutputStream output = new BufferOutputStream()) {\n      doEncodeResponse(output, result);\n      return output.getBuffer();\n    }\n  }\n\n  default Object decodeResponse(InputStream input, JavaType type) throws Exception {\n    return doDecodeResponse(input, type);\n  }\n\n  Object doDecodeResponse(InputStream input, JavaType type) throws Exception;\n\n  default Object decodeResponse(Buffer buffer, JavaType type) throws Exception {\n    if (buffer.length() == 0) {\n      return null;\n    }\n\n    try (BufferInputStream input = new BufferInputStream(buffer)) {\n      return doDecodeResponse(input, type);\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.entity.ContentType;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.RegisterManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport jakarta.ws.rs.core.MediaType;\n\npublic final class ProduceProcessorManager extends RegisterManager<String, Map<String, ProduceProcessor>> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProduceProcessorManager.class);\n\n  private static final List<ProduceProcessor> produceProcessor =\n      SPIServiceUtils.getSortedService(ProduceProcessor.class);\n\n  private static final String NAME = \"produce processor mgr\";\n\n  public static final String DEFAULT_SERIAL_CLASS = \"servicecomb_default_class\";\n\n  public static final ProduceProcessorManager INSTANCE = new ProduceProcessorManager();\n\n  public static final String PARAM_DEFAULT_RESPONSE_ENCODING = \"servicecomb.rest.parameter.default-response-encoding\";\n\n  private static String defaultResponseEncoding;\n\n  private final Map<String, ProduceProcessor> jsonProcessorMap;\n\n  private final Map<String, ProduceProcessor> plainProcessorMap;\n\n  private final Map<String, ProduceProcessor> defaultProcessorMap;\n\n  private ProduceProcessorManager() {\n    super(NAME);\n    produceProcessor.forEach(processor -> {\n      Map<String, ProduceProcessor> prodProcessorMap = getObjMap()\n          .computeIfAbsent(processor.getName(), key -> new HashMap<>());\n      prodProcessorMap.putIfAbsent(processor.getSerializationView(), processor);\n    });\n    jsonProcessorMap = ensureFindValue(MediaType.APPLICATION_JSON);\n    plainProcessorMap = ensureFindValue(MediaType.TEXT_PLAIN);\n    defaultProcessorMap = jsonProcessorMap;\n  }\n\n  private static ProduceProcessor cloneNewProduceProcessor(Class<?> serialViewClass,\n      Map<String, ProduceProcessor> produceViewMap) {\n    ProduceProcessor newInstance;\n    try {\n      newInstance = produceViewMap.get(DEFAULT_SERIAL_CLASS).getClass().getDeclaredConstructor().newInstance();\n      newInstance.setSerializationView(serialViewClass);\n      return newInstance;\n    } catch (Throwable e) {\n      // ignore exception\n      LOGGER.warn(\"Failed to create produceProcessor with {}\", serialViewClass.getName(), e);\n    }\n    return produceViewMap.get(DEFAULT_SERIAL_CLASS);\n  }\n\n  private static String defaultResponseEncoding() {\n    if (defaultResponseEncoding == null) {\n      defaultResponseEncoding = LegacyPropertyFactory\n          .getStringProperty(PARAM_DEFAULT_RESPONSE_ENCODING, MediaType.APPLICATION_JSON);\n    }\n    return defaultResponseEncoding;\n  }\n\n  public ProduceProcessor findJsonProcessorByViewClass(Class<?> serialViewClass) {\n    if (serialViewClass == null) {\n      return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);\n    }\n    return jsonProcessorMap.computeIfAbsent(serialViewClass.getName(),\n        viewKey -> cloneNewProduceProcessor(serialViewClass, jsonProcessorMap));\n  }\n\n  public ProduceProcessor findPlainProcessorByViewClass(Class<?> serialViewClass) {\n    if (serialViewClass == null) {\n      return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);\n    }\n    return plainProcessorMap.computeIfAbsent(serialViewClass.getName(),\n        viewKey -> cloneNewProduceProcessor(serialViewClass, plainProcessorMap));\n  }\n\n  public ProduceProcessor findDefaultJsonProcessor() {\n    return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);\n  }\n\n  public ProduceProcessor findDefaultProcessor() {\n    return defaultProcessorMap.get(DEFAULT_SERIAL_CLASS);\n  }\n\n  public ProduceProcessor findDefaultPlainProcessor() {\n    return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);\n  }\n\n  public ProduceProcessor createProduceProcessor(OperationMeta operationMeta,\n      int statusCode, String accept, Class<?> serialViewClass) {\n    // If no produces defined, using default processor\n    ApiResponses responses = operationMeta.getSwaggerOperation().getResponses();\n    ApiResponse response = responses.get(String.valueOf(statusCode));\n    if (response == null || response.getContent() == null ||\n        response.getContent().size() == 0) {\n      return findDefaultProcessor();\n    }\n\n    // check intersection of `Accept` and `Produces`\n    if (accept == null) {\n      if (response.getContent().get(defaultResponseEncoding()) != null) {\n        accept = defaultResponseEncoding();\n      } else {\n        accept = response.getContent().keySet().iterator().next();\n      }\n    }\n\n    String actualAccept = null;\n    for (String item : accept.split(\",\")) {\n      ContentType contentType = ContentType.parse(item);\n      if (MediaType.WILDCARD.equals(contentType.getMimeType()) ||\n          MediaType.MEDIA_TYPE_WILDCARD.equals(contentType.getMimeType())) {\n        if (response.getContent().get(defaultResponseEncoding()) != null) {\n          actualAccept = defaultResponseEncoding();\n        } else {\n          actualAccept = response.getContent().keySet().iterator().next();\n        }\n        break;\n      }\n      if (response.getContent().get(contentType.getMimeType()) != null) {\n        actualAccept = contentType.getMimeType();\n        break;\n      }\n    }\n\n    if (actualAccept == null) {\n      LOGGER.warn(\"Operation {} do not support accept type {}\", operationMeta.getSchemaQualifiedName(), accept);\n      return findDefaultProcessor();\n    }\n    if (MediaType.APPLICATION_JSON.equals(actualAccept)) {\n      return findJsonProcessorByViewClass(serialViewClass);\n    }\n    if (SwaggerConst.PROTOBUF_TYPE.equals(actualAccept)) {\n      return new ProduceProtoBufferProcessor(operationMeta,\n          operationMeta.getSchemaMeta().getSwagger(), response.getContent().get(actualAccept).getSchema());\n    }\n    if (MediaType.SERVER_SENT_EVENTS.equals(actualAccept)) {\n      return new ProduceEventStreamProcessor();\n    }\n    // text plain\n    return findPlainProcessorByViewClass(serialViewClass);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProtoBufferProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic class ProduceProtoBufferProcessor implements ProduceProcessor {\n  public static final String RESPONSE_MESSAGE_NAME = \"X_RESPONSE\";\n\n  public static final String EXT_ID = \"protobuf\";\n\n  private static final Object LOCK = new Object();\n\n  private final OperationMeta operationMeta;\n\n  private final OpenAPI openAPI;\n\n  private final Schema<?> schema;\n\n  private final ScopedProtobufSchemaManager scopedProtobufSchemaManager;\n\n  public ProduceProtoBufferProcessor(OperationMeta operationMeta, OpenAPI openAPI, Schema<?> schema) {\n    this.operationMeta = operationMeta;\n    this.openAPI = openAPI;\n    this.schema = schema;\n    this.scopedProtobufSchemaManager = getOrCreateScopedProtobufSchemaManager(operationMeta.getMicroserviceMeta());\n  }\n\n  private ScopedProtobufSchemaManager getOrCreateScopedProtobufSchemaManager(MicroserviceMeta microserviceMeta) {\n    ScopedProtobufSchemaManager scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);\n    if (scopedProtobufSchemaManager == null) {\n      synchronized (LOCK) {\n        scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);\n        if (scopedProtobufSchemaManager == null) {\n          scopedProtobufSchemaManager = new ScopedProtobufSchemaManager();\n          microserviceMeta.putExtData(EXT_ID, scopedProtobufSchemaManager);\n        }\n      }\n    }\n    return scopedProtobufSchemaManager;\n  }\n\n  @Override\n  public String getName() {\n    return SwaggerConst.PROTOBUF_TYPE;\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n\n  @Override\n  public void doEncodeResponse(OutputStream output, Object result) throws Exception {\n    ProtoMapper protoMapper = scopedProtobufSchemaManager\n        .getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),\n            RESPONSE_MESSAGE_NAME, schema);\n    RootSerializer serializer = protoMapper.getSerializerSchemaManager()\n        .createRootSerializer(protoMapper.getProto().getMessage(RESPONSE_MESSAGE_NAME),\n            Object.class);\n    Map<String, Object> bodyArg = new HashMap<>(1);\n    bodyArg.put(\"value\", result);\n    output.write(serializer.serialize(bodyArg));\n  }\n\n  @Override\n  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {\n    ProtoMapper protoMapper = scopedProtobufSchemaManager\n        .getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),\n            RESPONSE_MESSAGE_NAME, schema);\n    RootDeserializer<PropertyWrapper<Object>> deserializer = protoMapper.getDeserializerSchemaManager()\n        .createRootDeserializer(protoMapper.getProto().getMessage(RESPONSE_MESSAGE_NAME), type);\n    PropertyWrapper<Object> result = deserializer.deserialize(input.readAllBytes());\n    return result.getValue();\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport jakarta.ws.rs.core.MediaType;\n\npublic class ProduceTextPlainProcessor extends ProduceJsonProcessor {\n  @Override\n  public String getName() {\n    return MediaType.TEXT_PLAIN;\n  }\n\n  @Override\n  public void doEncodeResponse(OutputStream output, Object result) throws Exception {\n    if (result instanceof String) {\n      output.write(((String) result).getBytes(StandardCharsets.UTF_8));\n      return;\n    }\n    super.doEncodeResponse(output, result);\n  }\n\n  @Override\n  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {\n    if (String.class.equals(type.getRawClass())) {\n      return IOUtils.toString(input, StandardCharsets.UTF_8);\n    }\n    return super.doDecodeResponse(input, type);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/AbstractQueryCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\n\npublic abstract class AbstractQueryCodec implements QueryCodec {\n  private final String codecName;\n\n  public AbstractQueryCodec(String codecName) {\n    this.codecName = codecName;\n  }\n\n  @Override\n  public String getCodecName() {\n    return codecName;\n  }\n\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public void encode(URLPathStringBuilder builder, String name, Object value) throws Exception {\n    if (value == null) {\n      // not write query key to express \"null\"\n      return;\n    }\n\n    if (value.getClass().isArray()) {\n      if (!(value instanceof Object[])) {\n        value = RestObjectMapperFactory.getRestObjectMapper()\n            .convertValue(value, Object[].class);\n      }\n      encode(builder, name, Arrays.asList((Object[]) value));\n      return;\n    }\n\n    if (value instanceof Collection) {\n      encode(builder, name, (Collection<Object>) value);\n      return;\n    }\n\n    encode(builder, name, Collections.singletonList(value));\n  }\n\n  abstract void encode(URLPathStringBuilder builder, String name, Collection<Object> values) throws Exception;\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.springframework.core.Ordered;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\n/**\n * bigger order will override the same name codec\n */\npublic interface QueryCodec extends Ordered {\n  static String encodeValue(Object value) throws UnsupportedEncodingException {\n    return URLEncoder.encode(value.toString(), StandardCharsets.UTF_8.name());\n  }\n\n  // can not be replaced by value.toString() because of date serialize\n  static String convertToString(Object value) throws Exception {\n    return RestObjectMapperFactory.getRestObjectMapper().convertToString(value);\n  }\n\n  @Override\n  default int getOrder() {\n    return 0;\n  }\n\n  String getCodecName();\n\n  void encode(URLPathStringBuilder builder, String name, Object value) throws Exception;\n\n  Object decode(QueryProcessor processor, HttpServletRequest request);\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecCsv.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\n/**\n * ?query=x1,x2\n */\npublic class QueryCodecCsv extends QueryCodecWithDelimiter {\n  public static final String CODEC_NAME = \"form:0\";\n\n  public static final String DELIMITER = \",\";\n\n  public QueryCodecCsv() {\n    super(CODEC_NAME, DELIMITER, DELIMITER);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecMulti.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Collection;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\n@SuppressWarnings(\"unchecked\")\npublic class QueryCodecMulti extends AbstractQueryCodec {\n  public static final String CODEC_NAME = \"form:1\";\n\n  public QueryCodecMulti() {\n    super(CODEC_NAME);\n  }\n\n  @Override\n  public void encode(URLPathStringBuilder builder, String name, Collection<Object> values) throws Exception {\n    for (Object value : values) {\n      if (value == null) {\n        continue;\n      }\n\n      String strValue = QueryCodec.convertToString(value);\n      builder.appendQuery(name, QueryCodec.encodeValue(strValue));\n    }\n  }\n\n  @Override\n  public Object decode(QueryProcessor processor, HttpServletRequest request) {\n    if (processor.isRepeatedType()) {\n      //Even if the paramPath does not exist, value won't be null at now\n      String[] values = request.getParameterValues(processor.getParameterPath());\n\n      // compatible to SpringMVC @RequestParam. BODY_PARAMETER is only set for SpringMVC.\n      if (values == null || values.length == 0) {\n        Map<String, Object> forms = (Map<String, Object>) request.getAttribute(RestConst.BODY_PARAMETER);\n        if (forms == null) {\n          return processor.convertValue(values);\n        }\n        Object formValue = forms.get(processor.getParameterPath());\n        if (formValue == null) {\n          return processor.convertValue(values);\n        }\n        if (formValue instanceof String[]) {\n          values = (String[]) formValue;\n        } else {\n          values = new String[] {formValue.toString()};\n        }\n      }\n      return processor.convertValue(values);\n    }\n\n    Object value = processor.getAndCheckParameter(request);\n    return processor.convertValue(value);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecPipes.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\n/**\n * ?query=x1|x2\n */\npublic class QueryCodecPipes extends QueryCodecWithDelimiter {\n  public static final String CODEC_NAME = \"pipeDelimited:0\";\n\n  public static final String JOIN_DELIMITER = \"|\";\n\n  public static final String SPLIT_DELIMITER = \"\\\\|\";\n\n  public QueryCodecPipes() {\n    super(CODEC_NAME, JOIN_DELIMITER, SPLIT_DELIMITER);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecSsv.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\n/**\n * ?query=x1%20x2\n */\npublic class QueryCodecSsv extends QueryCodecWithDelimiter {\n  public static final String CODEC_NAME = \"spaceDelimited:0\";\n\n  public static final String DELIMITER = \" \";\n\n  public QueryCodecSsv() {\n    super(CODEC_NAME, DELIMITER, DELIMITER);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecWithDelimiter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Collection;\nimport java.util.StringJoiner;\n\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\n/**\n * can not support value with delimiter<br>\n * a csv example, a collection with two values:<br>\n *   1. a<br>\n *   2. b,c<br>\n *  will encode to be a%2Cb%2Cc, this is ambiguous\n */\npublic class QueryCodecWithDelimiter extends AbstractQueryCodec {\n  private final String joinDelimiter;\n\n  private final String splitDelimiter;\n\n  public QueryCodecWithDelimiter(String codecName, String joinDelimiter, String splitDelimiter) {\n    super(codecName);\n    this.joinDelimiter = joinDelimiter;\n    this.splitDelimiter = splitDelimiter;\n  }\n\n  @Override\n  public void encode(URLPathStringBuilder builder, String name, Collection<Object> values) throws Exception {\n    String joined = join(values);\n    if (joined == null) {\n      return;\n    }\n\n    builder.appendQuery(name, joined);\n  }\n\n  /**\n   * <pre>\n   *   SwaggerIde:\n   *   1. encode query value by uri rule, not url rule\n   *      part of the difference:\n   *               uri  url\n   *        space  %20  +\n   *        [      [    %5B\n   *      some difference will cause tomcat parse url failed\n   *      so we encode query value by url rule\n   *   2. encode each element\n   *        for pipes, SwaggerIde will encode [a, b] to a|b\n   *        but this will cause problem when run with tomcat\n   *        so we encode the joined value, not encode each element\n   * </pre>\n   * @param values values to be joined\n   * @return joined value\n   */\n  protected String join(Collection<Object> values) throws Exception {\n    StringJoiner joiner = new StringJoiner(joinDelimiter);\n    boolean hasValue = false;\n    for (Object value : values) {\n      if (value != null) {\n        String strValue = QueryCodec.convertToString(value);\n        joiner.add(strValue);\n        hasValue = true;\n      }\n    }\n\n    return hasValue ? QueryCodec.encodeValue(joiner.toString()) : null;\n  }\n\n  @Override\n  public Object decode(QueryProcessor processor, HttpServletRequest request) {\n    Object value = processor.getAndCheckParameter(request);\n    value = value != null ? value.toString().split(splitDelimiter, -1) : new String[0];\n    return processor.convertValue(value);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class QueryCodecs {\n  private static final Logger LOGGER = LoggerFactory.getLogger(QueryCodecs.class);\n\n  static QueryCodecs createForTest() {\n    return new QueryCodecs(Arrays.asList(\n        new QueryCodecMulti(),\n        new QueryCodecCsv(),\n        new QueryCodecSsv(),\n        new QueryCodecPipes()\n    ));\n  }\n\n  private final Map<String, QueryCodec> codecs = new HashMap<>();\n\n  private final QueryCodec defaultCodec;\n\n  public QueryCodecs(List<QueryCodec> orderedCodecs) {\n    orderedCodecs.forEach(this::register);\n    defaultCodec = codecs.get(QueryCodecMulti.CODEC_NAME);\n  }\n\n  private void register(QueryCodec codec) {\n    QueryCodec exists = codecs.put(codec.getCodecName(), codec);\n    if (exists != null) {\n      LOGGER.info(\"override QueryCodec, exists={}, new={}.\",\n          exists.getClass().getName(), codec.getClass().getName());\n    }\n  }\n\n  public QueryCodec find(String name) {\n    if (name == null) {\n      return defaultCodec;\n    }\n\n    QueryCodec codec = codecs.get(name);\n    if (codec == null) {\n      throw new IllegalStateException(\"not support QueryCodec, name=\" + name);\n    }\n    return codec;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecsUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.Parameter.StyleEnum;\n\npublic class QueryCodecsUtils {\n  // create a default instance, so that more friendly to UT\n  private static QueryCodecs queryCodecs = QueryCodecs.createForTest();\n\n  public QueryCodecsUtils(QueryCodecs queryCodecs) {\n    QueryCodecsUtils.queryCodecs = queryCodecs;\n  }\n\n  public static QueryCodec find(Parameter.StyleEnum styleEnum, Boolean explode) {\n    return queryCodecs.find(formatName(styleEnum, explode));\n  }\n\n  private static String formatName(StyleEnum styleEnum, Boolean explode) {\n    if (styleEnum == null) {\n      return null;\n    }\n    return styleEnum + \":\" +\n        (explode != null && explode ? \"1\" : \"0\");\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestMetaUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.definition;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.definition.OperationMeta;\n\npublic final class RestMetaUtils {\n  private RestMetaUtils() {\n  }\n\n  public static RestOperationMeta getRestOperationMeta(OperationMeta operationMeta) {\n    return operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationComparator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition;\n\nimport java.io.Serializable;\nimport java.util.Comparator;\n\nimport org.apache.servicecomb.common.rest.definition.path.PathRegExp;\n\n/**\n * 用于RestOperation的排序\n */\npublic class RestOperationComparator implements Serializable, Comparator<RestOperationMeta> {\n\n  private static final long serialVersionUID = -2364909265520813678L;\n\n  @Override\n  public int compare(RestOperationMeta r1, RestOperationMeta r2) {\n    // 排序规则:\n    // 1.静态字符多的优先\n    // 2.变量组多的优先\n    // 3.带正则表达式的优先\n    // 如:\n    // /customers/{id}/{name}/address\n    // /customers/{id : .+}/address\n    // /customers/{id}/address\n    // /customers/{id : .+}\n\n    PathRegExp path1 = r1.getAbsolutePathRegExp();\n    PathRegExp path2 = r2.getAbsolutePathRegExp();\n\n    int staticCompare = path2.getStaticCharCount() - path1.getStaticCharCount();\n    if (staticCompare != 0) {\n      return staticCompare;\n    }\n\n    int groupCompare = path2.getGroupCount() - path1.getGroupCount();\n    if (groupCompare != 0) {\n      return groupCompare;\n    }\n\n    return path2.getGroupWithRegExpCount() - path1.getGroupWithRegExpCount();\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition;\n\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.PartProcessor;\nimport org.apache.servicecomb.common.rest.definition.path.PathRegExp;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport jakarta.ws.rs.core.MediaType;\n\n@SuppressWarnings(\"rawtypes\")\npublic class RestOperationMeta {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestOperationMeta.class);\n\n  protected OperationMeta operationMeta;\n\n  protected boolean formData;\n\n  // make sure if response is file\n  protected boolean downloadFile;\n\n  protected boolean serverSendEvents;\n\n  protected List<RestParam> paramList = new ArrayList<>();\n\n  // key为参数名\n  protected Map<String, RestParam> paramMap = new LinkedHashMap<>();\n\n  protected List<String> fileKeys = new ArrayList<>();\n\n  protected String absolutePath;\n\n  protected PathRegExp absolutePathRegExp;\n\n  // 快速构建URL path\n  private URLPathBuilder pathBuilder;\n\n  public void init(OperationMeta operationMeta) {\n    this.operationMeta = operationMeta;\n\n    OpenAPI swagger = operationMeta.getSchemaMeta().getSwagger();\n    Operation operation = operationMeta.getSwaggerOperation();\n\n    this.downloadFile = checkDownloadFileFlag();\n    this.serverSendEvents = checkServerSendEvents();\n\n    if (operation.getParameters() != null) {\n      for (int swaggerParameterIdx = 0; swaggerParameterIdx < operation.getParameters().size(); swaggerParameterIdx++) {\n        Parameter parameter = operation.getParameters().get(swaggerParameterIdx);\n        Type type = operationMeta.getSwaggerProducerOperation() != null ? operationMeta.getSwaggerProducerOperation()\n            .getSwaggerParameterTypes().get(parameter.getName()) : null;\n        RestParam param = new RestParam(operationMeta, parameter, type);\n        addParam(param);\n      }\n    }\n\n    if (operation.getRequestBody() != null) {\n      if (isFormParameters(operation)) {\n        formData = true;\n        Schema formSchema = formSchemas(operation);\n        if (formSchema != null) {\n          formSchema.getProperties().forEach((k, v) -> {\n            addRestParamByName(operationMeta, (String) k, operation);\n          });\n        }\n      } else {\n        addRestParamByName(operationMeta,\n            (String) operation.getRequestBody().getExtensions().get(SwaggerConst.EXT_BODY_NAME), operation);\n      }\n    }\n\n    setAbsolutePath(SwaggerUtils.concatAbsolutePath(swagger, operationMeta.getOperationPath()));\n  }\n\n  private void addRestParamByName(OperationMeta operationMeta, String name, Operation operation) {\n    Type type = operationMeta.getSwaggerProducerOperation() != null ? operationMeta.getSwaggerProducerOperation()\n        .getSwaggerParameterTypes().get(name) : null;\n    RestParam param = new RestParam(operationMeta, name, operation.getRequestBody(), formData, type);\n    addParam(param);\n  }\n\n  private boolean isFormParameters(Operation operation) {\n    return operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null ||\n        operation.getRequestBody().getContent().get(SwaggerConst.FILE_MEDIA_TYPE) != null;\n  }\n\n  private Schema formSchemas(Operation operation) {\n    if (operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null) {\n      return operation.getRequestBody().getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema();\n    }\n    return operation.getRequestBody().getContent().get(SwaggerConst.FILE_MEDIA_TYPE).getSchema();\n  }\n\n  public boolean isDownloadFile() {\n    return downloadFile;\n  }\n\n  public boolean isServerSendEvents() {\n    return serverSendEvents;\n  }\n\n  private boolean checkServerSendEvents() {\n    ApiResponses responses = operationMeta.getSwaggerOperation().getResponses();\n    if (responses == null) {\n      return false;\n    }\n    ApiResponse response = responses.get(SwaggerConst.SUCCESS_KEY);\n    return response != null && response.getContent() != null\n        && response.getContent().get(MediaType.SERVER_SENT_EVENTS) != null;\n  }\n\n  private boolean checkDownloadFileFlag() {\n    ApiResponses responses = operationMeta.getSwaggerOperation().getResponses();\n    if (responses == null) {\n      return false;\n    }\n    ApiResponse response = responses.get(SwaggerConst.SUCCESS_KEY);\n    if (response != null && response.getContent() != null) {\n      for (io.swagger.v3.oas.models.media.MediaType mediaType : response.getContent().values()) {\n        if (mediaType.getSchema() != null\n            && \"string\".equals(mediaType.getSchema().getType())\n            && \"binary\".equals(mediaType.getSchema().getFormat())) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  public boolean isFormData() {\n    return formData;\n  }\n\n  public void setOperationMeta(OperationMeta operationMeta) {\n    this.operationMeta = operationMeta;\n  }\n\n  public String getAbsolutePath() {\n    return this.absolutePath;\n  }\n\n  public void setAbsolutePath(String absolutePath) {\n    this.absolutePath = absolutePath;\n    this.absolutePathRegExp = createPathRegExp(absolutePath);\n    this.pathBuilder = new URLPathBuilder(absolutePath, paramMap);\n  }\n\n  public PathRegExp getAbsolutePathRegExp() {\n    return this.absolutePathRegExp;\n  }\n\n  public boolean isAbsoluteStaticPath() {\n    return this.absolutePathRegExp.isStaticPath();\n  }\n\n  protected PathRegExp createPathRegExp(String path) {\n    if (path == null || path.equals(\"\")) {\n      throw new Error(\"null rest url is not supported\");\n    }\n    try {\n      return new PathRegExp(OperationLocator.getStandardPath(path));\n    } catch (Exception e) {\n      LOGGER.error(e.getMessage());\n      return null;\n    }\n  }\n\n  public RestParam getParamByName(String name) {\n    return paramMap.get(name);\n  }\n\n  public OperationMeta getOperationMeta() {\n    return operationMeta;\n  }\n\n  public URLPathBuilder getPathBuilder() {\n    return this.pathBuilder;\n  }\n\n  public List<RestParam> getParamList() {\n    return paramList;\n  }\n\n  private void addParam(RestParam param) {\n    if (param.getParamProcessor() instanceof PartProcessor) {\n      fileKeys.add(param.getParamName());\n    }\n    paramList.add(param);\n    paramMap.put(param.getParamName(), param);\n  }\n\n  public String getHttpMethod() {\n    return operationMeta.getHttpMethod();\n  }\n\n  public List<String> getFileKeys() {\n    return fileKeys;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition;\n\nimport java.lang.reflect.Type;\nimport java.util.Collection;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator;\nimport org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator;\nimport org.apache.servicecomb.common.rest.codec.param.ParamValueProcessor;\nimport org.apache.servicecomb.common.rest.codec.param.ParamValueProcessorCreator;\nimport org.apache.servicecomb.common.rest.codec.param.ParamValueProcessorCreatorManager;\nimport org.apache.servicecomb.core.definition.OperationMeta;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class RestParam {\n  private static final JavaType STRING_ARRAY_TYPE = TypeFactory.defaultInstance().constructArrayType(String.class);\n\n  protected ParamValueProcessor paramProcessor;\n\n  protected String paramName;\n\n  public RestParam(OperationMeta operationMeta, Parameter parameter, Type genericParamType) {\n    this.paramName = parameter.getName();\n\n    init(operationMeta, parameter, genericParamType);\n  }\n\n  public RestParam(OperationMeta operationMeta,\n      String paramName, RequestBody parameter, boolean isForm, Type genericParamType) {\n    this.paramName = paramName;\n\n    init(operationMeta, parameter, isForm, genericParamType);\n  }\n\n\n  public ParamValueProcessor getParamProcessor() {\n    return this.paramProcessor;\n  }\n\n  public void setParamProcessor(ParamValueProcessor paramProcessor) {\n    this.paramProcessor = paramProcessor;\n  }\n\n  public String getParamName() {\n    return paramName;\n  }\n\n  protected void init(OperationMeta operationMeta, Parameter parameter, Type genericParamType) {\n    String paramType = parameter.getIn();\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.ensureFindValue(paramType);\n\n    this.setParamProcessor(creator.create(operationMeta, parameter.getName(), parameter, genericParamType));\n  }\n\n  protected void init(OperationMeta operationMeta, RequestBody parameter, boolean isForm, Type genericParamType) {\n    ParamValueProcessorCreator creator;\n    if (isForm) {\n      creator =\n          ParamValueProcessorCreatorManager.INSTANCE.ensureFindValue(FormProcessorCreator.PARAMTYPE);\n    } else {\n      creator =\n          ParamValueProcessorCreatorManager.INSTANCE.ensureFindValue(BodyProcessorCreator.PARAM_TYPE);\n    }\n\n    this.setParamProcessor(creator.create(operationMeta, this.paramName,\n        parameter, genericParamType));\n  }\n\n  public <T> T getValue(Map<String, Object> args) {\n    return (T) args.get(paramName);\n  }\n\n  public String[] getValueAsStrings(Map<String, Object> args) {\n    Object value = args.get(paramName);\n    if (value == null) {\n      return null;\n    }\n\n    if (value.getClass().isArray() || value instanceof Collection) {\n      return (String[]) paramProcessor.convertValue(value, STRING_ARRAY_TYPE);\n    }\n\n    return new String[] {String.valueOf(value)};\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/AbstractUrlParamWriter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.Map;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\n\npublic abstract class AbstractUrlParamWriter implements UrlParamWriter {\n  protected RestParam param;\n\n  @VisibleForTesting\n  public Object getParamValue(Map<String, Object> args) {\n    if (param == null) {\n      // Wrong server definition\n      //  @GetMapping(path = \"/getLocalDateTime/{paramX}\")\n      //  public LocalDateTime getLocalDateTimePath(@PathParam(\"paramY\") LocalDateTime date) {\n      throw new IllegalArgumentException(\"Path parameter name not valid in provider. Check if provider \"\n          + \"path pattern has the parameter name.\");\n    }\n    return args.get(param.getParamName());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/PathRegExp.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * 处理path中的正则表达式\n */\npublic class PathRegExp {\n  // 不带正则表达式的group,使用这个作为正则表达式\n  private static final String DEFAULT_REG_EXP = \"[^/]+?\";\n\n  private static final byte NAME_READ = 2;\n\n  private static final byte NAME_READ_READY = 3;\n\n  private static final byte NAME_READ_START = 1;\n\n  private static final byte REGEXP_READ = 12;\n\n  private static final byte REGEXP_READ_READY = 13;\n\n  private static final byte REGEXP_READ_START = 11;\n\n  public static final String SLASH = \"/\";\n\n  // 静态字符的个数\n  protected int staticCharCount;\n\n  // 包括带正则表达式和不带正则表达式的group,总数\n  protected int groupCount;\n\n  // 带正则表达式的group数\n  protected int groupWithRegExpCount = 0;\n\n  protected final Pattern pattern;\n\n  protected final List<String> varNames = new ArrayList<>();\n\n  public static String ensureEndWithSlash(String path) {\n    if (path.endsWith(SLASH)) {\n      return path;\n    }\n\n    return path + \"/\";\n  }\n\n  // 调用者已经保证path不以/打头\n  public PathRegExp(String path)\n      throws Exception {\n    // a/{id}/{name:.+}/{age}/c变成下面的表达式\n    // a/([^/]+?)/(.+)/([^/]+?)/c/(.*)\n    final int pathLength = path.length();\n    final StringBuilder pathPattern = new StringBuilder();\n    for (int i = 0; i < pathLength; i++) {\n      final char c = path.charAt(i);\n      switch (c) {\n        case '{':\n          i = processGroup(path, i, pathPattern);\n          groupCount++;\n          break;\n        case '}':\n          throw new Exception(\"'}' is only allowed as \"\n              + \"end of a variable name in \\\"\" + path + \"\\\"\");\n        case ';':\n          throw new Exception(\"matrix parameters are not allowed in \\\"\" + path\n              + \"\\\"\");\n        default:\n          pathPattern.append(c);\n          staticCharCount++;\n      }\n    }\n    if (pathPattern.length() > 0\n        && pathPattern.charAt(pathPattern.length() - 1) != '/') {\n      pathPattern.append('/');\n    }\n    pathPattern.append(\"(.*)\");\n\n    pattern = Pattern.compile(pathPattern.toString());\n  }\n\n  protected int processGroup(final String path, final int braceIndex,\n      final StringBuilder pathPattern) throws Exception {\n    pathPattern.append('(');\n    final int pathLength = path.length();\n    final StringBuilder varName = new StringBuilder();\n    final StringBuilder regExp = new StringBuilder();\n    int state = NAME_READ_START;\n    for (int i = braceIndex + 1; i < pathLength; i++) {\n      final char c = path.charAt(i);\n      switch (c) {\n        case '{':\n          throw new Exception(\"A variable must not contain an extra '{' in \\\"\"\n              + path + \"\\\"\");\n        case ' ':\n        case '\\t':\n          state = processLineBreak(state);\n          break;\n        case ':':\n          state = processColon(path, braceIndex, state);\n          break;\n        case '}':\n          processBrace(path, pathPattern, varName, regExp, state);\n          return i;\n        default:\n          state = processDefault(path, varName, regExp, state, i, c);\n          break;\n      }\n    }\n    throw new Exception(\"No '}' found after '{' \" + \"at position \" + braceIndex\n        + \" of \\\"\" + path + \"\\\"\");\n  }\n\n  private int processDefault(final String path, final StringBuilder varName,\n      final StringBuilder regExp, int state, int i, final char c) throws Exception {\n    if (state == NAME_READ_START) {\n      state = NAME_READ;\n      varName.append(c);\n    } else if (state == NAME_READ) {\n      varName.append(c);\n    } else if (state == REGEXP_READ_START) {\n      state = REGEXP_READ;\n      regExp.append(c);\n    } else if (state == REGEXP_READ) {\n      regExp.append(c);\n    } else {\n      throw new Exception(\"Invalid character found at position \" + i\n          + \" of \\\"\" + path + \"\\\"\");\n    }\n    return state;\n  }\n\n  private void processBrace(final String path, final StringBuilder pathPattern,\n      final StringBuilder varName, final StringBuilder regExp, int state) throws Exception {\n    if (state == NAME_READ_START) {\n      throw new Exception(\n          \"The template variable name '{}' is not allowed in \"\n              + \"\\\"\" + path + \"\\\"\");\n    }\n    if ((state == REGEXP_READ) || (state == REGEXP_READ_READY)) {\n      pathPattern.append(regExp);\n      if (!regExp.toString().equals(DEFAULT_REG_EXP)) {\n        groupWithRegExpCount++;\n      }\n    } else {\n      pathPattern.append(DEFAULT_REG_EXP);\n    }\n    pathPattern.append(')');\n    this.varNames.add(varName.toString());\n  }\n\n  private int processColon(final String path, final int braceIndex, int state) throws Exception {\n    if (state == NAME_READ_START) {\n      throw new Exception(\n          \"The variable name at position must not be null at \"\n              + braceIndex + \" of \\\"\" + path + \"\\\"\");\n    }\n    if (state == NAME_READ || state == NAME_READ_READY) {\n      state = REGEXP_READ_START;\n    }\n    return state;\n  }\n\n  private int processLineBreak(int state) {\n    if (state == NAME_READ) {\n      state = NAME_READ_READY;\n    } else if (state == REGEXP_READ) {\n      state = REGEXP_READ_READY;\n    }\n    return state;\n  }\n\n  // 已知/customers/{id}/address/{id}\n  // @PathParam(\"id\") String addressId\n  // url:/customers/123/address/456\n  // 则addressId取值为456\n  // 即后面的总是覆盖前面的\n  public String match(String path, Map<String, String> varValues) {\n    Matcher matcher = pattern.matcher(path);\n    if (!matcher.matches()) {\n      return null;\n    }\n\n    for (int i = 1; i < matcher.groupCount(); i++) {\n      varValues.put(varNames.get(i - 1), matcher.group(i));\n    }\n\n    return matcher.group(matcher.groupCount());\n  }\n\n  @Override\n  public String toString() {\n    return this.pattern.pattern();\n  }\n\n  public boolean isStaticPath() {\n    return groupCount == 0;\n  }\n\n  public int getStaticCharCount() {\n    return staticCharCount;\n  }\n\n  public int getGroupCount() {\n    return groupCount;\n  }\n\n  public int getGroupWithRegExpCount() {\n    return groupWithRegExpCount;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/PathVarParamWriter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\n\n/**\n * Dynamically processing path\n */\npublic class PathVarParamWriter extends AbstractUrlParamWriter {\n  public PathVarParamWriter(RestParam param) {\n    this.param = param;\n  }\n\n  @Override\n  public void write(URLPathStringBuilder builder, Map<String, Object> args) throws Exception {\n    if (getParamValue(args) == null) {\n      throw new IllegalArgumentException(\"path parameter can not be null.\");\n    }\n    String encodedPathParam = encodeNotNullValue(getParamValue(args));\n    builder.appendPath(encodedPathParam);\n  }\n\n  private String encodeNotNullValue(Object value) throws Exception {\n    String strValue = RestObjectMapperFactory.getRestObjectMapper().convertToString(value);\n    return HttpUtils.encodePathParam(strValue);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/QueryVarParamWriter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodec;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\n\npublic class QueryVarParamWriter extends AbstractUrlParamWriter {\n  private final QueryCodec queryCodec;\n\n  public QueryVarParamWriter(RestParam param) {\n    this.param = param;\n    this.queryCodec = ((QueryProcessor) param.getParamProcessor()).getQueryCodec();\n  }\n\n  @Override\n  public void write(URLPathStringBuilder builder, Map<String, Object> args) throws Exception {\n    Object value = getParamValue(args);\n    queryCodec.encode(builder, param.getParamName(), value);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/StaticUrlParamWriter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\n\npublic class StaticUrlParamWriter implements UrlParamWriter {\n\n  private final String staticPath;\n\n  public StaticUrlParamWriter(String staticPath) {\n    this.staticPath = staticPath;\n  }\n\n  @Override\n  public void write(URLPathStringBuilder builder, Map<String, Object> args) {\n    builder.appendPath(staticPath);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/URLPathBuilder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\n\n/**\n * 初始化阶段创建URLPathBuilder，用于加速调用阶段的path创建\n */\npublic class URLPathBuilder {\n\n  private final List<UrlParamWriter> pathParamWriterList = new ArrayList<>();\n\n  private final List<UrlParamWriter> queryParamWriterList = new ArrayList<>();\n\n  private static final String SLASH = \"/\";\n\n  public URLPathBuilder(String rawPath, Map<String, RestParam> paramMap) {\n    initPathWriterList(rawPath, paramMap);\n    initQueryWriterList(paramMap);\n  }\n\n  private void initQueryWriterList(Map<String, RestParam> paramMap) {\n    for (RestParam param : paramMap.values()) {\n      if (!QueryProcessorCreator.PARAMTYPE.equals(param.getParamProcessor().getProcessorType())) {\n        continue;\n      }\n\n      UrlParamWriter dynamicWriter = new QueryVarParamWriter(param);\n      queryParamWriterList.add(dynamicWriter);\n    }\n  }\n\n  private void initPathWriterList(String rawPath, Map<String, RestParam> paramMap) {\n    // 首部加上'/'\n    if (!rawPath.startsWith(SLASH)) {\n      rawPath = SLASH + rawPath;\n    }\n\n    StringBuilder tmpPath = new StringBuilder();\n    for (int idx = 0; idx < rawPath.length(); idx++) {\n      char currentChar = rawPath.charAt(idx);\n      if (currentChar == '{') {\n        if (tmpPath.length() != 0) {\n          this.pathParamWriterList.add(new StaticUrlParamWriter(tmpPath.toString()));\n          tmpPath.setLength(0);\n        }\n      } else if (currentChar == '}') {\n        if (tmpPath.length() == 0) {\n          continue;\n        }\n        String tmpPathStr = tmpPath.toString();\n        String pathParamName = tmpPathStr;\n        if (tmpPathStr.contains(\":\")) {\n          pathParamName = tmpPathStr.split(\":\", 2)[0].trim();\n        }\n        RestParam param = paramMap.get(pathParamName);\n        this.pathParamWriterList.add(new PathVarParamWriter(param));\n        tmpPath.setLength(0);\n      } else {\n        tmpPath.append(currentChar);\n      }\n    }\n    if (tmpPath.length() != 0) {\n      this.pathParamWriterList.add(new StaticUrlParamWriter(tmpPath.toString()));\n    }\n  }\n\n  public String createRequestPath(Map<String, Object> args) throws Exception {\n    URLPathStringBuilder builder = new URLPathStringBuilder();\n\n    genPathString(builder, args);\n    genQueryString(builder, args);\n\n    return builder.build();\n  }\n\n  public String createPathString(Map<String, Object> args) throws Exception {\n    URLPathStringBuilder builder = new URLPathStringBuilder();\n    genPathString(builder, args);\n    return builder.build();\n  }\n\n  private void genPathString(URLPathStringBuilder builder, Map<String, Object> args) throws Exception {\n    for (UrlParamWriter writer : this.pathParamWriterList) {\n      writer.write(builder, args);\n    }\n  }\n\n  private void genQueryString(URLPathStringBuilder builder, Map<String, Object> args) throws Exception {\n    for (UrlParamWriter writer : queryParamWriterList) {\n      writer.write(builder, args);\n    }\n  }\n\n  public static class URLPathStringBuilder {\n    private final StringBuilder stringBuilder = new StringBuilder();\n\n    private boolean queryPrefixNotWrite = true;\n\n    public URLPathStringBuilder appendPath(String s) {\n      stringBuilder.append(s);\n      return this;\n    }\n\n    public URLPathStringBuilder appendQuery(String name, String encodedValue) {\n      if (queryPrefixNotWrite) {\n        stringBuilder.append('?');\n        queryPrefixNotWrite = false;\n      } else {\n        stringBuilder.append('&');\n      }\n\n      stringBuilder.append(name).append(\"=\").append(encodedValue);\n      return this;\n    }\n\n    public String build() {\n      return stringBuilder.toString();\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/path/UrlParamWriter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\n\npublic interface UrlParamWriter {\n  void write(URLPathStringBuilder builder, Map<String, Object> args) throws Exception;\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.filter.inner;\n\nimport static com.google.common.net.HttpHeaders.CONTENT_LENGTH;\nimport static com.google.common.net.HttpHeaders.TRANSFER_ENCODING;\nimport static org.apache.servicecomb.core.exception.Exceptions.toProducerResponse;\n\nimport java.io.IOException;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.common.rest.HttpTransportContext;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestCodec;\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.foundation.common.utils.PartUtils;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.TransportContext;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.reactivestreams.Publisher;\nimport org.reactivestreams.Subscriber;\nimport org.reactivestreams.Subscription;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\n\npublic class RestServerCodecFilter extends AbstractFilter implements ProviderFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestServerCodecFilter.class);\n\n  public static final String NAME = \"rest-server-codec\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    // almost time, should be the first filter.\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 2000;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.RESTFUL.equals(transport);\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    return CompletableFuture.completedFuture(invocation)\n        .thenAccept(this::decodeRequest)\n        .thenCompose(v -> invokeNext(invocation, nextNode))\n        .exceptionally(exception -> toProducerResponse(invocation, exception))\n        .thenCompose(response -> encodeResponse(invocation, response));\n  }\n\n  protected CompletableFuture<Response> invokeNext(Invocation invocation, FilterNode nextNode) {\n    if (invocation.isEdge()) {\n      TransportContext transportContext = invocation.getTransportContext();\n      return nextNode.onFilter(invocation).whenComplete((r, e) -> invocation.setTransportContext(transportContext));\n    }\n    return nextNode.onFilter(invocation);\n  }\n\n  protected void decodeRequest(Invocation invocation) {\n    invocation.getInvocationStageTrace().startProviderDecodeRequest();\n    HttpServletRequestEx requestEx = invocation.getRequestEx();\n\n    OperationMeta operationMeta = invocation.getOperationMeta();\n    RestOperationMeta restOperationMeta = operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);\n    Map<String, Object> swaggerArguments = RestCodec.restToArgs(requestEx, restOperationMeta);\n    invocation.setSwaggerArguments(swaggerArguments);\n    invocation.getInvocationStageTrace().finishProviderDecodeRequest();\n  }\n\n  protected CompletableFuture<Response> encodeResponse(Invocation invocation, Response response) {\n    invocation.onEncodeResponseStart(response);\n    HttpTransportContext transportContext = invocation.getTransportContext();\n    HttpServletResponseEx responseEx = transportContext.getResponseEx();\n    // TODO: response support JsonView\n    ProduceProcessor produceProcessor = ProduceProcessorManager.INSTANCE\n        .createProduceProcessor(invocation.getOperationMeta(), response.getStatusCode(),\n            invocation.getRequestEx().getHeader(HttpHeaders.ACCEPT), null);\n\n    return encodeResponse(invocation, response, produceProcessor, responseEx)\n        .whenComplete((r, e) -> invocation.onEncodeResponseFinish());\n  }\n\n  private static boolean isFailedResponse(Response response) {\n    return response.getResult() instanceof InvocationException;\n  }\n\n  private static CompletableFuture<Response> writePart(\n      HttpServletResponseEx responseEx, Object data, Response response) {\n    CompletableFuture<Response> result = new CompletableFuture<>();\n    responseEx.sendPart(PartUtils.getSinglePart(null, data))\n        .whenComplete((r, e) -> {\n          if (e != null) {\n            result.completeExceptionally(e);\n            return;\n          }\n          result.complete(response);\n        });\n    return result;\n  }\n\n  private static CompletableFuture<Response> writeResponse(\n      HttpServletResponseEx responseEx, ProduceProcessor produceProcessor, Object data, Response response,\n      boolean commit) {\n    try (BufferOutputStream output = new BufferOutputStream(Buffer.buffer())) {\n      produceProcessor.encodeResponse(output, data);\n\n      CompletableFuture<Response> result = new CompletableFuture<>();\n      responseEx.setBodyBuffer(output.getBuffer()); // For extensions usage\n      if (commit) {\n        responseEx.setContentLength(output.getBuffer().length());\n      }\n      responseEx.sendBuffer(output.getBuffer()).whenComplete((v, e) -> {\n        if (e != null) {\n          result.completeExceptionally(e);\n          return;\n        }\n        if (!commit) {\n          try {\n            responseEx.flushBuffer();\n          } catch (IOException ex) {\n            LOGGER.warn(\"Failed to flush buffer for Server Send Events\", ex);\n          }\n        }\n        result.complete(response);\n      });\n      return result;\n    } catch (Throwable e) {\n      LOGGER.error(\"internal service error must be fixed.\", e);\n      responseEx.setStatus(500);\n      return CompletableFuture.failedFuture(e);\n    }\n  }\n\n  public static CompletableFuture<Response> encodeResponse(Invocation invocation, Response response,\n      ProduceProcessor produceProcessor, HttpServletResponseEx responseEx) {\n    responseEx.setStatus(response.getStatusCode());\n    copyHeadersToHttpResponse(invocation, response.getHeaders(), responseEx);\n\n    if (isFailedResponse(response)) {\n      responseEx.setContentType(produceProcessor.getName());\n      return writeResponse(responseEx, produceProcessor, ((InvocationException) response.getResult()).getErrorData(),\n          response, true);\n    }\n\n    if (isDownloadFileResponseType(invocation, response)) {\n      return writePart(responseEx, response.getResult(), response);\n    }\n\n    if (isServerSendEvent(response)) {\n      responseEx.setContentType(produceProcessor.getName());\n      return writeServerSendEvent(response, produceProcessor, responseEx);\n    }\n\n    responseEx.setContentType(produceProcessor.getName());\n    return writeResponse(responseEx, produceProcessor, response.getResult(), response, true);\n  }\n\n  private static CompletableFuture<Response> writeServerSendEvent(Response response, ProduceProcessor produceProcessor,\n      HttpServletResponseEx responseEx) {\n    responseEx.setChunked(true);\n    CompletableFuture<Response> result = new CompletableFuture<>();\n    Publisher<?> publisher = response.getResult();\n    publisher.subscribe(new Subscriber<Object>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        s.request(1);\n        subscription = s;\n      }\n\n      @Override\n      public void onNext(Object o) {\n        writeResponse(responseEx, produceProcessor, o, response, false).whenComplete((r, e) -> {\n          if (e != null) {\n            subscription.cancel();\n            result.completeExceptionally(e);\n            return;\n          }\n          subscription.request(1);\n        });\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        result.completeExceptionally(t);\n      }\n\n      @Override\n      public void onComplete() {\n        result.complete(response);\n      }\n    });\n    return result;\n  }\n\n  /**\n   * Check whether this response is a downloaded file response,\n   * according to the schema recorded in {@link org.apache.servicecomb.swagger.invocation.response.ResponsesMeta}\n   * and response status code.\n   * @return true if this response is a downloaded file, otherwise false.\n   */\n  public static boolean isDownloadFileResponseType(Invocation invocation, Response response) {\n    return Part.class.isAssignableFrom(\n        invocation.findResponseType(response.getStatusCode()).getRawClass());\n  }\n\n  public static boolean isServerSendEvent(Response response) {\n    return response.getResult() instanceof Publisher<?>;\n  }\n\n  public static void copyHeadersToHttpResponse(Invocation invocation, MultiMap headers,\n      HttpServletResponseEx responseEx) {\n    if (headers != null) {\n      headers.remove(CONTENT_LENGTH);\n      headers.remove(TRANSFER_ENCODING);\n      for (Entry<String, String> entry : headers.entries()) {\n        responseEx.addHeader(entry.getKey(), entry.getValue());\n      }\n    }\n\n    if (invocation != null && responseEx.getHeader(CoreConst.TRACE_ID_NAME) == null) {\n      responseEx.addHeader(CoreConst.TRACE_ID_NAME, invocation.getTraceId());\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/WebSocketServerCodecFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.filter.inner;\n\nimport static org.apache.servicecomb.core.exception.Exceptions.toProducerResponse;\n\nimport java.util.HashMap;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.common.rest.WebSocketTransportContext;\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceJsonProcessor;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.TransportContext;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class WebSocketServerCodecFilter extends AbstractFilter implements ProviderFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServerCodecFilter.class);\n\n  public static final String NAME = \"websocket-codec\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    // almost time, should be the first filter.\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 2000;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.WEBSOCKET.equals(transport);\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    return CompletableFuture.completedFuture(invocation)\n        .thenCompose(this::decodeRequest)\n        .thenCompose(v -> invokeNext(invocation, nextNode))\n        .exceptionally(exception -> toProducerResponse(invocation, exception))\n        .thenCompose(response -> encodeResponse(invocation, response));\n  }\n\n  protected CompletableFuture<Response> invokeNext(Invocation invocation, FilterNode nextNode) {\n    if (invocation.isEdge()) {\n      TransportContext transportContext = invocation.getTransportContext();\n      return nextNode.onFilter(invocation).whenComplete((r, e) -> invocation.setTransportContext(transportContext));\n    }\n    return nextNode.onFilter(invocation);\n  }\n\n  protected CompletableFuture<Void> decodeRequest(Invocation invocation) {\n    invocation.getInvocationStageTrace().startProviderDecodeRequest();\n    invocation.setSwaggerArguments(new HashMap<>()); // set context parameters and do nothing else.\n    invocation.getInvocationStageTrace().finishProviderDecodeRequest();\n    return CompletableFuture.completedFuture(null);\n  }\n\n  protected CompletableFuture<Response> encodeResponse(Invocation invocation, Response response) {\n    invocation.onEncodeResponseStart(response);\n    WebSocketTransportContext context = invocation.getTransportContext();\n\n    return encodeResponse(response, context.getServerWebSocket())\n        .whenComplete((r, e) -> invocation.onEncodeResponseFinish());\n  }\n\n  private static boolean isFailedResponse(Response response) {\n    return response.getResult() instanceof InvocationException;\n  }\n\n  private static CompletableFuture<Response> writeResponse(\n      ServerWebSocket webSocket, Object data, Response response) {\n    try (BufferOutputStream output = new BufferOutputStream(Buffer.buffer())) {\n      ProduceJsonProcessor produceProcessor = new ProduceJsonProcessor();\n      produceProcessor.encodeResponse(output, data);\n      CompletableFuture<Response> result = new CompletableFuture<>();\n      webSocket.write(output.getBuffer()).onComplete(v ->\n          result.complete(response), result::completeExceptionally);\n\n      return result;\n    } catch (Throwable e) {\n      LOGGER.error(\"internal service error must be fixed.\", e);\n      return CompletableFuture.failedFuture(e);\n    }\n  }\n\n  public static CompletableFuture<Response> encodeResponse(Response response, ServerWebSocket webSocket) {\n    if (isFailedResponse(response)) {\n      return writeResponse(webSocket, ((InvocationException) response.getResult()).getErrorData(),\n          response);\n    }\n    return CompletableFuture.completedFuture(response);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/MicroservicePaths.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.locator;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationComparator;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class MicroservicePaths {\n  private static final Logger LOGGER = LoggerFactory.getLogger(MicroservicePaths.class);\n\n  // 运行阶段,静态path,一次直接查找到目标,不必遍历查找\n  // 以path为key\n  protected Map<String, OperationGroup> staticPathOperations = new HashMap<>();\n\n  // 运行阶段,以path优先级,从高到低排列的operation列表\n  protected List<RestOperationMeta> dynamicPathOperationsList = new ArrayList<>();\n\n  public void sortPath() {\n    RestOperationComparator comparator = new RestOperationComparator();\n    this.dynamicPathOperationsList.sort(comparator);\n  }\n\n  public void addResource(RestOperationMeta swaggerRestOperation) {\n    if (swaggerRestOperation.isAbsoluteStaticPath()) {\n      // 静态path\n      addStaticPathResource(swaggerRestOperation);\n      return;\n    }\n\n    dynamicPathOperationsList.add(swaggerRestOperation);\n  }\n\n  protected void addStaticPathResource(RestOperationMeta operation) {\n    String httpMethod = operation.getHttpMethod();\n    String path = OperationLocator.getStandardPath(operation.getAbsolutePath());\n    OperationGroup group = staticPathOperations.get(path);\n    if (group == null) {\n      group = new OperationGroup();\n      group.register(httpMethod, operation);\n      staticPathOperations.put(path, group);\n      return;\n    }\n\n    if (group.findValue(httpMethod) == null) {\n      group.register(httpMethod, operation);\n      return;\n    }\n\n    throw new ServiceCombException(\n        String.format(\"operation with url %s, method %s is duplicated.\", path, httpMethod));\n  }\n\n  public Map<String, OperationGroup> getStaticPathOperationMap() {\n    return staticPathOperations;\n  }\n\n  public List<RestOperationMeta> getDynamicPathOperationList() {\n    return dynamicPathOperationsList;\n  }\n\n  public void printPaths() {\n    for (Entry<String, OperationGroup> entry : staticPathOperations.entrySet()) {\n      OperationGroup operationGroup = entry.getValue();\n      printPath(operationGroup.values());\n    }\n\n    printPath(getDynamicPathOperationList());\n  }\n\n  protected void printPath(Collection<RestOperationMeta> operations) {\n    for (RestOperationMeta operation : operations) {\n      SwaggerProducerOperation producerOperation = operation.getOperationMeta().getSwaggerProducerOperation();\n\n      LOGGER.debug(\"Swagger mapped \\\"{[{}], method=[{}]}\\\" onto {}\",\n          operation.getAbsolutePath(),\n          operation.getHttpMethod(),\n          producerOperation.getProducerMethod());\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/OperationGroup.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.locator;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.foundation.common.RegisterManager;\n\n/**\n * 存放具有相同path，不同httpmethod的operation\n */\npublic class OperationGroup extends RegisterManager<String, RestOperationMeta> {\n  private static final String NAME = \"operation group manager\";\n\n  public OperationGroup() {\n    super(NAME);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/OperationLocator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.locator;\n\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport jakarta.ws.rs.core.Response.Status;\n\n/**\n * 从path和http method定位到具体的operation\n */\npublic class OperationLocator {\n  private static final Logger LOGGER = LoggerFactory.getLogger(OperationLocator.class);\n\n  private static final String SLASH = \"/\";\n\n  protected RestOperationMeta operation;\n\n  protected Map<String, String> pathVarMap = new HashMap<>();\n\n  protected boolean resourceFound = false;\n\n  public RestOperationMeta getOperation() {\n    return this.operation;\n  }\n\n  public Map<String, String> getPathVarMap() {\n    return this.pathVarMap;\n  }\n\n  // 先在静态路径operation list中查找；如果找不到，则在动态路径operation list中查找\n  public void locate(String microserviceName, String path, String httpMethod, MicroservicePaths microservicePaths) {\n    // 在静态路径中查找\n    operation = locateStaticPathOperation(path, httpMethod, microservicePaths.getStaticPathOperationMap());\n    if (operation != null) {\n      // 全部定位完成\n      return;\n    }\n\n    // 在动态路径中查找\n    operation = locateDynamicPathOperation(path, microservicePaths.getDynamicPathOperationList(), httpMethod);\n    if (operation != null) {\n      return;\n    }\n\n    Status status = Status.NOT_FOUND;\n    if (resourceFound) {\n      status = Status.METHOD_NOT_ALLOWED;\n    }\n    LOGGER.error(\"locate path failed, status:{}, http method:{}, path:{}, microserviceName:{}\",\n        status,\n        httpMethod,\n        path,\n        microserviceName);\n    throw new InvocationException(status, status.getReasonPhrase());\n  }\n\n  protected RestOperationMeta locateStaticPathOperation(String path, String httpMethod,\n      Map<String, OperationGroup> staticPathOperations) {\n    OperationGroup group = staticPathOperations.get(path);\n    if (group == null) {\n      return null;\n    }\n\n    resourceFound = true;\n    return group.findValue(httpMethod);\n  }\n\n  protected RestOperationMeta locateDynamicPathOperation(String path, Collection<RestOperationMeta> resourceList,\n      String httpMethod) {\n    for (RestOperationMeta resource : resourceList) {\n      String remainPath = resource.getAbsolutePathRegExp().match(path, pathVarMap);\n      // 刚好匹配，不多也不少\n      if (\"\".equals(remainPath)) {\n        resourceFound = true;\n        if (checkHttpMethod(resource, httpMethod)) {\n          return resource;\n        }\n      }\n    }\n    return null;\n  }\n\n  protected boolean checkHttpMethod(RestOperationMeta operation, String httpMethod) {\n    return operation.getHttpMethod().equals(httpMethod);\n  }\n\n  // Make path standard in order to build path mapping and find path operation.\n  // NOTE: Path: /a/b/c -> /a/b/c/. Almost change path every time, this make performance lower.\n  public static String getStandardPath(String path) {\n    if (path.length() > 0 && !path.endsWith(SLASH)) {\n      path += SLASH;\n    }\n    return path;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/locator/ServicePathManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.locator;\n\nimport java.util.Collection;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\n\n\n/**\n * 对静态路径和动态路径的operation进行预先处理，加速operation的查询定位\n */\npublic class ServicePathManager {\n  private static final String REST_PATH_MANAGER = \"RestServicePathManager\";\n\n  protected MicroserviceMeta microserviceMeta;\n\n  // equal to swagger\n  protected MicroservicePaths swaggerPaths = new MicroservicePaths();\n\n  // we support swagger basePath is not include contextPath and urlPattern\n  // so for producer, we must concat contextPath and urlPattern\n  // only valid for microservice of this process\n  protected MicroservicePaths producerPaths;\n\n  public static ServicePathManager getServicePathManager(MicroserviceMeta microserviceMeta) {\n    return microserviceMeta.getExtData(REST_PATH_MANAGER);\n  }\n\n  public ServicePathManager(MicroserviceMeta microserviceMeta) {\n    this.microserviceMeta = microserviceMeta;\n\n    for (SchemaMeta schemaMeta : microserviceMeta.getSchemaMetas().values()) {\n      addSchema(schemaMeta);\n    }\n    sortPath();\n\n    microserviceMeta.putExtData(REST_PATH_MANAGER, this);\n  }\n\n  private void addSchema(SchemaMeta schemaMeta) {\n    for (OperationMeta operationMeta : schemaMeta.getOperations().values()) {\n      RestOperationMeta restOperationMeta = new RestOperationMeta();\n      restOperationMeta.init(operationMeta);\n      operationMeta.putExtData(RestConst.SWAGGER_REST_OPERATION, restOperationMeta);\n      addResource(restOperationMeta);\n    }\n  }\n\n  public OperationLocator consumerLocateOperation(String path, String httpMethod) {\n    String standPath = OperationLocator.getStandardPath(path);\n    OperationLocator locator = new OperationLocator();\n    locator.locate(microserviceMeta.getMicroserviceName(), standPath, httpMethod, swaggerPaths);\n\n    return locator;\n  }\n\n  public OperationLocator producerLocateOperation(String path, String httpMethod) {\n    String standPath = OperationLocator.getStandardPath(path);\n    OperationLocator locator = new OperationLocator();\n    locator.locate(microserviceMeta.getMicroserviceName(), standPath, httpMethod, producerPaths);\n\n    return locator;\n  }\n\n  public void addResource(RestOperationMeta swaggerRestOperation) {\n    swaggerPaths.addResource(swaggerRestOperation);\n  }\n\n  public void sortPath() {\n    swaggerPaths.sortPath();\n  }\n\n  public void buildProducerPaths() {\n    String urlPrefix = ClassLoaderScopeContext.getClassLoaderScopeProperty(DefinitionConst.URL_PREFIX);\n    if (StringUtils.isEmpty(urlPrefix)) {\n      producerPaths = swaggerPaths;\n      producerPaths.printPaths();\n      return;\n    }\n\n    producerPaths = new MicroservicePaths();\n    for (OperationGroup operationGroup : swaggerPaths.getStaticPathOperationMap().values()) {\n      addProducerPaths(urlPrefix, operationGroup.values());\n    }\n\n    addProducerPaths(urlPrefix, swaggerPaths.getDynamicPathOperationList());\n    producerPaths.printPaths();\n  }\n\n  private void addProducerPaths(String urlPrefix, Collection<RestOperationMeta> restOperationMetas) {\n    for (RestOperationMeta swaggerRestOperation : restOperationMetas) {\n      RestOperationMeta producerRestOperation = swaggerRestOperation;\n      if (!swaggerRestOperation.getAbsolutePath().startsWith(urlPrefix)) {\n        producerRestOperation = new RestOperationMeta();\n        producerRestOperation.init(swaggerRestOperation.getOperationMeta());\n        producerRestOperation.setAbsolutePath(urlPrefix + swaggerRestOperation.getAbsolutePath());\n      }\n      producerPaths.addResource(producerRestOperation);\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/resource/ClassPathStaticResourceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.resource;\n\nimport java.io.IOException;\nimport java.net.URL;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.InputStreamPart;\n\npublic class ClassPathStaticResourceHandler extends StaticResourceHandler {\n  protected Part findResource(String path) throws IOException {\n    URL url = this.getClass().getClassLoader().getResource(path);\n    if (url == null) {\n      return null;\n    }\n\n    return new InputStreamPart(null, url.openStream()).setSubmittedFileName(path);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/resource/StaticResourceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.resource;\n\nimport java.io.IOException;\nimport java.net.URI;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n// TODO: LRU cache for small resource in jar?\npublic abstract class StaticResourceHandler {\n  private static final Logger LOGGER = LoggerFactory.getLogger(StaticResourceHandler.class);\n\n  private String webRoot = \"webroot/\";\n\n  public void setWebRoot(String webRoot) {\n    this.webRoot = webRoot;\n  }\n\n  protected abstract Part findResource(String path) throws IOException;\n\n  public Response handle(String path) {\n    path = URI.create(webRoot + path).normalize().getPath();\n    if (!path.startsWith(webRoot)) {\n      // maybe request of attack, just return 404\n      return Response.failResp(new InvocationException(Status.NOT_FOUND, Status.NOT_FOUND.getReasonPhrase()));\n    }\n\n    Part part;\n    try {\n      part = findResource(path);\n    } catch (Throwable e) {\n      LOGGER.error(\"failed to process static resource, path={}\", path, e);\n      return Response\n          .failResp(new InvocationException(Status.INTERNAL_SERVER_ERROR, \"failed to process static resource.\"));\n    }\n\n    if (part == null) {\n      return Response.failResp(new InvocationException(Status.NOT_FOUND, Status.NOT_FOUND.getReasonPhrase()));\n    }\n\n    return handler(part);\n  }\n\n  public Response handler(Part part) {\n    // todo: cache control\n    Response response = Response.ok(part);\n    response.setHeader(HttpHeaders.CONTENT_TYPE, part.getContentType());\n    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, \"inline\");\n    return response;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/route/URLMappedConfigurationItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.route;\n\nimport java.util.regex.Pattern;\n\npublic class URLMappedConfigurationItem {\n  private String microserviceName;\n\n  private String versionRule;\n\n  private int prefixSegmentCount;\n\n  private Pattern pattern;\n\n  private String stringPattern;\n\n  public String getMicroserviceName() {\n    return microserviceName;\n  }\n\n  public void setMicroserviceName(String microserviceName) {\n    this.microserviceName = microserviceName;\n  }\n\n  public String getVersionRule() {\n    return versionRule;\n  }\n\n  public void setVersionRule(String versionRule) {\n    this.versionRule = versionRule;\n  }\n\n  public int getPrefixSegmentCount() {\n    return prefixSegmentCount;\n  }\n\n  public void setPrefixSegmentCount(int prefixSegmentCount) {\n    this.prefixSegmentCount = prefixSegmentCount;\n  }\n\n  public Pattern getPattern() {\n    return pattern;\n  }\n\n  public void setPattern(Pattern pattern) {\n    this.pattern = pattern;\n  }\n\n  public String getStringPattern() {\n    return stringPattern;\n  }\n\n  public void setStringPattern(String stringPattern) {\n    this.stringPattern = stringPattern;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/route/URLMappedConfigurationLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.route;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.regex.Pattern;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.Environment;\n\npublic class URLMappedConfigurationLoader {\n  private static final Logger LOG = LoggerFactory.getLogger(URLMappedConfigurationLoader.class);\n\n  private static final String KEY_MAPPING_PATH = \".path\";\n\n  private static final String KEY_MAPPING_SERVICE_NAME = \"%s.%s.microserviceName\";\n\n  private static final String KEY_MAPPING_VERSION_RULE = \"%s.%s.versionRule\";\n\n  private static final String KEY_MAPPING_PREFIX_SEGMENT_COUNT = \"%s.%s.prefixSegmentCount\";\n\n  public static Map<String, URLMappedConfigurationItem> loadConfigurations(\n      Environment environment, String configPrefix) {\n    Map<String, URLMappedConfigurationItem> configurations = new HashMap<>();\n    Set<String> configsItems = ConfigUtil.propertiesWithPrefix((ConfigurableEnvironment) environment, configPrefix);\n    for (String pathKey : configsItems) {\n      if (pathKey.endsWith(KEY_MAPPING_PATH)) {\n        URLMappedConfigurationItem configurationItem = new URLMappedConfigurationItem();\n        String pattern = environment.getProperty(pathKey);\n        if (StringUtils.isEmpty(pattern)) {\n          continue;\n        }\n        configurationItem.setPattern(Pattern.compile(pattern));\n        configurationItem.setStringPattern(pattern);\n        String pathKeyItem = pathKey\n            .substring(configPrefix.length() + 1, pathKey.length() - KEY_MAPPING_PATH.length());\n        configurationItem.setMicroserviceName(environment.getProperty(\n            String.format(KEY_MAPPING_SERVICE_NAME, configPrefix, pathKeyItem)));\n        if (StringUtils.isEmpty(configurationItem.getMicroserviceName())) {\n          continue;\n        }\n        configurationItem.setPrefixSegmentCount(environment.getProperty(\n            String.format(KEY_MAPPING_PREFIX_SEGMENT_COUNT, configPrefix, pathKeyItem), int.class, 0));\n        configurationItem.setVersionRule(environment.getProperty(\n            String.format(KEY_MAPPING_VERSION_RULE, configPrefix, pathKeyItem), \"0.0.0+\"));\n        configurations.put(pathKeyItem, configurationItem);\n      }\n    }\n    logConfigurations(configurations);\n    return configurations;\n  }\n\n  private static void logConfigurations(Map<String, URLMappedConfigurationItem> configurations) {\n    configurations.forEach((key, item) -> LOG.info(\"config item: key=\" + key + \";pattern=\" + item.getStringPattern()\n        + \";service=\" + item.getMicroserviceName() + \";versionRule=\" + item.getVersionRule()));\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/java/org/apache/servicecomb/common/rest/route/Utils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.route;\n\n/**\n * Commonly used methods in this package.\n */\npublic final class Utils {\n  private Utils() {\n\n  }\n\n  /**\n   * Get the actual path without prefix\n   * @param path full path\n   * @param pathIndex the index of / that after prefix\n   * @return actual path\n   */\n  public static String findActualPath(String path, int pathIndex) {\n    if (pathIndex <= 0) {\n      return path;\n    }\n\n    int fromIndex = 0;\n    int counter = pathIndex;\n    char[] chars = path.toCharArray();\n    for (int i = 0; i < chars.length; i++) {\n      if (chars[i] == '/') {\n        if (--counter < 0) {\n          fromIndex = i;\n          break;\n        }\n      }\n    }\n    return fromIndex > 0 ? path.substring(fromIndex) : \"\";\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.foundation.common.utils.json.PartModule\n"
  },
  {
    "path": "common/common-rest/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.common.rest.codec.produce.ProduceJsonProcessor\norg.apache.servicecomb.common.rest.codec.produce.ProduceTextPlainProcessor\n"
  },
  {
    "path": "common/common-rest/src/main/resources/META-INF/services/org.apache.servicecomb.core.filter.FilterProvider",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.common.rest.filter.RestFilterProvider\n"
  },
  {
    "path": "common/common-rest/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.common.rest.CommonRestConfiguration\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreatorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport static jakarta.ws.rs.core.Response.Status.NOT_FOUND;\nimport static org.apache.servicecomb.common.rest.RestConst.DECODE_INVOCATION_CONTEXT;\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.SCBStatus;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.json.Json;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class RestProducerInvocationCreatorTest {\n\n  final RoutingContext routingContext = Mockito.mock(RoutingContext.class);\n\n  final MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n\n  final ServicePathManager servicePathManager = Mockito.mock(ServicePathManager.class);\n\n  final RestOperationMeta restOperationMeta = Mockito.mock(RestOperationMeta.class);\n\n  final Endpoint endpoint = Mockito.mock(Endpoint.class);\n\n  final HttpServletRequestEx requestEx = Mockito.mock(HttpServletRequestEx.class);\n\n  final HttpServletResponseEx responseEx = Mockito.mock(HttpServletResponseEx.class);\n\n  final OperationLocator locator = Mockito.mock(OperationLocator.class);\n\n  final InvocationRuntimeType invocationRuntimeType = Mockito.mock(InvocationRuntimeType.class);\n\n  final OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n\n  final SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n\n  RestProducerInvocationCreator creator;\n\n  static SCBEngine engine;\n\n  static Environment environment;\n\n  @BeforeAll\n  public static void beforeClass() {\n    environment = Mockito.mock(Environment.class);\n    engine = SCBBootstrap.createSCBEngineForTest(environment);\n    engine.setStatus(SCBStatus.UP);\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    engine.setEnvironment(environment);\n  }\n\n  @AfterAll\n  public static void afterClass() {\n    engine.destroy();\n  }\n\n  @BeforeEach\n  public void setUp() {\n    creator = new RestVertxProducerInvocationCreator(routingContext, microserviceMeta, endpoint,\n        requestEx, responseEx);\n    creator = Mockito.spy(creator);\n  }\n\n  @Test\n  public void should_failed_when_not_defined_any_schema() {\n    try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {\n      mockedStatic.when(() -> ServicePathManager.getServicePathManager(null)).thenReturn(servicePathManager);\n\n      InvocationException throwable = (InvocationException) catchThrowable(() -> creator.createAsync().join());\n      CommonExceptionData data = (CommonExceptionData) throwable.getErrorData();\n\n      assertThat(throwable.getStatusCode()).isEqualTo(NOT_FOUND.getStatusCode());\n      assertThat(Json.encode(data)).isIn(\"{\\\"code\\\":\\\"SCB.00000002\\\",\\\"message\\\":\\\"Not Found\\\"}\",\n          \"{\\\"message\\\":\\\"Not Found\\\",\\\"code\\\":\\\"SCB.00000002\\\"}\");\n    }\n  }\n\n  @Test\n  public void should_save_requestEx_in_invocation_context() {\n    try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {\n      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))\n          .thenReturn(servicePathManager);\n      Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);\n      Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);\n      Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);\n      Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);\n      Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n      Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n\n      Invocation invocation = creator.createAsync().join();\n\n      Object request = invocation.getLocalContext(RestConst.REST_REQUEST);\n      assertThat(request).isSameAs(requestEx);\n    }\n  }\n\n  @Test\n  public void should_save_path_var_map_in_requestEx() {\n    try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {\n      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))\n          .thenReturn(servicePathManager);\n      Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);\n      Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);\n      Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);\n      Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);\n      Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n      Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n\n      creator.createAsync().join();\n\n      Mockito.verify(requestEx, Mockito.times(1)).setAttribute(Mockito.eq(RestConst.PATH_PARAMETERS), Mockito.any());\n    }\n  }\n\n  @Test\n  public void should_merge_invocation_context_from_request() {\n    Mockito.when(environment.getProperty(DECODE_INVOCATION_CONTEXT, boolean.class, true))\n        .thenReturn(true);\n    try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {\n      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))\n          .thenReturn(servicePathManager);\n      Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);\n      Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);\n      Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);\n      Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);\n      Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n      Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n      Mockito.when(requestEx.getHeader(CoreConst.CSE_CONTEXT)).thenReturn(\"{\\\"k\\\":\\\"v\\\"}\");\n\n      Invocation invocation = creator.createAsync().join();\n\n      assertThat(invocation.getContext(\"k\")).isEqualTo(\"v\");\n    }\n  }\n\n  @Test\n  public void should_not_merge_invocation_context_from_request() {\n    Mockito.when(environment.getProperty(DECODE_INVOCATION_CONTEXT, boolean.class, true))\n        .thenReturn(false);\n    try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {\n      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))\n          .thenReturn(servicePathManager);\n      Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);\n      Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);\n      Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);\n      Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);\n      Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n      Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n      Mockito.when(requestEx.getHeader(CoreConst.CSE_CONTEXT)).thenReturn(\"{\\\"k\\\":\\\"v\\\"}\");\n\n      Invocation invocation = creator.createAsync().join();\n\n      assertThat(invocation.getContext(\"k\")).isNull();\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestDefPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport org.apache.servicecomb.common.rest.definition.path.PathRegExp;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestDefPath {\n\n  @Test\n  public void testPathRegExp() throws Exception {\n    PathRegExp oPathRegExp = new PathRegExp(\"//{test}//\");\n    Assertions.assertEquals(1, oPathRegExp.getGroupCount());\n    Assertions.assertEquals(0, oPathRegExp.getGroupWithRegExpCount());\n    PathRegExp oSecondPathRegExp = new PathRegExp(\"{[^/:]+?}\");\n    Assertions.assertEquals(1, oSecondPathRegExp.getGroupCount());\n    Assertions.assertEquals(1, oSecondPathRegExp.getGroupWithRegExpCount());\n    Assertions.assertEquals(\"test/\", PathRegExp.ensureEndWithSlash(\"test/\"));\n    Assertions.assertEquals(\"test/\", PathRegExp.ensureEndWithSlash(\"test\"));\n    Assertions.assertNull(oSecondPathRegExp.match(\"{test/test}\", null));\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestRestEngineSchemaListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.common.rest.locator.TestPathSchema;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestRestEngineSchemaListener {\n  static SCBEngine scbEngine;\n\n  static ServicePathManager spm;\n\n  @BeforeAll\n  public static void setup() {\n    Environment environment = Mockito.mock(Environment.class);\n    scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    scbEngine.setTransportManager(transportManager);\n    scbEngine.setExecutorManager(executorManager);\n    scbEngine.setEnvironment(environment);\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION))\n        .thenReturn(BootStrapProperties.DEFAULT_APPLICATION);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_NAME);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_ENVIRONMENT))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_ENVIRONMENT);\n\n    List<BootListener> listeners = new ArrayList<>();\n    listeners.add(new RestEngineSchemaListener());\n    scbEngine.setBootListeners(listeners);\n    scbEngine.addProducerMeta(\"sid1\", new TestPathSchema())\n        .run();\n    spm = ServicePathManager.getServicePathManager(scbEngine.getProducerMicroserviceMeta());\n  }\n\n  @AfterAll\n  public static void teardown() {\n    scbEngine.destroy();\n  }\n\n  @Test\n  public void testLocateNotFound() {\n    InvocationException exception = Assertions.assertThrows(InvocationException.class,\n        () -> spm.producerLocateOperation(\"/notExist\", \"GET\"));\n    Assertions.assertEquals(\"InvocationException: code=404;msg=CommonExceptionData [message=Not Found]\",\n        exception.getMessage());\n  }\n\n  @Test\n  public void testLocateNotFoundDynamicRemained() {\n    InvocationException exception = Assertions.assertThrows(InvocationException.class,\n        () -> spm.producerLocateOperation(\"/dynamic/1/2\", \"GET\"));\n    Assertions.assertEquals(\"InvocationException: code=404;msg=CommonExceptionData [message=Not Found]\",\n        exception.getMessage());\n  }\n\n  @Test\n  public void testLocateStaticMethodNotAllowed() {\n    InvocationException exception = Assertions.assertThrows(InvocationException.class,\n        () -> spm.producerLocateOperation(\"/staticEx\", \"POST\"));\n    Assertions.assertEquals(\"InvocationException: code=405;msg=CommonExceptionData [message=Method Not Allowed]\",\n        exception.getMessage());\n  }\n\n  @Test\n  public void testLocateDynamicMethodNotAllowed() {\n    InvocationException exception = Assertions.assertThrows(InvocationException.class,\n        () -> spm.producerLocateOperation(\"/dynamic/1\", \"POST\"));\n    Assertions.assertEquals(\"InvocationException: code=405;msg=CommonExceptionData [message=Method Not Allowed]\",\n        exception.getMessage());\n  }\n\n  @Test\n  public void testLocateStaticFound() {\n    Assertions.assertNotNull(spm.producerLocateOperation(\"/staticEx\", \"GET\"));\n  }\n\n  @Test\n  public void testLocateDynamicFound() {\n    OperationLocator locator = spm.producerLocateOperation(\"/dynamic/1\", \"GET\");\n    Assertions.assertEquals(\"1\", locator.getPathVarMap().get(\"id\"));\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/PojoModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec;\n\npublic class PojoModel {\n  private String name;\n\n  private String desc;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getDesc() {\n    return desc;\n  }\n\n  public void setDesc(String desc) {\n    this.desc = desc;\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.param.ParamValueProcessor;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.HeaderParameter;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class TestRestCodec {\n\n  private static RestOperationMeta restOperation;\n\n  private static List<RestParam> paramList = null;\n\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.header.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n\n    Parameter hp = new HeaderParameter();\n    hp.setName(\"header\");\n    hp.setSchema(new Schema<>());\n    RestParam restParam = new RestParam(null, hp, int.class);\n\n    restOperation = Mockito.mock(RestOperationMeta.class);\n    paramList = new ArrayList<>();\n\n    paramList.add(restParam);\n    Mockito.when(restOperation.getParamList()).thenReturn(paramList);\n    Mockito.when(restOperation.getParamByName(\"test\")).thenReturn(restParam);\n  }\n\n  @AfterAll\n  public static void afterClass() {\n    restOperation = null;\n    paramList.clear();\n  }\n\n  @Test\n  public void testRestToArgs() throws Exception {\n    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n    RestOperationMeta restOperation = Mockito.mock(RestOperationMeta.class);\n    RestParam restParam = Mockito.mock(RestParam.class);\n    ParamValueProcessor processor = Mockito.mock(ParamValueProcessor.class);\n    List<RestParam> params = new ArrayList<>();\n    params.add(restParam);\n    String s = \"my\";\n    Mockito.when(restOperation.getParamList()).thenReturn(params);\n    Mockito.when(restParam.getParamProcessor()).thenReturn(processor);\n    Mockito.when(processor.getValue(request)).thenReturn(s);\n    Mockito.when(restParam.getParamName()).thenReturn(\"test\");\n\n    Map<String, Object> xx = RestCodec.restToArgs(request, restOperation);\n    Assertions.assertEquals(xx.get(\"test\"), s);\n  }\n\n  @Test\n  public void testRestToArgsException() throws Exception {\n    ParamValueProcessor processor = Mockito.mock(ParamValueProcessor.class);\n    Mockito.when(processor.getValue(Mockito.any())).thenThrow(new Exception(\"bad request parame\"));\n\n    RestOperationMeta restOperation = Mockito.mock(RestOperationMeta.class);\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(restParam.getParamProcessor()).thenReturn(processor);\n\n    List<RestParam> params = new ArrayList<>();\n    params.add(restParam);\n    Mockito.when(restOperation.getParamList()).thenReturn(params);\n\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(restOperation.getOperationMeta()).thenReturn(operationMeta);\n\n    boolean success = false;\n    try {\n      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n      RestCodec.restToArgs(request, restOperation);\n      success = true;\n    } catch (InvocationException e) {\n      Assertions.assertEquals(400, e.getStatusCode());\n      Assertions.assertTrue(e.getMessage().contains(\"Parameter is not valid\"));\n    }\n    Assertions.assertFalse(success);\n  }\n\n  @Test\n  public void testRestToArgsInstanceException() throws Exception {\n    InvocationException exception = new InvocationException(Status.BAD_REQUEST, \"Parameter is not valid.\");\n    ParamValueProcessor processor = Mockito.mock(ParamValueProcessor.class);\n    Mockito.when(processor.getValue(Mockito.any())).thenThrow(exception);\n\n    RestOperationMeta restOperation = Mockito.mock(RestOperationMeta.class);\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(restParam.getParamProcessor()).thenReturn(processor);\n\n    List<RestParam> params = new ArrayList<>();\n    params.add(restParam);\n    Mockito.when(restOperation.getParamList()).thenReturn(params);\n\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(restOperation.getOperationMeta()).thenReturn(operationMeta);\n\n    boolean success = false;\n    try {\n      HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n      RestCodec.restToArgs(request, restOperation);\n      success = true;\n    } catch (InvocationException e) {\n      Assertions.assertEquals(e.getStatusCode(), Status.BAD_REQUEST.getStatusCode());\n      Assertions.assertTrue(((CommonExceptionData) e.getErrorData()).getMessage()\n          .contains(\"Parameter is not valid for operation\"));\n    }\n    Assertions.assertFalse(success);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestObjectMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\nimport java.util.Date;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.core.exc.StreamConstraintsException;\nimport com.google.common.base.Strings;\nimport org.apache.servicecomb.foundation.common.utils.RestObjectMapper;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.core.JsonParser.Feature;\nimport com.fasterxml.jackson.databind.DeserializationFeature;\nimport com.fasterxml.jackson.databind.MapperFeature;\nimport com.fasterxml.jackson.databind.exc.MismatchedInputException;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.vertx.core.json.JsonObject;\nimport org.junit.jupiter.api.Test;\n\npublic class TestRestObjectMapper {\n\n  @Test\n  public void testFormatDate() throws Exception {\n    RestObjectMapper mapper = new RestObjectMapper();\n    // must read/write ISO 8061 dates\n    Date date = mapper.readValue(\"\\\"2017-07-21T17:32:28Z\\\"\".getBytes(), Date.class);\n    String dateStr = mapper.writeValueAsString(date);\n    Assertions.assertEquals(dateStr, \"\\\"2017-07-21T17:32:28.000+00:00\\\"\");\n\n    date = mapper.readValue(\"\\\"2017-07-21T17:32:28.320+0100\\\"\".getBytes(), Date.class);\n    dateStr = mapper.writeValueAsString(date);\n    Assertions.assertEquals(dateStr, \"\\\"2017-07-21T16:32:28.320+00:00\\\"\"); // one hour later\n  }\n\n  @Test\n  public void testAutoCloseSource() {\n    Assertions.assertFalse(RestObjectMapperFactory.getRestObjectMapper().getFactory().isEnabled(Feature.AUTO_CLOSE_SOURCE));\n  }\n\n  @Test\n  public void testDeserializationFeature() {\n    Assertions.assertFalse(\n        RestObjectMapperFactory.getRestObjectMapper().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));\n  }\n\n  @Test\n  public void testDefaultViewInclusionFeature() {\n    Assertions.assertFalse(RestObjectMapperFactory.getRestObjectMapper().isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION));\n  }\n\n  @Test\n  public void testJsonObjectWork() {\n    JsonObject obj = new JsonObject();\n    obj.put(\"name\", \"a\");\n    obj.put(\"desc\", \"b\");\n    PojoModel model = RestObjectMapperFactory.getRestObjectMapper()\n        .convertValue(obj, TypeFactory.defaultInstance().constructType(PojoModel.class));\n    Assertions.assertEquals(\"a\", model.getName());\n    Assertions.assertEquals(\"b\", model.getDesc());\n\n    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapper());\n    model = RestObjectMapperFactory.getRestObjectMapper()\n        .convertValue(obj, TypeFactory.defaultInstance().constructType(PojoModel.class));\n    Assertions.assertEquals(\"a\", model.getName());\n    Assertions.assertEquals(\"b\", model.getDesc());\n\n    InputStream inputStream = new ByteArrayInputStream(new byte[0]);\n    try {\n      RestObjectMapperFactory.getRestObjectMapper().readValue(inputStream, PojoModel.class);\n      Assertions.fail();\n    } catch (MismatchedInputException e) {\n      // right place, nothing to do.\n    } catch (Exception e) {\n      Assertions.fail();\n    }\n  }\n\n  @Test\n  public void testReadValue() {\n    String content = \"{\\\"desc\\\":\" + Strings.repeat(\"9\", 1001) + \"}\";\n    try {\n      RestObjectMapperFactory.getRestObjectMapper().readValue(content, PojoModel.class);\n      Assertions.fail();\n    } catch (StreamConstraintsException e) {\n      // right place, nothing to do.\n    } catch (JsonProcessingException ex) {\n      Assertions.fail();\n    }\n  }\n\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/fix/TestDoSFix.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.fix;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\nimport java.lang.reflect.Field;\nimport java.util.concurrent.Callable;\n\nimport org.apache.servicecomb.foundation.common.utils.RestObjectMapper;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.core.exc.InputCoercionException;\nimport com.fasterxml.jackson.databind.JsonMappingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.exc.InvalidFormatException;\nimport com.google.common.base.Strings;\nimport org.junit.jupiter.api.Test;\n\npublic class TestDoSFix {\n  static final ObjectMapper mapper = new RestObjectMapper();\n\n  static final String invalidNum = Strings.repeat(\"9\", 1000);\n\n  static final String invalidStr = \"\\\"\" + invalidNum + \"\\\"\";\n\n  static final String invalidArrNum = \"[\" + invalidNum + \"]\";\n\n  static final String invalidArrStr = \"[\\\"\" + invalidNum + \"\\\"]\";\n\n  public static class Model {\n    public Color color;\n\n    public char cValue;\n\n    public Character cObjValue;\n\n    public byte bValue;\n\n    public Byte bObjValue;\n\n    public short sValue;\n\n    public Short sObjValue;\n\n    public int iValue;\n\n    public Integer iObjValue;\n\n    public long lValue;\n\n    public Long lObjValue;\n\n    public float fValue;\n\n    public Float fObjValue;\n\n    public double dValue;\n\n    public Double dObjValue;\n  }\n\n  void fastFail(Callable<?> callable, Class<?> eCls) {\n    long start = System.currentTimeMillis();\n    try {\n      Object ret = callable.call();\n      Assertions.fail(\"expect failed, but success to be \" + ret);\n    } catch (AssertionError e) {\n      throw e;\n    } catch (Throwable e) {\n      if (eCls != e.getClass()) {\n        e.printStackTrace();\n      }\n      Assertions.assertEquals(eCls, e.getClass());\n    }\n\n    long time = System.currentTimeMillis() - start;\n    Assertions.assertTrue(time < 1000, \"did not fix DoS problem, time:\" + time);\n  }\n\n  void fastFail(String input, Class<?> cls, Class<?> eCls) {\n    fastFail(() -> mapper.readValue(input, cls), eCls);\n\n    fastFail(() -> mapper.readValue(new ByteArrayInputStream(input.getBytes()), cls), eCls);\n  }\n\n  void batFastFail(Class<?> cls, Class<?> e1, Class<?> e2) {\n    fastFail(invalidNum, cls, e1);\n    fastFail(invalidStr, cls, e2);\n    fastFail(invalidArrNum, cls, e1);\n    fastFail(invalidArrStr, cls, e2);\n  }\n\n  void batFastFail(Class<?> cls) {\n    batFastFail(cls, InputCoercionException.class, InvalidFormatException.class);\n  }\n\n  void batFastFail(String fieldName, Class<?> e1, Class<?> e2) {\n    fastFail(\"{\\\"\" + fieldName + \"\\\":\" + invalidNum + \"}\", Model.class, e1);\n    fastFail(\"{\\\"\" + fieldName + \"\\\":\\\"\" + invalidNum + \"\\\"}\", Model.class, e2);\n    fastFail(\"{\\\"\" + fieldName + \"\\\":[\" + invalidNum + \"]}\", Model.class, e1);\n    fastFail(\"{\\\"\" + fieldName + \"\\\":[\\\"\" + invalidNum + \"\\\"]}\", Model.class, e2);\n  }\n\n  void batFastFail(String fieldName) {\n    batFastFail(fieldName, JsonMappingException.class, InvalidFormatException.class);\n  }\n\n  @Test\n  public void testEnum() {\n    batFastFail(Color.class);\n    batFastFail(\"color\");\n  }\n\n  @Test\n  public void testChar() {\n    batFastFail(char.class, InputCoercionException.class, InvalidFormatException.class);\n    batFastFail(Character.class, InputCoercionException.class, InvalidFormatException.class);\n\n    batFastFail(\"cValue\", JsonMappingException.class, InvalidFormatException.class);\n    batFastFail(\"cObjValue\", JsonMappingException.class, InvalidFormatException.class);\n  }\n\n  @Test\n  public void testByte() {\n    batFastFail(byte.class);\n    batFastFail(Byte.class);\n\n    batFastFail(\"bValue\");\n    batFastFail(\"bObjValue\");\n  }\n\n  @Test\n  public void testShort() {\n    batFastFail(short.class);\n    batFastFail(Short.class);\n\n    batFastFail(\"sValue\");\n    batFastFail(\"sObjValue\");\n  }\n\n  @Test\n  public void testInt() {\n    batFastFail(int.class);\n    batFastFail(Integer.class);\n\n    batFastFail(\"iValue\");\n    batFastFail(\"iObjValue\");\n  }\n\n  @Test\n  public void testLong() {\n    batFastFail(long.class);\n    batFastFail(Long.class);\n\n    batFastFail(\"lValue\");\n    batFastFail(\"lObjValue\");\n  }\n\n  Object fastSucc(Callable<?> callable) {\n    long start = System.currentTimeMillis();\n    try {\n      Object ret = callable.call();\n      Assertions.assertTrue(System.currentTimeMillis() - start < 1000);\n      return ret;\n    } catch (Throwable e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  Object fastSucc(String input, Class<?> cls) {\n    return fastSucc(() -> mapper.readValue(input, cls));\n  }\n\n  Object fastSucc(InputStream input, Class<?> cls) {\n    return fastSucc(() -> {\n      input.reset();\n      return mapper.readValue(input, cls);\n    });\n  }\n\n  void batFastSucc(Class<?> cls, Object expected) {\n    Assertions.assertEquals(expected, fastSucc(invalidNum, cls));\n    Assertions.assertEquals(expected, fastSucc(new ByteArrayInputStream(invalidNum.getBytes()), cls));\n\n    Assertions.assertEquals(expected, fastSucc(invalidStr, cls));\n    Assertions.assertEquals(expected, fastSucc(new ByteArrayInputStream(invalidStr.getBytes()), cls));\n\n    Assertions.assertEquals(expected, fastSucc(invalidArrNum, cls));\n    Assertions.assertEquals(expected, fastSucc(new ByteArrayInputStream(invalidArrNum.getBytes()), cls));\n\n    Assertions.assertEquals(expected, fastSucc(invalidArrStr, cls));\n    Assertions.assertEquals(expected, fastSucc(new ByteArrayInputStream(invalidArrStr.getBytes()), cls));\n  }\n\n  void checkField(Model model, String fieldName, Object expected) {\n    try {\n      Field field = Model.class.getField(fieldName);\n      Object value = field.get(model);\n      Assertions.assertEquals(expected, value);\n    } catch (Throwable e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  void batFastSucc(String fieldName, Object expected) {\n    checkField((Model) fastSucc(\"{\\\"\" + fieldName + \"\\\":\" + invalidNum + \"}\", Model.class), fieldName, expected);\n    checkField((Model) fastSucc(\"{\\\"\" + fieldName + \"\\\":\\\"\" + invalidNum + \"\\\"}\", Model.class), fieldName, expected);\n    checkField((Model) fastSucc(\"{\\\"\" + fieldName + \"\\\":[\" + invalidNum + \"]}\", Model.class), fieldName, expected);\n    checkField((Model) fastSucc(\"{\\\"\" + fieldName + \"\\\":[\\\"\" + invalidNum + \"\\\"]}\", Model.class), fieldName, expected);\n  }\n\n  @Test\n  public void testFloat() {\n    batFastSucc(float.class, Float.POSITIVE_INFINITY);\n    batFastSucc(Float.class, Float.POSITIVE_INFINITY);\n\n    batFastSucc(\"fValue\", Float.POSITIVE_INFINITY);\n    batFastSucc(\"fObjValue\", Float.POSITIVE_INFINITY);\n  }\n\n  @Test\n  public void testDouble() {\n    batFastSucc(double.class, Double.POSITIVE_INFINITY);\n    batFastSucc(Double.class, Double.POSITIVE_INFINITY);\n\n    batFastSucc(\"dValue\", Double.POSITIVE_INFINITY);\n    batFastSucc(\"dObjValue\", Double.POSITIVE_INFINITY);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.BodyProcessor;\nimport org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.RawJsonBodyProcessor;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.buffer.impl.BufferImpl;\nimport io.vertx.core.http.impl.headers.HeadersMultiMap;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.MediaType;\n\n\npublic class TestBodyProcessor {\n  Environment environment = Mockito.mock(Environment.class);\n\n  final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n\n  MultiMap headers;\n\n  final RestClientRequest clientRequest = Mockito.mock(RestClientRequest.class);\n\n  ParamValueProcessor processor;\n\n  final Buffer inputBodyByteBuf = Buffer.buffer();\n\n  final BufferInputStream inputStream = new BufferInputStream(inputBodyByteBuf);\n\n  Buffer outputBodyBuffer;\n\n  String value;\n\n  private void createProcessor(Class<?> type) {\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n    OpenAPI openAPI = Mockito.mock(OpenAPI.class);\n    Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n    Mockito.when(schemaMeta.getSwagger()).thenReturn(openAPI);\n    RequestBody requestBody = Mockito.mock(RequestBody.class);\n    Content content = Mockito.mock(Content.class);\n    Mockito.when(requestBody.getContent()).thenReturn(content);\n    Mockito.when(requestBody.getRequired()).thenReturn(true);\n    Set<String> supported = new HashSet<>();\n    supported.add(MediaType.APPLICATION_JSON);\n    supported.add(MediaType.TEXT_PLAIN);\n    Mockito.when(content.keySet()).thenReturn(supported);\n    processor = new BodyProcessor(operationMeta, TypeFactory.defaultInstance().constructType(type), requestBody);\n  }\n\n  private void createRawJsonProcessor() {\n    processor = new RawJsonBodyProcessor(TypeFactory.defaultInstance().constructType(String.class), true);\n  }\n\n  private void createClientRequest() {\n    Mockito.doAnswer(invocation -> {\n      headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);\n      return null;\n    }).when(clientRequest).putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);\n\n    Mockito.when(clientRequest.getHeaders()).thenReturn(headers);\n  }\n\n  private void initInputStream() throws IOException {\n    Mockito.when(request.getInputStream()).thenReturn(inputStream);\n  }\n\n  private void setupGetValue(Class<?> type) throws IOException {\n    createProcessor(type);\n    initInputStream();\n  }\n\n  @BeforeEach\n  public void before() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    headers = HeadersMultiMap.httpHeaders();\n    value = \"value\";\n  }\n\n  @Test\n  public void testGetValueHaveAttr() throws Exception {\n    int body = 10;\n    createProcessor(String.class);\n    Mockito.when(request.getAttribute(RestConst.BODY_PARAMETER)).thenReturn(body);\n\n    Object result = processor.getValue(request);\n    Assertions.assertEquals(\"10\", result);\n  }\n\n  @Test\n  public void testGetValueNoAttrNoStream() throws Exception {\n    createProcessor(String.class);\n    Mockito.when(request.getInputStream()).thenReturn(null);\n    Assertions.assertThrows(InvocationException.class, () -> processor.getValue(request));\n  }\n\n  @Test\n  public void testGetValueTextPlain() throws Exception {\n    setupGetValue(String.class);\n    inputBodyByteBuf.appendString(\"abc\", StandardCharsets.UTF_8.toString());\n\n    Mockito.when(request.getContentType()).thenReturn(MediaType.TEXT_PLAIN);\n\n    Assertions.assertEquals(\"abc\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetValueContextTypeJson() throws Exception {\n    setupGetValue(Integer.class);\n    inputBodyByteBuf.appendString(\"\\\"1\\\"\", StandardCharsets.UTF_8.toString());\n\n    Mockito.when(request.getContentType()).thenReturn(MediaType.APPLICATION_JSON);\n\n    Assertions.assertEquals(1, processor.getValue(request));\n  }\n\n  @Test\n  public void testGetValueDefaultJson() throws Exception {\n    setupGetValue(Integer.class);\n    inputBodyByteBuf.appendString(\"\\\"1\\\"\", StandardCharsets.UTF_8.toString());\n\n    Assertions.assertEquals(1, processor.getValue(request));\n  }\n\n  @Test\n  public void testSetValue() throws Exception {\n    createClientRequest();\n    createProcessor(String.class);\n\n    Mockito.when(clientRequest.getHeaders()).thenReturn(headers);\n    ParamValueProcessor spy = Mockito.spy(processor);\n    Mockito.doAnswer(invocation -> {\n      outputBodyBuffer = new BufferImpl().appendBytes((value).getBytes(StandardCharsets.UTF_8));\n      return null;\n    }).when(spy).setValue(clientRequest, value);\n\n    spy.setValue(clientRequest, value);\n    processor.setValue(clientRequest, value);\n    Assertions.assertEquals(MediaType.APPLICATION_JSON, headers.get(HttpHeaders.CONTENT_TYPE));\n    Assertions.assertEquals(value, outputBodyBuffer.toString());\n  }\n\n  @Test\n  public void testSetValueTextPlain() throws Exception {\n    createClientRequest();\n    createProcessor(String.class);\n    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);\n\n    ParamValueProcessor spy = Mockito.spy(processor);\n    Mockito.doAnswer(invocation -> {\n      outputBodyBuffer = new BufferImpl().appendBytes((value).getBytes(StandardCharsets.UTF_8));\n      return null;\n    }).when(spy).setValue(clientRequest, value);\n\n    spy.setValue(clientRequest, value);\n    processor.setValue(clientRequest, value);\n    Assertions.assertEquals(MediaType.TEXT_PLAIN, headers.get(HttpHeaders.CONTENT_TYPE));\n    Assertions.assertEquals(value, outputBodyBuffer.toString());\n  }\n\n\n  @Test\n  public void testGetParameterPath() {\n    createProcessor(String.class);\n    Assertions.assertEquals(\"\", processor.getParameterPath());\n  }\n\n  @Test\n  public void testGetProcessorType() {\n    createProcessor(String.class);\n    Assertions.assertEquals(\"body\", processor.getProcessorType());\n  }\n\n  @Test\n  public void testGetValueRawJson() throws Exception {\n    createRawJsonProcessor();\n    initInputStream();\n    inputBodyByteBuf.appendString(\"\\\"1\\\"\", StandardCharsets.UTF_8.toString());\n\n    Assertions.assertEquals(\"\\\"1\\\"\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetValueRawJsonHaveAttr() throws Exception {\n    int body = 10;\n    createRawJsonProcessor();\n    Mockito.when(request.getAttribute(RestConst.BODY_PARAMETER)).thenReturn(body);\n\n    Object result = processor.getValue(request);\n    Assertions.assertEquals(\"10\", result);\n  }\n\n  @Test\n  public void testGetValueRawJsonNoAttrNoStream() throws Exception {\n    createRawJsonProcessor();\n    Mockito.when(request.getInputStream()).thenReturn(null);\n\n    Object result = processor.getValue(request);\n    Assertions.assertNull(result);\n  }\n\n  @Test\n  public void testSetValueRawJson() throws Exception {\n    createClientRequest();\n    createRawJsonProcessor();\n\n    ParamValueProcessor spy = Mockito.spy(processor);\n    Mockito.doAnswer(invocation -> {\n      outputBodyBuffer = new BufferImpl().appendBytes((value).getBytes(StandardCharsets.UTF_8));\n      return null;\n    }).when(spy).setValue(clientRequest, value);\n    spy.setValue(clientRequest, value);\n    processor.setValue(clientRequest, value);\n    Assertions.assertEquals(MediaType.APPLICATION_JSON, headers.get(HttpHeaders.CONTENT_TYPE));\n    Assertions.assertEquals(\"value\", outputBodyBuffer.toString());\n  }\n\n  static class BodyModel {\n    public String name;\n\n    public int age;\n  }\n\n  @Test\n  public void convertFromFormData() throws Exception {\n    createProcessor(BodyModel.class);\n    Map<String, String[]> parameterMap = new HashMap<>();\n    parameterMap.put(\"name\", new String[] {\"n\"});\n    parameterMap.put(\"age\", new String[] {\"10\"});\n    Mockito.when(request.getParameterMap()).thenReturn(parameterMap);\n    Mockito.when(request.getContentType()).thenReturn(MediaType.MULTIPART_FORM_DATA + \";utf-8\");\n\n    BodyModel bm = (BodyModel) processor.getValue(request);\n    Assertions.assertEquals(\"n\", bm.name);\n    Assertions.assertEquals(10, bm.age);\n  }\n\n  @Test\n  public void convertFromUrlencoded() throws Exception {\n    createProcessor(BodyModel.class);\n    Map<String, String[]> parameterMap = new HashMap<>();\n    parameterMap.put(\"name\", new String[] {\"n\"});\n    parameterMap.put(\"age\", new String[] {\"10\"});\n    Mockito.when(request.getParameterMap()).thenReturn(parameterMap);\n    Mockito.when(request.getContentType()).thenReturn(MediaType.APPLICATION_FORM_URLENCODED + \";utf-8\");\n\n    BodyModel bm = (BodyModel) processor.getValue(request);\n    Assertions.assertEquals(\"n\", bm.name);\n    Assertions.assertEquals(10, bm.age);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.BodyProcessor;\nimport org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.RawJsonBodyProcessor;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.MediaType;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class TestBodyProcessorCreator {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void before() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @Test\n  public void testCreateNormal() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(BodyProcessorCreator.PARAM_TYPE);\n    RequestBody param = new RequestBody();\n    param.setContent(new Content());\n    param.getContent().addMediaType(SwaggerConst.DEFAULT_MEDIA_TYPE, new MediaType());\n    param.getContent().get(SwaggerConst.DEFAULT_MEDIA_TYPE).setSchema(new Schema());\n    param.setExtensions(new HashMap<>());\n\n    ParamValueProcessor processor = creator.create(null, null, param, String.class);\n\n    Assertions.assertEquals(BodyProcessor.class, processor.getClass());\n  }\n\n  @Test\n  public void testCreateRawJson() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(BodyProcessorCreator.PARAM_TYPE);\n    RequestBody param = new RequestBody();\n    param.setContent(new Content());\n    param.getContent().addMediaType(SwaggerConst.DEFAULT_MEDIA_TYPE, new MediaType());\n    param.getContent().get(SwaggerConst.DEFAULT_MEDIA_TYPE).setSchema(new Schema());\n    param.addExtension(SwaggerConst.EXT_RAW_JSON_TYPE, true);\n\n    ParamValueProcessor processor = creator.create(null, null, param, String.class);\n\n    Assertions.assertEquals(RawJsonBodyProcessor.class, processor.getClass());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.CookieProcessorCreator.CookieProcessor;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.fasterxml.jackson.databind.util.StdDateFormat;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestCookieProcessor {\n  final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n\n  final Map<String, String> cookies = new HashMap<>();\n\n  final RestClientRequest clientRequest = Mockito.mock(RestClientRequest.class);\n\n  final String cookieName = \"v1\";\n\n  final String cookieValue = \"c1v\";\n\n  private CookieProcessor createProcessor(String name, Class<?> type) {\n    return new CookieProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);\n  }\n\n  private CookieProcessor createProcessor(String name, Class<?> type, String defaultValue, boolean required) {\n    return new CookieProcessor(name, TypeFactory.defaultInstance().constructType(type), defaultValue, required);\n  }\n\n  private void createClientRequest() {\n    Mockito.doAnswer(invocation -> {\n      cookies.put(cookieName, cookieValue);\n      return null;\n    }).when(clientRequest).addCookie(cookieName, cookieValue);\n  }\n\n  @Test\n  public void testGetValueNoCookies() throws Exception {\n    Mockito.when(request.getCookies()).thenReturn(null);\n\n    CookieProcessor processor = createProcessor(cookieName, String.class, null, false);\n    Object value = processor.getValue(request);\n    Assertions.assertNull(value);\n  }\n\n  @Test\n  public void testNoCookieAndRequired() throws Exception {\n    Mockito.when(request.getCookies()).thenReturn(null);\n\n    CookieProcessor processor = createProcessor(cookieName, String.class, null, true);\n    try {\n      processor.getValue(request);\n      Assertions.assertEquals(\"required is true, throw exception\", \"not throw exception\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"Parameter is required.\"));\n    }\n  }\n\n  @Test\n  public void testGetValueCookiesNotFound() throws Exception {\n    Cookie[] cookies = new Cookie[] {new Cookie(cookieName, cookieValue)};\n    Mockito.when(request.getCookies()).thenReturn(cookies);\n\n    CookieProcessor processor = createProcessor(\"c2\", String.class, null, false);\n    Object value = processor.getValue(request);\n    Assertions.assertNull(value);\n  }\n\n  @Test\n  public void testGetValueCookiesFound() throws Exception {\n    Cookie[] cookies = new Cookie[] {new Cookie(cookieName, cookieValue)};\n    Mockito.when(request.getCookies()).thenReturn(cookies);\n\n    CookieProcessor processor = createProcessor(cookieName, String.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(cookieValue, value);\n  }\n\n  @Test\n  public void testGetValueRequiredTrue() throws Exception {\n    Cookie[] cookies = new Cookie[] {new Cookie(cookieName, null)};\n    Mockito.when(request.getCookies()).thenReturn(cookies);\n\n    CookieProcessor processor = createProcessor(cookieName, String.class, null, true);\n    try {\n      processor.getValue(request);\n      Assertions.assertEquals(\"required is true, throw exception\", \"not throw exception\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"Parameter is required.\"));\n    }\n  }\n\n  @Test\n  public void testGetValueRequiredFalse() throws Exception {\n    Cookie[] cookies = new Cookie[] {new Cookie(cookieName, null)};\n    Mockito.when(request.getCookies()).thenReturn(cookies);\n\n    CookieProcessor processor = createProcessor(cookieName, String.class, \"test\", false);\n    Object result = processor.getValue(request);\n    Assertions.assertEquals(\"test\", result);\n  }\n\n  @SuppressWarnings(\"deprecation\")\n  @Test\n  public void testGetValueCookiesDate() throws Exception {\n    Date date = new Date();\n    String strDate = com.fasterxml.jackson.databind.util.ISO8601Utils.format(date);\n    Cookie[] cookies = new Cookie[] {new Cookie(cookieName, strDate)};\n    Mockito.when(request.getCookies()).thenReturn(cookies);\n\n    CookieProcessor processor = createProcessor(cookieName, Date.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(strDate, com.fasterxml.jackson.databind.util.ISO8601Utils.format((Date) value));\n  }\n\n  @Test\n  public void testSetValue() throws Exception {\n    createClientRequest();\n\n    CookieProcessor processor = createProcessor(cookieName, String.class);\n    processor.setValue(clientRequest, cookieValue);\n    Assertions.assertEquals(cookieValue, cookies.get(cookieName));\n  }\n\n  @Test\n  public void testSetValueDateFixed() throws Exception {\n    Date date = new Date(1586957400199L);\n    String strDate =  \"2020-04-15T13:30:00.199+00:00\";\n\n    String cookieValue = RestObjectMapperFactory.getConsumerWriterMapper().convertToString(date);\n    Mockito.doAnswer(invocation -> {\n      cookies.put(\"h1\", cookieValue);\n      return null;\n    }).when(clientRequest).addCookie(\"h1\", cookieValue);\n    CookieProcessor processor = createProcessor(\"h1\", Date.class);\n    processor.setValue(clientRequest, date);\n    Assertions.assertEquals(strDate, cookies.get(\"h1\"));\n  }\n\n  @Test\n  public void testSetValueDate() throws Exception {\n    Date date = new Date();\n\n    String strDate =  new StdDateFormat().format(date);\n\n    String cookieValue = RestObjectMapperFactory.getConsumerWriterMapper().convertToString(date);\n    Mockito.doAnswer(invocation -> {\n      cookies.put(\"h1\", cookieValue);\n      return null;\n    }).when(clientRequest).addCookie(\"h1\", cookieValue);\n    CookieProcessor processor = createProcessor(\"h1\", Date.class);\n    processor.setValue(clientRequest, date);\n    Assertions.assertEquals(strDate, cookies.get(\"h1\"));\n  }\n\n  @Test\n  public void testGetProcessorType() {\n    CookieProcessor processor = createProcessor(cookieName, String.class);\n    Assertions.assertEquals(\"cookie\", processor.getProcessorType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestCookieProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport org.apache.servicecomb.common.rest.codec.param.CookieProcessorCreator.CookieProcessor;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.CookieParameter;\n\npublic class TestCookieProcessorCreator {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testCreate() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(CookieProcessorCreator.PARAMTYPE);\n    CookieParameter p = new CookieParameter();\n    p.setName(\"p1\");\n    p.setSchema(new Schema());\n    ParamValueProcessor processor = creator.create(null, p.getName(), p, String.class);\n\n    Assertions.assertEquals(CookieProcessor.class, processor.getClass());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.FormProcessor;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.MapSchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class TestFormProcessor {\n  final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n\n  final Map<String, Object> forms = new HashMap<>();\n\n  final RestClientRequest clientRequest = Mockito.mock(RestClientRequest.class);\n\n  private FormProcessor createProcessor(String name, Type type) {\n    return createProcessor(name, type, null, true);\n  }\n\n  private FormProcessor createProcessor(String name, Type type, String defaultValue, boolean required) {\n    JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n\n    RequestBody formParameter = new RequestBody();\n    Content content = new Content();\n    MapSchema schema = new MapSchema();\n    io.swagger.v3.oas.models.media.MediaType mediaType = new io.swagger.v3.oas.models.media.MediaType();\n\n    if (javaType.isContainerType()) {\n      Schema propertySchema = new ArraySchema();\n      schema.addProperty(name, propertySchema);\n      mediaType.schema(schema);\n    } else {\n      Schema propertySchema = new Schema();\n      propertySchema.setDefault(defaultValue);\n      schema.addProperty(name, propertySchema);\n      mediaType.schema(schema);\n    }\n\n    content.addMediaType(MediaType.APPLICATION_FORM_URLENCODED,\n        mediaType);\n    formParameter.content(content)\n        .required(required);\n\n    return new FormProcessor(name, formParameter, MediaType.APPLICATION_FORM_URLENCODED, javaType);\n  }\n\n  @Test\n  public void testGetValueWithAttr() throws Exception {\n    Map<String, Object> forms = new HashMap<>();\n    forms.put(\"name\", \"value\");\n    Mockito.when(request.getAttribute(RestConst.BODY_PARAMETER)).thenReturn(forms);\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(\"value\", value);\n  }\n\n  @Test\n  public void testGetValueNormal() throws Exception {\n    Mockito.when(request.getParameter(\"name\")).thenReturn(\"value\");\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(\"value\", value);\n  }\n\n  @SuppressWarnings(\"deprecation\")\n  @Test\n  public void testGetValueNormalDate() throws Exception {\n    Date date = new Date();\n    String strDate = com.fasterxml.jackson.databind.util.ISO8601Utils.format(date);\n    Mockito.when(request.getParameter(\"name\")).thenReturn(strDate);\n\n    ParamValueProcessor processor = createProcessor(\"name\", Date.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(strDate, com.fasterxml.jackson.databind.util.ISO8601Utils.format((Date) value));\n  }\n\n  @Test\n  public void testGetValueContainerTypeNull() throws Exception {\n    Mockito.when(request.getParameterValues(\"name\")).thenReturn(null);\n\n    ParamValueProcessor processor = createProcessor(\"name\", String[].class, null, false);\n    String[] value = (String[]) processor.getValue(request);\n    Assertions.assertNull(value);\n  }\n\n  @Test\n  public void testGetValueNull() throws Exception {\n    Mockito.when(request.getParameter(\"name\")).thenReturn(null);\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class, null, true);\n    try {\n      processor.getValue(request);\n      Assertions.assertEquals(\"required is true, throw exception\", \"not throw exception\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"Parameter is required.\"));\n    }\n  }\n\n  @Test\n  public void testGetValueArray() throws Exception {\n    Mockito.when(request.getParameterValues(\"name\")).thenReturn(new String[] {\"value\"});\n\n    ParamValueProcessor processor = createProcessor(\"name\", String[].class);\n    String[] value = (String[]) processor.getValue(request);\n    MatcherAssert.assertThat(value, Matchers.arrayContaining(\"value\"));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void testGetValueList() throws Exception {\n    Mockito.when(request.getParameterValues(\"name\")).thenReturn(new String[] {\"value\"});\n\n    ParamValueProcessor processor = createProcessor(\"name\",\n        TypeFactory.defaultInstance().constructCollectionType(List.class, String.class),\n        null, true);\n    Object value = processor.getValue(request);\n    MatcherAssert.assertThat((List<String>) value, Matchers.contains(\"value\"));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void testGetValueSet() throws Exception {\n    Mockito.when(request.getParameterValues(\"name\")).thenReturn(new String[] {\"value\"});\n\n    ParamValueProcessor processor = createProcessor(\"name\",\n        TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class), null,\n        true);\n    Object value = processor.getValue(request);\n    MatcherAssert.assertThat((Set<String>) value, Matchers.contains(\"value\"));\n  }\n\n  @Test\n  public void testSetValue() throws Exception {\n    Mockito.doAnswer(invocation -> {\n      forms.put(\"name\", \"value\");\n      return null;\n    }).when(clientRequest).addForm(\"name\", \"value\");\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class);\n    processor.setValue(clientRequest, \"value\");\n    Assertions.assertEquals(\"value\", forms.get(\"name\"));\n  }\n\n  @Test\n  public void testSetValueDate() throws Exception {\n    Date date = new Date();\n\n    Mockito.doAnswer(invocation -> {\n      forms.put(\"name\", date);\n      return null;\n    }).when(clientRequest).addForm(\"name\", date);\n    ParamValueProcessor processor = createProcessor(\"name\", Date.class);\n    processor.setValue(clientRequest, date);\n    Assertions.assertSame(date, forms.get(\"name\"));\n  }\n\n  @Test\n  public void testGetProcessorType() {\n    ParamValueProcessor processor = createProcessor(\"name\", String.class);\n    Assertions.assertEquals(\"formData\", processor.getProcessorType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestFormProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.FormProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.MediaType;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class TestFormProcessorCreator {\n  @Test\n  public void testCreate() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(FormProcessorCreator.PARAMTYPE);\n    RequestBody p = new RequestBody();\n    p.setContent(new Content());\n    p.getContent().addMediaType(SwaggerConst.FORM_MEDIA_TYPE, new MediaType());\n    p.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).setSchema(new Schema());\n    p.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().setProperties(new HashMap<>());\n\n    ParamValueProcessor processor = creator.create(null, \"p1\", p, String.class);\n\n    Assertions.assertEquals(FormProcessor.class, processor.getClass());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.param.HeaderProcessorCreator.HeaderProcessor;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.fasterxml.jackson.databind.util.StdDateFormat;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.HeaderParameter;\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic class TestHeaderProcessor {\n  final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n\n  final Map<String, String> headers = new HashMap<>();\n\n  final RestClientRequest clientRequest = Mockito.mock(RestClientRequest.class);\n\n  private HeaderProcessor createProcessor(String name, Type type) {\n    return createProcessor(name, type, null, true);\n  }\n\n  private HeaderProcessor createProcessor(String name, Type type, String defaultValue, boolean required) {\n    JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n\n    HeaderParameter headerParameter = new HeaderParameter();\n    headerParameter.setSchema(new Schema());\n    headerParameter.name(name)\n        .required(required);\n    headerParameter.getSchema().setDefault(defaultValue);\n\n    if (javaType.isContainerType()) {\n      headerParameter.schema(new ArraySchema());\n    }\n    return new HeaderProcessor(headerParameter, javaType);\n  }\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.header.ignoreRequiredCheck\"\n        , boolean.class, false)).thenReturn(false);\n  }\n\n  @Test\n  public void testGetValueNormal() throws Exception {\n    Mockito.when(request.getHeader(\"h1\")).thenReturn(\"h1v\");\n\n    HeaderProcessor processor = createProcessor(\"h1\", String.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(\"h1v\", value);\n  }\n\n  @SuppressWarnings(\"deprecation\")\n  @Test\n  public void testGetValueNormalDate() throws Exception {\n    Date date = new Date();\n    String strDate = com.fasterxml.jackson.databind.util.ISO8601Utils.format(date);\n    Mockito.when(request.getHeader(\"h1\")).thenReturn(strDate);\n\n    HeaderProcessor processor = createProcessor(\"h1\", Date.class);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(strDate, com.fasterxml.jackson.databind.util.ISO8601Utils.format((Date) value));\n  }\n\n  @Test\n  public void testGetValueContainerTypeNull() throws Exception {\n    Mockito.when(request.getHeader(\"h1\")).thenReturn(null);\n\n    HeaderProcessor processor = createProcessor(\"h1\", String[].class, null, false);\n    String[] value = (String[]) processor.getValue(request);\n    Assertions.assertNull(value);\n  }\n\n  @Test\n  public void testGetValueRequiredTrue() throws Exception {\n    Mockito.when(request.getHeader(\"h1\")).thenReturn(null);\n\n    HeaderProcessor processor = createProcessor(\"h1\", String.class);\n    try {\n      processor.getValue(request);\n      Assertions.assertEquals(\"required is true, throw exception\", \"not throw exception\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"Parameter is required.\"));\n    }\n  }\n\n  @Test\n  public void testGetValueRequiredFalse() throws Exception {\n    Mockito.when(request.getHeader(\"h1\")).thenReturn(null);\n\n    HeaderProcessor processor = createProcessor(\"h1\", String.class, \"test\", false);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(\"test\", value);\n  }\n\n  @Test\n  public void testGetValueArray() throws Exception {\n    Mockito.when(request.getHeaders(\"h1\")).thenReturn(Collections.enumeration(Arrays.asList(\"h1v\")));\n\n    HeaderProcessor processor = createProcessor(\"h1\", String[].class);\n    String[] value = (String[]) processor.getValue(request);\n    MatcherAssert.assertThat(value, Matchers.arrayContaining(\"h1v\"));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void testGetValueList() throws Exception {\n    Mockito.when(request.getHeaders(\"h1\")).thenReturn(Collections.enumeration(Arrays.asList(\"h1v\")));\n\n    HeaderProcessor processor = createProcessor(\"h1\",\n        TypeFactory.defaultInstance().constructCollectionType(List.class, String.class),\n        null, true);\n    Object value = processor.getValue(request);\n    MatcherAssert.assertThat((List<String>) value, Matchers.contains(\"h1v\"));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void testGetValueSet() throws Exception {\n    Mockito.when(request.getHeaders(\"h1\")).thenReturn(Collections.enumeration(Arrays.asList(\"h1v\")));\n\n    HeaderProcessor processor = createProcessor(\"h1\",\n        TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class),\n        null, true);\n    Object value = processor.getValue(request);\n    MatcherAssert.assertThat((Set<String>) value, Matchers.contains(\"h1v\"));\n  }\n\n  @Test\n  public void testSetValue() throws Exception {\n    Mockito.doAnswer(invocation -> {\n      headers.put(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(\"h1v\"));\n      return null;\n    }).when(clientRequest).putHeader(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(\"h1v\"));\n\n    HeaderProcessor processor = createProcessor(\"h1\", String.class);\n    processor.setValue(clientRequest, \"h1v\");\n    Assertions.assertEquals(\"h1v\", headers.get(\"h1\"));\n  }\n\n  @Test\n  public void testSetValueNull() throws Exception {\n    Mockito.doAnswer(invocation -> {\n      headers.put(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(null));\n      return null;\n    }).when(clientRequest).putHeader(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(null));\n    HeaderProcessor processor = createProcessor(\"h1\", String.class);\n    processor.setValue(clientRequest, null);\n    Assertions.assertEquals(0, headers.size());\n  }\n\n  @Test\n  public void testSetValueDateFixed() throws Exception {\n    Date date = new Date(1586957400199L);\n    String strDate = \"2020-04-15T13:30:00.199+00:00\";\n\n    Mockito.doAnswer(invocation -> {\n      headers.put(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(date));\n      return null;\n    }).when(clientRequest).putHeader(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(date));\n\n    HeaderProcessor processor = createProcessor(\"h1\", Date.class);\n    processor.setValue(clientRequest, date);\n    Assertions.assertEquals(strDate, headers.get(\"h1\"));\n  }\n\n  @Test\n  public void testSetValueDate() throws Exception {\n    Date date = new Date();\n    String strDate = new StdDateFormat().format(date);\n    Mockito.doAnswer(invocation -> {\n      headers.put(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(date));\n      return null;\n    }).when(clientRequest).putHeader(\"h1\", RestObjectMapperFactory.getConsumerWriterMapper().convertToString(date));\n\n    HeaderProcessor processor = createProcessor(\"h1\", Date.class);\n    processor.setValue(clientRequest, date);\n    Assertions.assertEquals(strDate, headers.get(\"h1\"));\n  }\n\n  @Test\n  public void testGetProcessorType() {\n    HeaderProcessor processor = createProcessor(\"h1\", String.class);\n    Assertions.assertEquals(\"header\", processor.getProcessorType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestHeaderProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport org.apache.servicecomb.common.rest.codec.param.HeaderProcessorCreator.HeaderProcessor;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.HeaderParameter;\n\npublic class TestHeaderProcessorCreator {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.header.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @Test\n  public void testCreate() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(HeaderProcessorCreator.PARAMTYPE);\n    HeaderParameter hp = new HeaderParameter();\n    hp.setName(\"h1\");\n    hp.setSchema(new Schema());\n\n    ParamValueProcessor processor = creator.create(null, hp.getName(), hp, String.class);\n\n    Assertions.assertEquals(HeaderProcessor.class, processor.getClass());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestPathProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.param.PathProcessorCreator.PathProcessor;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestPathProcessor {\n  final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n\n  final Map<String, String> pathVars = new HashMap<>();\n\n  ParamValueProcessor processor;\n\n  private void createProcessor(String name, Class<?> type) {\n    processor = new PathProcessor(name, TypeFactory.defaultInstance().constructType(type), null, true);\n  }\n\n  private void prepareGetValue(String name, Class<?> type) {\n    createProcessor(name, type);\n    Mockito.when(request.getAttribute(RestConst.PATH_PARAMETERS)).thenReturn(pathVars);\n  }\n\n  @Test\n  public void testGetValueNoPathVars() throws Exception {\n    createProcessor(\"name\", String.class);\n\n    Assertions.assertNull(processor.getValue(request));\n  }\n\n  @Test\n  public void testGetValuePathNotFound() throws Exception {\n    prepareGetValue(\"name\", String.class);\n\n    Assertions.assertNull(processor.getValue(request));\n  }\n\n  @Test\n  public void testGetValuePathNormal() throws Exception {\n    prepareGetValue(\"name\", String.class);\n    pathVars.put(\"name\", \"value\");\n\n    Assertions.assertEquals(\"value\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetSpaceEncoded() throws Exception {\n    prepareGetValue(\"name\", String.class);\n    pathVars.put(\"name\", \"a%20b\");\n\n    Assertions.assertEquals(\"a b\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetPlus() throws Exception {\n    prepareGetValue(\"name\", String.class);\n    pathVars.put(\"name\", \"a+b\");\n\n    Assertions.assertEquals(\"a+b\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetPercentage() throws Exception {\n    prepareGetValue(\"name\", String.class);\n    pathVars.put(\"name\", \"%25%25\");\n\n    Assertions.assertEquals(\"%%\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetColon() throws Exception {\n    prepareGetValue(\"name\", String.class);\n    pathVars.put(\"name\", \"aa:bb\");\n    Assertions.assertEquals(\"aa:bb\", processor.getValue(request));\n  }\n\n  @Test\n  public void testGetProcessorType() {\n    createProcessor(\"name\", String.class);\n    Assertions.assertEquals(\"path\", processor.getProcessorType());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestPathProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport org.apache.servicecomb.common.rest.codec.param.PathProcessorCreator.PathProcessor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.PathParameter;\n\npublic class TestPathProcessorCreator {\n  @Test\n  public void testCreate() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(PathProcessorCreator.PARAMTYPE);\n    Parameter parameter = new PathParameter();\n    parameter.setName(\"path\");\n    parameter.setSchema(new Schema());\n\n    ParamValueProcessor processor = creator.create(null, parameter.getName(), parameter, String.class);\n\n    Assertions.assertEquals(PathProcessor.class, processor.getClass());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.StringSchema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.Parameter.StyleEnum;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic class TestQueryProcessor {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n\n  private ParamValueProcessor createProcessor(String name, Class<?> type,\n      Parameter.StyleEnum style, boolean explode) {\n    return createProcessor(name, type, null, true, style, explode);\n  }\n\n  private ParamValueProcessor createProcessor(String name, Class<?> type, String defaultValue, boolean required,\n      Parameter.StyleEnum style, boolean explode) {\n    JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n\n    QueryParameter queryParameter = new QueryParameter();\n    queryParameter.name(name)\n        .required(required)\n        .setSchema(new StringSchema());\n    queryParameter.getSchema().setDefault(defaultValue);\n\n    if (javaType.isContainerType()) {\n      queryParameter.setSchema(new ArraySchema());\n      queryParameter.setExplode(explode);\n      queryParameter.setStyle(style);\n    }\n    return new QueryProcessor(queryParameter, javaType);\n  }\n\n  @Test\n  public void testGetValueNormal() throws Exception {\n    Mockito.when(request.getParameter(\"name\")).thenReturn(\"value\");\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class, StyleEnum.FORM, true);\n    Object value = processor.getValue(request);\n    Assertions.assertEquals(\"value\", value);\n  }\n\n  @Test\n  public void testGetValueContainerType() throws Exception {\n    Mockito.when(request.getParameterValues(\"name\")).thenReturn(new String[] {\"value\", \"value2\"});\n\n    ParamValueProcessor processor = createProcessor(\"name\", String[].class, StyleEnum.FORM, true);\n    String[] value = (String[]) processor.getValue(request);\n    MatcherAssert.assertThat(value, Matchers.arrayContaining(\"value\", \"value2\"));\n  }\n\n  @Test\n  public void testGetValueOnCollectionFormatIsCsv() throws Exception {\n    Mockito.when(request.getParameter(\"name\")).thenReturn(\"value2,value3\");\n\n    ParamValueProcessor processor = createProcessor(\"name\", String[].class, StyleEnum.FORM, false);\n    String[] value = (String[]) processor.getValue(request);\n    MatcherAssert.assertThat(value, Matchers.arrayContaining(\"value2\", \"value3\"));\n  }\n\n  @Test\n  public void testGetProcessorType() {\n    ParamValueProcessor processor = createProcessor(\"name\", String.class, StyleEnum.FORM, true);\n    Assertions.assertEquals(\"query\", processor.getProcessorType());\n  }\n\n  @Test\n  public void testGetValueRequiredTrue() throws Exception {\n    Mockito.when(request.getParameter(\"name\")).thenReturn(null);\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class, StyleEnum.FORM, true);\n    try {\n      processor.getValue(request);\n      Assertions.assertEquals(\"required is true, throw exception\", \"not throw exception\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"Parameter name is required.\"));\n    }\n  }\n\n  @Test\n  public void testGetValueRequiredFalse() throws Exception {\n    Mockito.when(request.getParameter(\"name\")).thenReturn(null);\n\n    ParamValueProcessor processor = createProcessor(\"name\", String.class, \"test\", false, StyleEnum.FORM, true);\n    Object result = processor.getValue(request);\n    Assertions.assertEquals(\"test\", result);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestQueryProcessorCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.param;\n\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic class TestQueryProcessorCreator {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @Test\n  public void testCreate() {\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(QueryProcessorCreator.PARAMTYPE);\n    Parameter parameter = new QueryParameter();\n    parameter.setName(\"query\");\n    parameter.setSchema(new Schema());\n    ParamValueProcessor processor = creator.create(null, parameter.getName(), parameter, String.class);\n\n    Assertions.assertEquals(QueryProcessor.class, processor.getClass());\n\n    String result = (String) processor.convertValue(\"Hello\", TypeFactory.defaultInstance().constructType(String.class));\n    Assertions.assertEquals(\"Hello\", result);\n\n    result = (String) processor.convertValue(\"\", TypeFactory.defaultInstance().constructType(String.class));\n    Assertions.assertEquals(\"\", result);\n\n    result = (String) processor.convertValue(null, TypeFactory.defaultInstance().constructType(String.class));\n    Assertions.assertNull(result);\n  }\n\n  @SuppressWarnings(\"UnusedAssignment\")\n  @Test\n  public void testCreateNullAsEmpty() throws Exception {\n    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(true);\n    ParamValueProcessorCreator creator =\n        ParamValueProcessorCreatorManager.INSTANCE.findValue(QueryProcessorCreator.PARAMTYPE);\n    Parameter parameter = new QueryParameter();\n    parameter.setName(\"query\");\n    parameter.setSchema(new Schema());\n\n    ParamValueProcessor processor = creator.create(null, parameter.getName(), parameter, String.class);\n\n    Assertions.assertEquals(QueryProcessor.class, processor.getClass());\n\n    Mockito.when(request.getParameter(\"query\")).thenReturn(\"Hello\");\n    String result = (String) processor.getValue(request);\n    Assertions.assertEquals(\"Hello\", result);\n\n    Mockito.when(request.getParameter(\"query\")).thenReturn(\"\");\n    result = (String) processor.getValue(request);\n    Assertions.assertNull(result);\n\n    Mockito.when(request.getParameter(\"query\")).thenReturn(null);\n    result = (String) processor.convertValue(null, TypeFactory.defaultInstance().constructType(String.class));\n    result = (String) processor.getValue(request);\n    Assertions.assertNull(result);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceJsonProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport static org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager.DEFAULT_SERIAL_CLASS;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.exc.MismatchedInputException;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.vertx.core.buffer.Buffer;\nimport org.junit.jupiter.api.Test;\n\npublic class TestProduceJsonProcessor {\n  final ProduceProcessor pp = ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor();\n\n  final JavaType stringType = TypeFactory.defaultInstance().constructType(String.class);\n\n  @Test\n  public void testEncodeResponseNull() throws Exception {\n    Buffer buffer = pp.encodeResponse(null);\n    Assertions.assertNull(buffer);\n\n    ByteArrayOutputStream os = new ByteArrayOutputStream();\n    pp.encodeResponse(os, null);\n    Assertions.assertEquals(0, os.size());\n  }\n\n  @Test\n  public void testDecodeResponseNull() throws Exception {\n    JavaType resultType = TypeFactory.unknownType();\n    Object result = pp.decodeResponse(Buffer.buffer(), resultType);\n    Assertions.assertNull(result);\n\n    ByteArrayInputStream is = new ByteArrayInputStream(new byte[] {});\n    try {\n      pp.decodeResponse(is, resultType);\n      Assertions.fail();\n    } catch (Exception e) {\n      Assertions.assertTrue(e instanceof MismatchedInputException);\n    }\n  }\n\n  @Test\n  public void testBufferNormal() throws Exception {\n    String value = \"abc\";\n    Buffer buffer = pp.encodeResponse(value);\n    Assertions.assertEquals(\"\\\"abc\\\"\", buffer.toString(StandardCharsets.UTF_8));\n\n    Object result = pp.decodeResponse(buffer, stringType);\n    Assertions.assertEquals(value, result);\n  }\n\n  @Test\n  public void testStreamNormal() throws Exception {\n    String value = \"abc\";\n    ByteArrayOutputStream os = new ByteArrayOutputStream();\n\n    pp.encodeResponse(os, value);\n    Assertions.assertEquals(\"\\\"abc\\\"\", os.toString(StandardCharsets.UTF_8.name()));\n\n    ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());\n    Object result = pp.decodeResponse(is, stringType);\n    Assertions.assertEquals(value, result);\n\n    os.close();\n    is.close();\n  }\n\n  @Test\n  public void testSetSerializationView() {\n    Assertions.assertEquals(DEFAULT_SERIAL_CLASS, pp.getSerializationView());\n\n    pp.setSerializationView(null);\n    Assertions.assertEquals(DEFAULT_SERIAL_CLASS, pp.getSerializationView());\n\n    pp.setSerializationView(Object.class);\n    Assertions.assertEquals(Object.class.getCanonicalName(), pp.getSerializationView());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceProcessorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestProduceProcessorManager {\n  @Test\n  public void testDefault() {\n    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),\n        ProduceProcessorManager.INSTANCE.findDefaultProcessor());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceTextPlainProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.produce;\n\nimport static org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager.DEFAULT_SERIAL_CLASS;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.vertx.core.buffer.Buffer;\nimport org.junit.jupiter.api.Test;\n\npublic class TestProduceTextPlainProcessor {\n  final ProduceProcessor pp = ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor();\n\n  final JavaType stringType = TypeFactory.defaultInstance().constructType(String.class);\n\n  @Test\n  public void testEncodeResponseNull() throws Exception {\n    Buffer buffer = pp.encodeResponse(null);\n    Assertions.assertNull(buffer);\n\n    ByteArrayOutputStream os = new ByteArrayOutputStream();\n    pp.encodeResponse(os, null);\n    Assertions.assertEquals(0, os.size());\n  }\n\n  @Test\n  public void testdecodeResponseNull() throws Exception {\n    JavaType resultType = TypeFactory.unknownType();\n    Object result = pp.decodeResponse(Buffer.buffer(), resultType);\n    Assertions.assertNull(result);\n\n    ByteArrayInputStream is = new ByteArrayInputStream(\"\\\"\\\"\".getBytes(StandardCharsets.UTF_8));\n    result = pp.decodeResponse(is, resultType);\n    Assertions.assertEquals(result, \"\");\n  }\n\n  @Test\n  public void testBufferNormal() throws Exception {\n    String value = \"abc\";\n    Buffer buffer = pp.encodeResponse(value);\n    Assertions.assertEquals(value, buffer.toString(StandardCharsets.UTF_8));\n\n    Object result = pp.decodeResponse(buffer, stringType);\n    Assertions.assertEquals(value, result);\n  }\n\n  @Test\n  public void testStreamNormal() throws Exception {\n    String value = \"abc\";\n    ByteArrayOutputStream os = new ByteArrayOutputStream();\n\n    pp.encodeResponse(os, value);\n    Assertions.assertEquals(value, os.toString(StandardCharsets.UTF_8.name()));\n\n    ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());\n    Object result = pp.decodeResponse(is, stringType);\n    Assertions.assertEquals(value, result);\n\n    os.close();\n    is.close();\n  }\n\n  @Test\n  public void testSetSerializationView() {\n    Assertions.assertEquals(DEFAULT_SERIAL_CLASS, pp.getSerializationView());\n\n    pp.setSerializationView(null);\n    Assertions.assertEquals(DEFAULT_SERIAL_CLASS, pp.getSerializationView());\n\n    pp.setSerializationView(Object.class);\n    Assertions.assertEquals(\"java.lang.Object\", pp.getSerializationView());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecCsvTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nclass QueryCodecCsvTest extends QueryCodecTestBase {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @BeforeEach\n  void setUp() {\n    codec = new QueryCodecCsv();\n  }\n\n  @Nested\n  class Encode {\n    @Test\n    void should_encode_date() throws Exception {\n      should_encode(\"?q=1970-01-01T00%3A00%3A00.000%2B00%3A00\", new Date(0));\n    }\n\n    @Test\n    void should_encode_single_value() throws Exception {\n      should_encode(\"?q=v1\", \"v1\");\n    }\n\n    @Test\n    void should_encode_empty_string() throws Exception {\n      should_encode(\"?q=\", \"\");\n    }\n\n    @Test\n    void should_encode_common_string() throws Exception {\n      should_encode(\"?q=v1%2Cv2\", \"v1\", \"v2\");\n    }\n\n    @Test\n    void should_encode_common_numbers() throws Exception {\n      should_encode(\"?q=1%2C2\", 1, 2);\n    }\n\n    @Test\n    void should_encode_chinese_values() throws Exception {\n      should_encode(\"?q=%E4%B8%AD%E6%96%87%2Cv2\", \"中文\", \"v2\");\n    }\n\n    @Test\n    void should_encode_ignore_null() throws Exception {\n      should_encode(\"?q=v1%2Cv2\", \"v1\", null, \"v2\");\n    }\n\n    @Test\n    void should_encode_when_values_is_empty_after_ignore_null() throws Exception {\n      should_encode(\"\", new Object[] {null});\n    }\n  }\n\n  @Nested\n  class Decode {\n    @Test\n    void should_decode_single_value_to_array() {\n      should_decode(\"1\", new int[] {1});\n    }\n\n    @Test\n    void should_decode_common_values_to_array() {\n      should_decode(\"1,2\", new int[] {1, 2});\n    }\n\n    @Test\n    void should_decode_null_to_array() {\n      should_decode((String) null, new int[] {});\n    }\n\n    @Test\n    void should_decode_empty_string_to_number() {\n      should_decode(\"\", new int[] {0});\n    }\n\n    @Test\n    void should_decode_empty_string_to_string() {\n      should_decode(\"\", new String[] {\"\"});\n    }\n\n    @Test\n    void should_decode_common_values_with_empty_string_to_array() {\n      should_decode(\"1,,2\", new int[] {1, 0, 2});\n    }\n\n    @Test\n    void should_decode_values_end_with_delimiter() {\n      should_decode(\"1,,\", new int[] {1, 0, 0});\n    }\n\n    @Test\n    void should_decode_values_start_with_delimiter() {\n      should_decode(\",,1\", new int[] {0, 0, 1});\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecMultiTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nclass QueryCodecMultiTest extends QueryCodecTestBase {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n    codec = new QueryCodecMulti();\n  }\n\n  @Nested\n  class Encode {\n    @Test\n    void should_encode_date() throws Exception {\n      should_encode(\"?q=1970-01-01T00%3A00%3A00.000%2B00%3A00\", new Date(0));\n    }\n\n    @Test\n    void should_encode_single_value() throws Exception {\n      should_encode(\"?q=v1\", \"v1\");\n    }\n\n    @Test\n    void should_encode_empty_string() throws Exception {\n      should_encode(\"?q=\", \"\");\n    }\n\n    @Test\n    void should_encode_common_string() throws Exception {\n      should_encode(\"?q=v1&q=v2\", \"v1\", \"v2\");\n    }\n\n    @Test\n    void should_encode_common_numbers() throws Exception {\n      should_encode(\"?q=1&q=2\", 1, 2);\n    }\n\n    @Test\n    void should_encode_chinese_values() throws Exception {\n      should_encode(\"?q=%E4%B8%AD%E6%96%87&q=v2\", \"中文\", \"v2\");\n    }\n\n    @Test\n    void should_encode_ignore_null() throws Exception {\n      should_encode(\"?q=v1&q=v2\", \"v1\", null, \"v2\");\n    }\n\n    @Test\n    void should_encode_when_values_is_empty_after_ignore_null() throws Exception {\n      should_encode(\"\", new Object[] {null});\n    }\n  }\n\n  @Nested\n  class Decode {\n    @Test\n    void should_decode_single_value_to_array() {\n      should_decode(new String[] {\"1\"}, new int[] {1});\n    }\n\n    @Test\n    void should_decode_common_values_to_array() {\n      should_decode(new String[] {\"1\", \"2\"}, new int[] {1, 2});\n    }\n\n    @Test\n    void should_decode_empty_string_to_array() {\n      should_decode(new String[] {\"\"}, new int[] {0});\n    }\n\n    @Test\n    void should_decode_common_values_with_empty_string_to_array() {\n      should_decode(new String[] {\"1\", \"\", \"2\"}, new int[] {1, 0, 2});\n    }\n\n    @Test\n    void should_decode_single_value_to_single() {\n      should_decode(\"1\", 1);\n    }\n\n    @Test\n    void should_decode_null_to_single() {\n      should_decode((String) null, null);\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecPipesTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nclass QueryCodecPipesTest extends QueryCodecTestBase {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @BeforeEach\n  void setUp() {\n    codec = new QueryCodecPipes();\n  }\n\n  @Nested\n  class Encode {\n    @Test\n    void should_encode_date() throws Exception {\n      should_encode(\"?q=1970-01-01T00%3A00%3A00.000%2B00%3A00\", new Date(0));\n    }\n\n    @Test\n    void should_encode_single_value() throws Exception {\n      should_encode(\"?q=v1\", \"v1\");\n    }\n\n    @Test\n    void should_encode_empty_string() throws Exception {\n      should_encode(\"?q=\", \"\");\n    }\n\n    @Test\n    void should_encode_common_string() throws Exception {\n      should_encode(\"?q=v1%7Cv2\", \"v1\", \"v2\");\n    }\n\n    @Test\n    void should_encode_common_numbers() throws Exception {\n      should_encode(\"?q=1%7C2\", 1, 2);\n    }\n\n    @Test\n    void should_encode_chinese_values() throws Exception {\n      should_encode(\"?q=%E4%B8%AD%E6%96%87%7Cv2\", \"中文\", \"v2\");\n    }\n\n    @Test\n    void should_encode_ignore_null() throws Exception {\n      should_encode(\"?q=v1%7Cv2\", \"v1\", null, \"v2\");\n    }\n\n    @Test\n    void should_encode_when_values_is_empty_after_ignore_null() throws Exception {\n      should_encode(\"\", new Object[] {null});\n    }\n  }\n\n  @Nested\n  class Decode {\n    @Test\n    void should_decode_single_value_to_array() {\n      should_decode(\"1\", new int[] {1});\n    }\n\n    @Test\n    void should_decode_common_values_to_array() {\n      should_decode(\"1|2\", new int[] {1, 2});\n    }\n\n    @Test\n    void should_decode_null_to_array() {\n      should_decode((String) null, new int[] {});\n    }\n\n    @Test\n    void should_decode_empty_string_to_number() {\n      should_decode(\"\", new int[] {0});\n    }\n\n    @Test\n    void should_decode_empty_string_to_string() {\n      should_decode(\"\", new String[] {\"\"});\n    }\n\n    @Test\n    void should_decode_common_values_with_empty_string_to_array() {\n      should_decode(\"1||2\", new int[] {1, 0, 2});\n    }\n\n    @Test\n    void should_decode_values_end_with_delimiter() {\n      should_decode(\"1||\", new int[] {1, 0, 0});\n    }\n\n    @Test\n    void should_decode_values_start_with_delimiter() {\n      should_decode(\"||1\", new int[] {0, 0, 1});\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecSsvTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class QueryCodecSsvTest extends QueryCodecTestBase {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @BeforeEach\n  void setUp() {\n    codec = new QueryCodecSsv();\n  }\n\n  @Nested\n  class Encode {\n    @Test\n    void should_encode_date() throws Exception {\n      should_encode(\"?q=1970-01-01T00%3A00%3A00.000%2B00%3A00\", new Date(0));\n    }\n\n    @Test\n    void should_encode_single_value() throws Exception {\n      should_encode(\"?q=v1\", \"v1\");\n    }\n\n    @Test\n    void should_encode_empty_string() throws Exception {\n      should_encode(\"?q=\", \"\");\n    }\n\n    @Test\n    void should_encode_common_string() throws Exception {\n      should_encode(\"?q=v1+v2\", \"v1\", \"v2\");\n    }\n\n    @Test\n    void should_encode_common_numbers() throws Exception {\n      should_encode(\"?q=1+2\", 1, 2);\n    }\n\n    @Test\n    void should_encode_chinese_values() throws Exception {\n      should_encode(\"?q=%E4%B8%AD%E6%96%87+v2\", \"中文\", \"v2\");\n    }\n\n    @Test\n    void should_encode_ignore_null() throws Exception {\n      should_encode(\"?q=v1+v2\", \"v1\", null, \"v2\");\n    }\n\n    @Test\n    void should_encode_when_values_is_empty_after_ignore_null() throws Exception {\n      should_encode(\"\", new Object[] {null});\n    }\n  }\n\n  @Nested\n  class Decode {\n    @Test\n    void should_decode_single_value_to_array() {\n      should_decode(\"1\", new int[] {1});\n    }\n\n    @Test\n    void should_decode_common_values_to_array() {\n      should_decode(\"1 2\", new int[] {1, 2});\n    }\n\n    @Test\n    void should_decode_null_to_array() {\n      should_decode((String) null, new int[] {});\n    }\n\n    @Test\n    void should_decode_empty_string_to_number() {\n      should_decode(\"\", new int[] {0});\n    }\n\n    @Test\n    void should_decode_empty_string_to_string() {\n      should_decode(\"\", new String[] {\"\"});\n    }\n\n    @Test\n    void should_decode_common_values_with_empty_string_to_array() {\n      should_decode(\"1  2\", new int[] {1, 0, 2});\n    }\n\n    @Test\n    void should_decode_values_end_with_delimiter() {\n      should_decode(\"1  \", new int[] {1, 0, 0});\n    }\n\n    @Test\n    void should_decode_values_start_with_delimiter() {\n      should_decode(\"  1\", new int[] {0, 0, 1});\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecTestBase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.codec.param.QueryProcessorCreator.QueryProcessor;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.apache.servicecomb.foundation.vertx.http.AbstractHttpServletRequest;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\n\npublic class QueryCodecTestBase {\n  QueryCodec codec;\n\n  final String queryName = \"q\";\n\n  void should_encode(String encodedValue, Object... values) throws Exception {\n    URLPathStringBuilder builder = new URLPathStringBuilder();\n    codec.encode(builder, queryName, values);\n\n    assertThat(builder.build()).isEqualTo(encodedValue);\n  }\n\n  void should_decode(String value, Object decodedValue) {\n    HttpServletRequest request = new AbstractHttpServletRequest() {\n      @Override\n      public String getParameter(String name) {\n        return value;\n      }\n    };\n\n    should_decode(request, decodedValue);\n  }\n\n  void should_decode(String[] value, Object decodedValue) {\n    HttpServletRequest request = new AbstractHttpServletRequest() {\n      @Override\n      public String[] getParameterValues(String name) {\n        return value;\n      }\n    };\n\n    should_decode(request, decodedValue);\n  }\n\n  private void should_decode(HttpServletRequest request, Object decodedValue) {\n    Class<?> targetType = decodedValue == null ? Object.class : decodedValue.getClass();\n\n    QueryParameter queryParameter = new QueryParameter();\n    queryParameter.setSchema(new Schema());\n    queryParameter.getSchema().setFormat(codec.getCodecName());\n    if (targetType.isArray()) {\n      queryParameter.setSchema(new ArraySchema());\n    }\n\n    QueryProcessor queryProcessor = new QueryProcessor(queryParameter,\n        TypeFactory.defaultInstance().constructType(targetType));\n\n    Object values = codec.decode(queryProcessor, request);\n\n    assertThat(values).isEqualTo(decodedValue);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecsTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.codec.query;\n\nimport static java.util.Collections.singletonList;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport org.junit.jupiter.api.Test;\n\nclass QueryCodecsTest {\n  static class MyQueryCodecCsv extends QueryCodecCsv {\n    @Override\n    public int getOrder() {\n      return 0;\n    }\n  }\n\n  @Test\n  void can_override_by_customize_implement() {\n    QueryCodecs queryCodecs = QueryCodecs.createForTest();\n    assertThat(queryCodecs.find(QueryCodecCsv.CODEC_NAME).getClass())\n        .isEqualTo(QueryCodecCsv.class);\n\n    queryCodecs = new QueryCodecs(singletonList(new MyQueryCodecCsv()));\n    assertThat(queryCodecs.find(QueryCodecCsv.CODEC_NAME).getClass())\n        .isEqualTo(MyQueryCodecCsv.class);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.path.PathRegExp;\nimport org.apache.servicecomb.common.rest.definition.path.QueryVarParamWriter;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.PathParameter;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\n\npublic class TestPath {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @BeforeEach\n  public void setUp() {\n  }\n\n  @AfterEach\n  public void tearDown() {\n  }\n\n  @Test\n  public void testPathRegExp() throws Exception {\n    PathRegExp oPathRegExp = new PathRegExp(\"//{test}//\");\n    Assertions.assertEquals(1, oPathRegExp.getGroupCount());\n    Assertions.assertEquals(0, oPathRegExp.getGroupWithRegExpCount());\n    PathRegExp oSecondPathRegExp = new PathRegExp(\"{[^/:]+?}\");\n    Assertions.assertEquals(1, oSecondPathRegExp.getGroupCount());\n    Assertions.assertEquals(1, oSecondPathRegExp.getGroupWithRegExpCount());\n    Assertions.assertEquals(\"test/\", PathRegExp.ensureEndWithSlash(\"test/\"));\n    Assertions.assertEquals(\"test/\", PathRegExp.ensureEndWithSlash(\"test\"));\n    Assertions.assertNull(oSecondPathRegExp.match(\"{test/test}\", null));\n    Assertions.assertEquals(\"(]+?)/(.*)\", (oSecondPathRegExp.toString()));\n    Assertions.assertFalse(oSecondPathRegExp.isStaticPath());\n    Assertions.assertEquals(0, oSecondPathRegExp.getStaticCharCount());\n    Assertions.assertNotEquals(null, (oPathRegExp.match(\"//{test}//\", new HashMap<>())));\n    // Error Scenarios\n    new PathRegExp(\"//{test \\t}//\");\n    // Error Scenarios for double {{\n    try {\n      new PathRegExp(\"//{test{\");\n      Assertions.fail(\"an exception is expected!\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"A variable must not contain an extra\"));\n    }\n    // Error Scenarios for illegal }}\n    try {\n      new PathRegExp(\"//}\");\n      Assertions.fail(\"an exception is expected!\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"is only allowed as\"));\n    }\n    // Error Scenarios for illegal ;\n    try {\n      new PathRegExp(\"//;\");\n      Assertions.fail(\"an exception is expected!\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"matrix parameters are not allowed in\"));\n    }\n\n    // Error Scenarios for NO } ;\n    try {\n      new PathRegExp(\"//{test\");\n      Assertions.fail(\"an exception is expected!\");\n    } catch (Exception e) {\n      Assertions.assertTrue(e.getMessage().contains(\"No '}' found after\"));\n    }\n  }\n\n  @Test\n  public void testUrlPathBuilder() throws Exception {\n    Map<String, RestParam> paramMap = new HashMap<>();\n\n    Parameter pathParameter = new PathParameter();\n    pathParameter.setName(\"id\");\n    pathParameter.setSchema(new Schema<>());\n    RestParam oRestParam = new RestParam(null, pathParameter, int.class);\n    paramMap.put(oRestParam.getParamName(), oRestParam);\n\n    Parameter queryParameter = new QueryParameter();\n    queryParameter.setName(\"q\");\n    queryParameter.setSchema(new Schema<>());\n    oRestParam = new RestParam(null, queryParameter, String.class);\n    paramMap.put(oRestParam.getParamName(), oRestParam);\n\n    URLPathBuilder oURLPathBuilder = new URLPathBuilder(\"/root/{id}\", paramMap);\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"id\", 100);\n    parameters.put(\"q\", \"query\");\n    Assertions.assertEquals(\"/root/100?q=query\", oURLPathBuilder.createRequestPath(parameters));\n    Assertions.assertEquals(\"/root/100\", oURLPathBuilder.createPathString(parameters));\n  }\n\n  @Test\n  public void testQueryVarParamWriter() {\n    boolean status = true;\n\n    Parameter parameter = new QueryParameter();\n    parameter.setSchema(new Schema<>());\n    RestParam restParam = new RestParam(null, parameter, String.class);\n    RestParam spy = Mockito.spy(restParam);\n    Mockito.when(spy.getParamName()).thenReturn(\"queryVar\");\n    QueryVarParamWriter writer = new QueryVarParamWriter(spy);\n    try {\n      Map<String, Object> parameters = new HashMap<>();\n      parameters.put(\"queryVar\", \"T\");\n      verify(writer, parameters, \"?queryVar=T\");\n      parameters.put(\"queryVar\", null);\n      verify(writer, parameters, \"\");\n      parameters.put(\"queryVar\", new String[] {\"a\", \"b\"});\n      verify(writer, parameters, \"?queryVar=a&queryVar=b\");\n      parameters.put(\"queryVar\", new String[] {\"a\", null, \"b\"});\n      verify(writer, parameters, \"?queryVar=a&queryVar=b\");\n      parameters.put(\"queryVar\", Arrays.asList(\"Lars\", \"Simon\"));\n      verify(writer, parameters, \"?queryVar=Lars&queryVar=Simon\");\n      parameters.put(\"queryVar\", \"测试\");\n      verify(writer, parameters, \"?queryVar=%E6%B5%8B%E8%AF%95\");\n      parameters.put(\"queryVar\", \"a b\");\n      verify(writer, parameters, \"?queryVar=a+b\");\n      parameters.put(\"queryVar\", \"a+b\");\n      verify(writer, parameters, \"?queryVar=a%2Bb\");\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertTrue(status);\n  }\n\n  private void verify(QueryVarParamWriter writer, Map<String, Object> args, String expect) throws Exception {\n    URLPathStringBuilder sb = new URLPathStringBuilder();\n    writer.write(sb, args);\n    Assertions.assertEquals(expect, sb.build());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestRestOperationComparator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition;\n\nimport org.apache.servicecomb.common.rest.locator.MicroservicePaths;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestRestOperationComparator {\n  @Test\n  public void testStaticCharCount() {\n    RestOperationMeta less = new RestOperationMeta();\n    less.setAbsolutePath(\"/a/{id}\");\n\n    RestOperationMeta more = new RestOperationMeta();\n    more.setAbsolutePath(\"/abc/{id}\");\n\n    MicroservicePaths paths = new MicroservicePaths();\n    paths.addResource(less);\n    paths.addResource(more);\n    paths.sortPath();\n\n    Assertions.assertSame(more, paths.getDynamicPathOperationList().get(0));\n    Assertions.assertSame(less, paths.getDynamicPathOperationList().get(1));\n  }\n\n  @Test\n  public void testVarGroupCount() {\n    RestOperationMeta less = new RestOperationMeta();\n    less.setAbsolutePath(\"/ab/{id}\");\n\n    RestOperationMeta more = new RestOperationMeta();\n    more.setAbsolutePath(\"/a/{test}/{id}\");\n\n    MicroservicePaths paths = new MicroservicePaths();\n    paths.addResource(less);\n    paths.addResource(more);\n    paths.sortPath();\n\n    Assertions.assertSame(more, paths.getDynamicPathOperationList().get(0));\n    Assertions.assertSame(less, paths.getDynamicPathOperationList().get(1));\n  }\n\n  @Test\n  public void testGroupWithRegExpCount() {\n    RestOperationMeta less = new RestOperationMeta();\n    less.setAbsolutePath(\"/a/{test}/{id}\");\n\n    RestOperationMeta more = new RestOperationMeta();\n    more.setAbsolutePath(\"/a/{test : .+}/{id}\");\n\n    MicroservicePaths paths = new MicroservicePaths();\n    paths.addResource(less);\n    paths.addResource(more);\n    paths.sortPath();\n\n    Assertions.assertSame(more, paths.getDynamicPathOperationList().get(0));\n    Assertions.assertSame(less, paths.getDynamicPathOperationList().get(1));\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestRestOperationMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.hamcrest.core.Is.is;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.RestEngineSchemaListener;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.annotation.JsonView;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.servers.Server;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class TestRestOperationMeta {\n  @Path(\"/\")\n  static class RestOperationMetaSchema {\n    @Path(\"/emptyProduces\")\n    @GET\n    @Produces(value = MediaType.APPLICATION_JSON)\n    public String emptyProduces() {\n      return null;\n    }\n\n    @Path(\"/emptyProducesWithView\")\n    @GET\n    @Produces(value = MediaType.APPLICATION_JSON)\n    @JsonView(Object.class)\n    public String emptyProducesWithView() {\n      return null;\n    }\n\n    @Path(\"/notSupport\")\n    @GET\n    @Produces(value = MediaType.APPLICATION_JSON)\n    public void notSupport() {\n\n    }\n\n    @Path(\"/notSupportWithView\")\n    @GET\n    @Produces(value = MediaType.APPLICATION_JSON)\n    @JsonView(Object.class)\n    public void notSupportWithView() {\n\n    }\n\n    @Path(\"/textPlain\")\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    public String textPlain() {\n      return null;\n    }\n\n    @Path(\"/textPlainWithView\")\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    @JsonView(Object.class)\n    public String textPlainWithView() {\n      return null;\n    }\n\n    @Path(\"/json\")\n    @GET\n    @Produces(MediaType.APPLICATION_JSON)\n    public String json() {\n      return null;\n    }\n\n    @Path(\"/jsonWithView\")\n    @GET\n    @Produces(MediaType.APPLICATION_JSON)\n    @JsonView(Object.class)\n    public String jsonWithView() {\n      return null;\n    }\n\n    @Path(\"/textCharJsonChar\")\n    @GET\n    @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})\n    public void textCharJsonChar() {\n\n    }\n\n    @Path(\"/textCharJsonCharWithView\")\n    @GET\n    @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})\n    @JsonView(Object.class)\n    public void textCharJsonCharWithView() {\n\n    }\n\n    @Path(\"/download\")\n    @GET\n    @Produces(MediaType.APPLICATION_JSON)\n    public File download() {\n      return null;\n    }\n\n    @Path(\"/downloadWithView\")\n    @GET\n    @Produces(MediaType.APPLICATION_JSON)\n    @JsonView(Object.class)\n    public File downloadWithView() {\n      return null;\n    }\n\n    @Path(\"/form\")\n    @POST\n    public void form(@FormParam(\"form\") String form) {\n    }\n\n    @Path(\"/formWithView\")\n    @POST\n    public void formWithView(@FormParam(\"form\") String form) {\n    }\n  }\n\n  SCBEngine scbEngine;\n\n  OpenAPI swagger;\n\n  OperationMeta meta;\n\n  RestOperationMeta operationMeta;\n\n  @BeforeEach\n  public void setUp() {\n    Environment environment = Mockito.mock(Environment.class);\n    scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    scbEngine.setTransportManager(transportManager);\n    scbEngine.setExecutorManager(executorManager);\n\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION))\n        .thenReturn(BootStrapProperties.DEFAULT_APPLICATION);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME))\n        .thenReturn(\"test\");\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_ENVIRONMENT))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_ENVIRONMENT);\n\n    List<BootListener> listeners = new ArrayList<>();\n    listeners.add(new RestEngineSchemaListener());\n    scbEngine.setBootListeners(listeners);\n    scbEngine\n        .addProducerMeta(\"sid1\", new RestOperationMetaSchema())\n        .run();\n    swagger = Mockito.spy(scbEngine.getProducerMicroserviceMeta().ensureFindSchemaMeta(\"sid1\").getSwagger());\n  }\n\n  @AfterEach\n  public void teardown() {\n    scbEngine.destroy();\n  }\n\n  private void findOperation(String operationId) {\n    meta = Mockito.spy(scbEngine.getProducerMicroserviceMeta().operationMetas().get(\"test.sid1.\" + operationId));\n    operationMeta = Mockito.spy(RestMetaUtils.getRestOperationMeta(meta));\n    SchemaMeta schemaMeta = Mockito.spy(meta.getSchemaMeta());\n    Mockito.when(meta.getSchemaMeta()).thenReturn(schemaMeta);\n    Mockito.when(schemaMeta.getSwagger()).thenReturn(swagger);\n  }\n\n  @Test\n  public void generatesAbsolutePathWithRootBasePath() {\n    findOperation(\"textCharJsonChar\");\n\n    MatcherAssert.assertThat(operationMeta.getAbsolutePath(), is(\"/textCharJsonChar\"));\n  }\n\n  @Test\n  public void generatesAbsolutePathWithNonRootBasePath() {\n    findOperation(\"textCharJsonChar\");\n    Server server = Mockito.mock(Server.class);\n    Mockito.when(server.getUrl()).thenReturn(\"/rest\");\n    Mockito.when(swagger.getServers()).thenReturn(Arrays.asList(server));\n    RestOperationMeta restOperationMeta = new RestOperationMeta();\n    restOperationMeta.init(meta);\n\n    MatcherAssert.assertThat(restOperationMeta.getAbsolutePath(), is(\"/rest/textCharJsonChar\"));\n  }\n\n  @Test\n  public void generatesAbsolutePathWithNullPath() {\n    findOperation(\"textCharJsonChar\");\n    Server server = Mockito.mock(Server.class);\n    Mockito.when(server.getUrl()).thenReturn(null);\n    Mockito.when(swagger.getServers()).thenReturn(Arrays.asList(server));\n    Mockito.when(meta.getOperationPath()).thenReturn(null);\n    RestOperationMeta restOperationMeta = new RestOperationMeta();\n    restOperationMeta.init(meta);\n\n    MatcherAssert.assertThat(restOperationMeta.getAbsolutePath(), is(\"/\"));\n  }\n\n  @Test\n  public void generatesAbsolutePathWithEmptyPath() {\n    findOperation(\"textCharJsonChar\");\n    Server server = Mockito.mock(Server.class);\n    Mockito.when(server.getUrl()).thenReturn(\"\");\n    Mockito.when(swagger.getServers()).thenReturn(Arrays.asList(server));\n    Mockito.when(meta.getOperationPath()).thenReturn(\"\");\n    RestOperationMeta restOperationMeta = new RestOperationMeta();\n    restOperationMeta.init(meta);\n\n    MatcherAssert.assertThat(restOperationMeta.getAbsolutePath(), is(\"/\"));\n  }\n\n  @Test\n  public void consecutiveSlashesAreRemoved() {\n    findOperation(\"textCharJsonChar\");\n    Server server = Mockito.mock(Server.class);\n    Mockito.when(server.getUrl()).thenReturn(\"//rest//\");\n    Mockito.when(swagger.getServers()).thenReturn(Arrays.asList(server));\n    Mockito.when(meta.getOperationPath()).thenReturn(\"//sayHi//\");\n    RestOperationMeta restOperationMeta = new RestOperationMeta();\n    restOperationMeta.init(meta);\n\n    MatcherAssert.assertThat(restOperationMeta.getAbsolutePath(), is(\"/rest/sayHi/\"));\n  }\n\n  @Test\n  public void testFormDataFlagTrue() {\n    findOperation(\"form\");\n\n    MatcherAssert.assertThat(operationMeta.isFormData(), is(true));\n  }\n\n  @Test\n  public void testFormDataFlagFalse() {\n    findOperation(\"json\");\n\n    MatcherAssert.assertThat(operationMeta.isFormData(), is(false));\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/path/PathVarParamWriterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class PathVarParamWriterTest {\n\n  @Test\n  public void writePlainPath() throws Exception {\n    PathVarParamWriter pathVarParamWriter = createPathVarParamWriter();\n\n    URLPathStringBuilder pathBuilder = new URLPathStringBuilder();\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"test\", \"abc\");\n    pathVarParamWriter.write(pathBuilder, parameters);\n    Assertions.assertEquals(\"abc\", pathBuilder.build());\n  }\n\n  @Test\n  public void writePathWithSpace() throws Exception {\n    PathVarParamWriter pathVarParamWriter = createPathVarParamWriter();\n\n    URLPathStringBuilder pathBuilder = new URLPathStringBuilder();\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"test\", \"a 20bc\");\n    pathVarParamWriter.write(pathBuilder, parameters);\n    Assertions.assertEquals(\"a%2020bc\", pathBuilder.build());\n  }\n\n  @Test\n  public void writePathWithPercentage() throws Exception {\n    PathVarParamWriter pathVarParamWriter = createPathVarParamWriter();\n    URLPathStringBuilder pathBuilder = new URLPathStringBuilder();\n    pathBuilder.appendPath(\"/api/\");\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"test\", \"a%%bc\");\n    pathVarParamWriter.write(pathBuilder, parameters);\n    Assertions.assertEquals(\"/api/a%25%25bc\", pathBuilder.build());\n  }\n\n  @Test\n  public void writePathParamWithSlash() throws Exception {\n    PathVarParamWriter pathVarParamWriter = createPathVarParamWriter();\n    URLPathStringBuilder pathBuilder = new URLPathStringBuilder();\n    pathBuilder.appendPath(\"/api/\");\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"test\", \"a/bc\");\n    pathVarParamWriter.write(pathBuilder, parameters);\n    Assertions.assertEquals(\"/api/a%2Fbc\", pathBuilder.build());\n  }\n\n  @Test\n  public void writeIntegerParam() throws Exception {\n    PathVarParamWriter pathVarParamWriter = createPathVarParamWriter();\n    URLPathStringBuilder pathBuilder = new URLPathStringBuilder();\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"test\", 12);\n    pathVarParamWriter.write(pathBuilder, parameters);\n    Assertions.assertEquals(\"12\", pathBuilder.build());\n  }\n\n  private PathVarParamWriter createPathVarParamWriter() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(restParam.getParamName()).thenReturn(\"test\");\n    return new PathVarParamWriter(restParam);\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/path/QueryVarParamWriterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter.StyleEnum;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\n\npublic class QueryVarParamWriterTest {\n  private static QueryVarParamWriter queryVarParamWriterCsv;\n\n  private static QueryVarParamWriter queryVarParamWriterMulti;\n\n  private static QueryVarParamWriter queryVarParamWriterDefault;\n\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n\n    QueryParameter parameter = new QueryParameter();\n    parameter.setName(\"q\");\n    parameter.setSchema(new Schema());\n    parameter.setStyle(StyleEnum.FORM);\n    parameter.setExplode(false);\n    queryVarParamWriterCsv = new QueryVarParamWriter(\n        new RestParam(null, parameter, String[].class));\n\n    parameter = new QueryParameter();\n    parameter.setName(\"q\");\n    parameter.setSchema(new Schema());\n    parameter.setStyle(StyleEnum.FORM);\n    parameter.setExplode(true);\n    queryVarParamWriterMulti = new QueryVarParamWriter(\n        new RestParam(null, parameter, String[].class));\n\n    parameter = new QueryParameter();\n    parameter.setName(\"q\");\n    parameter.setSchema(new Schema());\n    queryVarParamWriterDefault = new QueryVarParamWriter(\n        new RestParam(null, parameter, String[].class));\n  }\n\n  @Test\n  public void write() throws Exception {\n    URLPathStringBuilder stringBuilder = new URLPathStringBuilder();\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"q\", \"a\");\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a\", stringBuilder.build());\n  }\n\n  @Test\n  public void writeNull() throws Exception {\n    URLPathStringBuilder stringBuilder = new URLPathStringBuilder();\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"test\", null);\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n  }\n\n  @Test\n  public void writeArray() throws Exception {\n    URLPathStringBuilder stringBuilder = new URLPathStringBuilder();\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"q\", new String[] {\"ab\", \"cd\", \"ef\"});\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab%2Ccd%2Cef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=ef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=ef\", stringBuilder.build());\n\n    // encode space char\n    stringBuilder = new URLPathStringBuilder();\n    parameters.put(\"q\", new String[] {\"a b\", \" \", \"\", \"ef\"});\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a+b%2C+%2C%2Cef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a+b&q=+&q=&q=ef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a+b&q=+&q=&q=ef\", stringBuilder.build());\n\n    // pass blank string\n    stringBuilder = new URLPathStringBuilder();\n    parameters.put(\"q\", new String[] {\"\"});\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=\", stringBuilder.build());\n\n    // pass empty\n    stringBuilder = new URLPathStringBuilder();\n    parameters.put(\"q\", new String[] {});\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    // pass null\n    parameters.put(\"q\", new String[] {null});\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n\n    parameters.put(\"q\", new String[] {null, \"ab\", null, \"cd\", null, null, \"\", null, \"ef\", null});\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab%2Ccd%2C%2Cef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=&q=ef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=&q=ef\", stringBuilder.build());\n  }\n\n  @Test\n  public void writeList() throws Exception {\n    List<String> queryList = Arrays.asList(\"ab\", \"cd\", \"ef\");\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"q\", queryList);\n    URLPathStringBuilder stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab%2Ccd%2Cef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=ef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=ef\", stringBuilder.build());\n\n    // encode space char\n    parameters.put(\"q\", Arrays.asList(\"a b\", \" \", \"\", \"ef\"));\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a+b%2C+%2C%2Cef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a+b&q=+&q=&q=ef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=a+b&q=+&q=&q=ef\", stringBuilder.build());\n\n    // pass blank string\n    stringBuilder = new URLPathStringBuilder();\n    parameters.put(\"q\", Collections.singletonList(\"\"));\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=\", stringBuilder.build());\n\n    // pass empty\n    stringBuilder = new URLPathStringBuilder();\n    parameters.put(\"q\", new ArrayList<>());\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    // pass null\n    parameters.put(\"q\", Collections.singletonList(null));\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"\", stringBuilder.build());\n\n    parameters.put(\"q\", Arrays.asList(null, \"ab\", null, \"cd\", null, null, \"\", null, \"ef\", null));\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterCsv.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab%2Ccd%2C%2Cef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterMulti.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=&q=ef\", stringBuilder.build());\n    stringBuilder = new URLPathStringBuilder();\n    queryVarParamWriterDefault.write(stringBuilder, parameters);\n    Assertions.assertEquals(\"?q=ab&q=cd&q=&q=ef\", stringBuilder.build());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/path/URLPathBuilderTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport java.lang.reflect.Type;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.PathParameter;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\n\npublic class URLPathBuilderTest {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void beforeClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.emptyAsNull\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreDefaultValue\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.query.ignoreRequiredCheck\", boolean.class, false))\n        .thenReturn(false);\n  }\n\n  @Test\n  public void testNormal() throws Exception {\n    Map<String, RestParam> paramMap = new LinkedHashMap<>();\n    addParam(\"p0\", int.class, PathParameter::new, paramMap);\n    addParam(\"p1\", String.class, PathParameter::new, paramMap);\n    addParam(\"q0\", int.class, QueryParameter::new, paramMap);\n    addParam(\"q1\", String.class, QueryParameter::new, paramMap);\n\n    URLPathBuilder urlPathBuilder = new URLPathBuilder(\"/path/{p0}/and/{p1}\", paramMap);\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"p0\", 10);\n    parameters.put(\"p1\", \"abcPath\");\n    parameters.put(\"q0\", 11);\n    parameters.put(\"q1\", \"queryABC\");\n    Assertions.assertEquals(\"/path/10/and/abcPath?q0=11&q1=queryABC\",\n        urlPathBuilder.createRequestPath(parameters));\n    Assertions.assertEquals(\"/path/10/and/abcPath\",\n        urlPathBuilder.createPathString(parameters));\n  }\n\n  @Test\n  public void testEncode() throws Exception {\n    Map<String, RestParam> paramMap = new LinkedHashMap<>();\n    addParam(\"p\", String.class, PathParameter::new, paramMap);\n    addParam(\"q\", String.class, QueryParameter::new, paramMap);\n\n    URLPathBuilder urlPathBuilder = new URLPathBuilder(\"/path/{p}\", paramMap);\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"p\", \"ab%% %cd%\");\n    parameters.put(\"q\", \"ab%% %cd%\");\n    Assertions.assertEquals(\"/path/ab%25%25%20%25cd%25?q=ab%25%25+%25cd%25\",\n        urlPathBuilder.createRequestPath(parameters));\n    Assertions.assertEquals(\"/path/ab%25%25%20%25cd%25\",\n        urlPathBuilder.createPathString(parameters));\n  }\n\n  @Test\n  public void testMultiQuery() throws Exception {\n    Map<String, RestParam> paramMap = new LinkedHashMap<>();\n    addParam(\"strArr\", String[].class, QueryParameter::new, paramMap);\n    addParam(\"intArr\", int[].class, QueryParameter::new, paramMap);\n\n    URLPathBuilder urlPathBuilder = new URLPathBuilder(\"/path\", paramMap);\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"strArr\", new Object[] {\"a\", \"b\", \"c\"});\n    parameters.put(\"intArr\", new Object[] {1, 2, 3});\n    Assertions.assertEquals(\"/path?strArr=a&strArr=b&strArr=c&intArr=1&intArr=2&intArr=3\",\n        urlPathBuilder.createRequestPath(parameters));\n    parameters.put(\"strArr\", new Object[] {});\n    parameters.put(\"intArr\", new Object[] {1, 2, 3});\n    Assertions.assertEquals(\"/path?intArr=1&intArr=2&intArr=3\",\n        urlPathBuilder.createRequestPath(parameters));\n    parameters.put(\"strArr\", new Object[] {\"a\", \"b\", \"c\"});\n    parameters.put(\"intArr\", new Object[] {});\n    Assertions.assertEquals(\"/path?strArr=a&strArr=b&strArr=c\",\n        urlPathBuilder.createRequestPath(parameters));\n    parameters.put(\"strArr\", new Object[] {});\n    parameters.put(\"intArr\", new Object[] {});\n    Assertions.assertEquals(\"/path\",\n        urlPathBuilder.createRequestPath(parameters));\n  }\n\n  @Test\n  public void testRegexPathParam() throws Exception {\n    Map<String, RestParam> paramMap = new LinkedHashMap<>();\n    addParam(\"p0\", int.class, PathParameter::new, paramMap);\n    addParam(\"p1\", String.class, PathParameter::new, paramMap);\n    addParam(\"q0\", int.class, QueryParameter::new, paramMap);\n    addParam(\"q1\", String.class, QueryParameter::new, paramMap);\n\n    URLPathBuilder urlPathBuilder = new URLPathBuilder(\"/path/{p0 : .*}/and/{p1:.*}\", paramMap);\n    Map<String, Object> parameters = new HashMap<>();\n    parameters.put(\"p0\", 10);\n    parameters.put(\"p1\", \"abcPath\");\n    parameters.put(\"q0\", 11);\n    parameters.put(\"q1\", \"queryABC\");\n    Assertions.assertEquals(\"/path/10/and/abcPath?q0=11&q1=queryABC\",\n        urlPathBuilder.createRequestPath(parameters));\n    Assertions.assertEquals(\"/path/10/and/abcPath\",\n        urlPathBuilder.createPathString(parameters));\n  }\n\n  private void addParam(String paramName, Type paramType,\n      ParameterConstructor constructor, Map<String, RestParam> paramMap) {\n    Parameter parameter = constructor.construct();\n    parameter.setName(paramName);\n    parameter.setSchema(new Schema());\n    paramMap.put(paramName, new RestParam(null, parameter, paramType));\n  }\n\n  interface ParameterConstructor {\n    Parameter construct();\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/path/URLPathStringBuilderTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.definition.path;\n\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder.URLPathStringBuilder;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class URLPathStringBuilderTest {\n  @Test\n  public void testNormal() {\n    URLPathStringBuilder builder = new URLPathStringBuilder();\n    builder.appendPath(\"/path\");\n    builder.appendQuery(\"q\", \"abc\");\n    Assertions.assertEquals(\"/path?q=abc\", builder.build());\n  }\n\n  @Test\n  public void appendPath() {\n    URLPathStringBuilder builder = new URLPathStringBuilder();\n    builder.appendPath(\"/abc\");\n    Assertions.assertEquals(\"/abc\", builder.build());\n    builder.appendPath(\"/de fg\");\n    Assertions.assertEquals(\"/abc/de fg\", builder.build());\n  }\n\n  @Test\n  public void appendQuery() {\n    URLPathStringBuilder builder = new URLPathStringBuilder();\n    Assertions.assertEquals(\"\", builder.build());\n    builder.appendQuery(\"ab\", \"cd\");\n    Assertions.assertEquals(\"?ab=cd\", builder.build());\n    builder.appendQuery(\"ef\", \"\");\n    Assertions.assertEquals(\"?ab=cd&ef=\", builder.build());\n    builder.appendQuery(\"gh\", \"jk\");\n    Assertions.assertEquals(\"?ab=cd&ef=&gh=jk\", builder.build());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.filter.inner;\n\nimport static com.google.common.net.HttpHeaders.CONTENT_LENGTH;\nimport static com.google.common.net.HttpHeaders.TRANSFER_ENCODING;\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport java.io.ByteArrayInputStream;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\n\nimport org.apache.servicecomb.common.rest.HttpTransportContext;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.SCBStatus;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.foundation.common.part.InputStreamPart;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.StringSchema;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport io.vertx.core.MultiMap;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class RestServerCodecFilterTest {\n  final RestServerCodecFilter codecFilter = new RestServerCodecFilter();\n\n  Invocation invocation;\n\n  final Endpoint endpoint = Mockito.mock(Endpoint.class);\n\n  final OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n\n  final SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n\n  final MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n\n  final InvocationRuntimeType invocationRuntimeType = Mockito.mock(InvocationRuntimeType.class);\n\n  final RestOperationMeta restOperationMeta = Mockito.mock(RestOperationMeta.class);\n\n  final HttpTransportContext transportContext = Mockito.mock(HttpTransportContext.class);\n\n  final HttpServletResponseEx responseEx = Mockito.mock(HttpServletResponseEx.class);\n\n  final MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n\n  final Part part = new InputStreamPart(\"ok\", new ByteArrayInputStream(new byte[] {1, 2}));\n\n  final FilterNode nextNode = new FilterNode(new AbstractFilter() {\n    @Override\n    public String getName() {\n      return \"f2\";\n    }\n\n    @Override\n    public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n      Response response = Response.ok(part);\n      response.setHeaders(headers);\n      return CompletableFuture.completedFuture(response);\n    }\n  });\n\n  static SCBEngine engine;\n\n  @BeforeAll\n  public static void beforeClass() {\n    Environment environment = Mockito.mock(Environment.class);\n    engine = SCBBootstrap.createSCBEngineForTest(environment);\n    engine.setEnvironment(environment);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    engine.setStatus(SCBStatus.UP);\n  }\n\n  @AfterAll\n  public static void afterClass() {\n    engine.destroy();\n  }\n\n  @BeforeEach\n  public void setUp() {\n    Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n    Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n    Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);\n    invocation = Mockito.spy(InvocationFactory.forProvider(endpoint, operationMeta, null));\n    Mockito.when(responseEx.sendPart(part)).thenReturn(CompletableFuture.completedFuture(null));\n  }\n\n  private void mockDecodeRequestFail() {\n    Mockito.when(invocation.getTransportContext()).thenReturn(transportContext);\n    Mockito.when(transportContext.getResponseEx()).thenReturn(responseEx);\n    Mockito.when(invocation.getRequestEx())\n        .thenThrow(new RuntimeExceptionWithoutStackTrace(\"mock encode request failed\"));\n  }\n\n  @Test\n  public void should_not_invoke_filter_when_decode_request_failed() {\n    FilterNode nextNode = Mockito.mock(FilterNode.class);\n    mockDecodeRequestFail();\n\n    codecFilter.onFilter(invocation, nextNode);\n\n    Mockito.verify(nextNode, Mockito.times(0)).onFilter(invocation);\n  }\n\n  @Test\n  public void should_convert_exception_to_response_when_decode_request_failed()\n      throws ExecutionException, InterruptedException {\n    mockDecodeRequestFail();\n    Mockito.when(invocation.findResponseType(INTERNAL_SERVER_ERROR.getStatusCode()))\n        .thenReturn(TypeFactory.defaultInstance().constructType(String.class));\n\n    Assertions.assertThrows(ExecutionException.class,\n        () -> codecFilter.onFilter(invocation, nextNode).get());\n  }\n\n  private void success_invocation() throws InterruptedException, ExecutionException {\n    Mockito.when(invocation.getTransportContext()).thenReturn(transportContext);\n    HttpServletRequestEx requestExt = Mockito.mock(HttpServletRequestEx.class);\n    Mockito.when(invocation.getRequestEx()).thenReturn(requestExt);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Operation swaggerOperation = Mockito.mock(Operation.class);\n    Mockito.when(operationMeta.getSwaggerOperation()).thenReturn(swaggerOperation);\n    ApiResponses apiResponses = Mockito.mock(ApiResponses.class);\n    Mockito.when(swaggerOperation.getResponses()).thenReturn(apiResponses);\n    ApiResponse apiResponse = Mockito.mock(ApiResponse.class);\n    Mockito.when(apiResponses.get(\"200\")).thenReturn(apiResponse);\n    Content content = new Content();\n    content.addMediaType(MediaType.APPLICATION_JSON, new io.swagger.v3.oas.models.media.MediaType());\n    content.get(MediaType.APPLICATION_JSON).setSchema(new StringSchema());\n    Mockito.when(apiResponse.getContent()).thenReturn(content);\n    Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);\n    Mockito.when(invocation.findResponseType(INTERNAL_SERVER_ERROR.getStatusCode()))\n        .thenReturn(TypeFactory.defaultInstance().constructType(String.class));\n    JavaType javaType = Mockito.mock(JavaType.class);\n    Mockito.when(invocationRuntimeType.findResponseType(200)).thenReturn(javaType);\n    Mockito.when(javaType.getRawClass()).thenAnswer(invocationOnMock -> Part.class);\n    Mockito.when(invocation.getTransportContext()).thenReturn(transportContext);\n    Mockito.when(transportContext.getResponseEx()).thenReturn(responseEx);\n\n    codecFilter.onFilter(invocation, nextNode).get();\n  }\n\n  @Test\n  public void should_encode_response_header() throws ExecutionException, InterruptedException {\n    headers.add(\"h1\", \"v1\");\n    success_invocation();\n\n    Mockito.verify(responseEx).addHeader(\"h1\", \"v1\");\n  }\n\n  @Test\n  public void should_not_encode_content_length_header() throws ExecutionException, InterruptedException {\n    headers.add(\"h1\", \"v1\")\n        .add(\"h2\", \"v2\")\n        .add(CONTENT_LENGTH, \"10\");\n    success_invocation();\n\n    Mockito.verify(responseEx, Mockito.times(1)).addHeader(\"h1\", \"v1\");\n    Mockito.verify(responseEx, Mockito.times(1)).addHeader(\"h2\", \"v2\");\n  }\n\n  @Test\n  public void should_not_encode_transfer_encoding_header() throws ExecutionException, InterruptedException {\n    headers.add(\"h1\", \"v1\")\n        .add(\"h2\", \"v2\")\n        .add(TRANSFER_ENCODING, \"test\");\n    success_invocation();\n\n    Mockito.verify(responseEx, Mockito.times(1)).addHeader(\"h1\", \"v1\");\n    Mockito.verify(responseEx, Mockito.times(1)).addHeader(\"h2\", \"v2\");\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/locator/TestMicroservicePaths.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.locator;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.RestEngineSchemaListener;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestMicroservicePaths {\n  SCBEngine scbEngine;\n\n  MicroservicePaths paths;\n\n  @BeforeEach\n  public void setup() {\n    Environment environment = Mockito.mock(Environment.class);\n    scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION))\n        .thenReturn(BootStrapProperties.DEFAULT_APPLICATION);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_NAME);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_ENVIRONMENT))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_ENVIRONMENT);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    List<BootListener> listeners = new ArrayList<>();\n    listeners.add(new RestEngineSchemaListener());\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    scbEngine.setTransportManager(transportManager);\n    scbEngine.setExecutorManager(executorManager);\n    scbEngine.setBootListeners(listeners);\n    scbEngine.addProducerMeta(\"sid1\", new TestPathSchema())\n        .run();\n\n    ServicePathManager spm = ServicePathManager.getServicePathManager(scbEngine.getProducerMicroserviceMeta());\n    paths = spm.producerPaths;\n  }\n\n  @AfterEach\n  public void teardown() {\n    scbEngine.destroy();\n  }\n\n  @Test\n  public void staticGroup() {\n    RestOperationMeta meta = paths.getStaticPathOperationMap().get(\"/static/\").findValue(\"POST\");\n    Assertions.assertSame(\"postStatic\", meta.getOperationMeta().getOperationId());\n\n    meta = paths.getStaticPathOperationMap().get(\"/static/\").findValue(\"GET\");\n    Assertions.assertSame(\"getStatic\", meta.getOperationMeta().getOperationId());\n  }\n\n  @Test\n  public void testAddResourceStaticDuplicatedHttpMethod() {\n    RestOperationMeta staticResPost = Mockito.mock(RestOperationMeta.class);\n    Mockito.when(staticResPost.getHttpMethod()).thenReturn(\"POST\");\n    Mockito.when(staticResPost.getAbsolutePath()).thenReturn(\"/static/\");\n    Mockito.when(staticResPost.isAbsoluteStaticPath()).thenReturn(true);\n\n    ServiceCombException exception = Assertions.assertThrows(ServiceCombException.class,\n        () -> paths.addResource(staticResPost));\n    Assertions.assertEquals(\"operation with url /static/, method POST is duplicated.\", exception.getMessage());\n  }\n\n  @Test\n  public void dynamicPath() {\n    Assertions.assertEquals(\"dynamicExId\",\n        paths.getDynamicPathOperationList().get(0).getOperationMeta().getOperationId());\n    Assertions.assertEquals(\"dynamicId\",\n        paths.getDynamicPathOperationList().get(1).getOperationMeta().getOperationId());\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/locator/TestPathSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.locator;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.PathParam;\n\n@Path(\"/\")\npublic class TestPathSchema {\n  @Path(\"/static\")\n  @GET\n  public void getStatic() {\n\n  }\n\n  @Path(\"/static\")\n  @POST\n  public void postStatic() {\n\n  }\n\n  @Path(\"/staticEx\")\n  @GET\n  public void getStaticEx() {\n\n  }\n\n  @Path(\"/dynamic/{id}\")\n  @GET\n  public void dynamicId(@PathParam(\"id\") String id) {\n\n  }\n\n  @Path(\"/dynamicEx/{id}\")\n  @GET\n  public void dynamicExId(@PathParam(\"id\") String id) {\n\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/locator/TestServicePathManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.common.rest.locator;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.RestEngineSchemaListener;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestServicePathManager {\n  SCBEngine scbEngine;\n\n  Environment environment;\n\n  @BeforeEach\n  public void setUp() {\n    environment = Mockito.mock(Environment.class);\n    scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.parameter.decodeAsObject\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION))\n        .thenReturn(BootStrapProperties.DEFAULT_APPLICATION);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_NAME);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_ENVIRONMENT))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_ENVIRONMENT);\n  }\n\n  @AfterEach\n  public void tearDown() {\n    scbEngine.destroy();\n    ClassLoaderScopeContext.clearClassLoaderScopeProperty();\n  }\n\n  @Test\n  public void testBuildProducerPathsNoPrefix() {\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    scbEngine.setTransportManager(transportManager);\n    scbEngine.setExecutorManager(executorManager);\n    List<BootListener> listeners = new ArrayList<>();\n    listeners.add(new RestEngineSchemaListener());\n    scbEngine.setBootListeners(listeners);\n    scbEngine.addProducerMeta(\"sid1\", new TestPathSchema())\n        .run();\n\n    ServicePathManager spm = ServicePathManager.getServicePathManager(scbEngine.getProducerMicroserviceMeta());\n\n    Assertions.assertSame(spm.producerPaths, spm.swaggerPaths);\n\n    scbEngine.destroy();\n  }\n\n  @Test\n  public void testBuildProducerPathsHasPrefix() {\n    ClassLoaderScopeContext.setClassLoaderScopeProperty(DefinitionConst.URL_PREFIX, \"/root/rest\");\n\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(DefinitionConst.REGISTER_URL_PREFIX, boolean.class, false)).thenReturn(false);\n\n    ExecutorManager executorManager = Mockito.mock(ExecutorManager.class);\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    scbEngine.setTransportManager(transportManager);\n    scbEngine.setExecutorManager(executorManager);\n    List<BootListener> listeners = new ArrayList<>();\n    listeners.add(new RestEngineSchemaListener());\n    scbEngine.setBootListeners(listeners);\n    scbEngine.addProducerMeta(\"sid1\", new TestPathSchema())\n        .run();\n\n    ServicePathManager spm = ServicePathManager.getServicePathManager(scbEngine.getProducerMicroserviceMeta());\n\n    // all locate should be success\n    spm.producerLocateOperation(\"/root/rest/static/\", \"GET\");\n    spm.producerLocateOperation(\"/root/rest/static/\", \"POST\");\n    spm.producerLocateOperation(\"/root/rest/dynamic/1/\", \"GET\");\n    spm.producerLocateOperation(\"/root/rest/dynamicEx/1/\", \"GET\");\n\n    scbEngine.destroy();\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/java/org/apache/servicecomb/common/rest/resource/TestClassPathStaticResourceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.common.rest.resource;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class TestClassPathStaticResourceHandler {\n  static ClassPathStaticResourceHandler handler = new ClassPathStaticResourceHandler();\n\n  @BeforeAll\n  public static void setup() {\n    handler.setWebRoot(\"web-root/\");\n  }\n\n  @Test\n  public void normal() throws IOException {\n    Response response = handler.handle(\"index.html\");\n    Part part = response.getResult();\n\n    try (InputStream is = part.getInputStream()) {\n      Assertions.assertTrue(IOUtils.toString(is, StandardCharsets.UTF_8).trim().endsWith(\"<html></html>\"));\n    }\n    Assertions.assertEquals(\"text/html\", part.getContentType());\n    Assertions.assertEquals(\"text/html\", response.getHeader(HttpHeaders.CONTENT_TYPE));\n    Assertions.assertEquals(\"inline\", response.getHeader(HttpHeaders.CONTENT_DISPOSITION));\n  }\n\n  @Test\n  public void notExist() {\n    Response response = handler.handle(\"notExist.html\");\n\n    InvocationException invocationException = response.getResult();\n    Assertions.assertEquals(Status.NOT_FOUND, invocationException.getStatus());\n    Assertions.assertEquals(Status.NOT_FOUND.getReasonPhrase(),\n        ((CommonExceptionData) invocationException.getErrorData()).getMessage());\n    Assertions.assertEquals(404, response.getStatusCode());\n    Assertions.assertEquals(\"Not Found\", response.getReasonPhrase());\n  }\n\n  @Test\n  public void attack() {\n    Response response = handler.handle(\"../microservice.yaml\");\n\n    InvocationException invocationException = response.getResult();\n    Assertions.assertEquals(Status.NOT_FOUND, invocationException.getStatus());\n    Assertions.assertEquals(Status.NOT_FOUND.getReasonPhrase(),\n        ((CommonExceptionData) invocationException.getErrorData()).getMessage());\n    Assertions.assertEquals(404, response.getStatusCode());\n    Assertions.assertEquals(\"Not Found\", response.getReasonPhrase());\n  }\n\n  @Test\n  public void readContentFailed() throws IOException {\n    handler = Mockito.spy(TestClassPathStaticResourceHandler.handler);\n    Mockito.when(handler.findResource(\"web-root/index.html\"))\n        .thenThrow(new RuntimeExceptionWithoutStackTrace(\"read content failed.\"));\n\n    try (LogCollector logCollector = new LogCollector()) {\n      Response response = handler.handle(\"index.html\");\n\n      Assertions.assertEquals(\"failed to process static resource, path=web-root/index.html\",\n          logCollector.getLastEvents().getMessage().getFormattedMessage());\n\n      InvocationException invocationException = response.getResult();\n      Assertions.assertEquals(Status.INTERNAL_SERVER_ERROR, invocationException.getStatus());\n      Assertions.assertEquals(\"failed to process static resource.\",\n          ((CommonExceptionData) invocationException.getErrorData()).getMessage());\n      Assertions.assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());\n      Assertions.assertEquals(Status.INTERNAL_SERVER_ERROR.getReasonPhrase(), response.getReasonPhrase());\n    }\n  }\n}\n"
  },
  {
    "path": "common/common-rest/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "common/common-rest/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nAPPLICATION_ID: test\nservice_description:\n  name: test\n  version: 0.0.1\nservicecomb:\n  service:\n    registry:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n  highway:\n    address: 0.0.0.0:7070\n"
  },
  {
    "path": "common/common-rest/src/test/resources/web-root/index.html",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<html></html>\n"
  },
  {
    "path": "common/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>common</artifactId>\n  <name>Java Chassis::Common</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>common-protobuf</module>\n    <module>common-rest</module>\n    <module>common-access-log</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "core/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>java-chassis-core</artifactId>\n  <name>Java Chassis::Core</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.hibernate.validator</groupId>\n      <artifactId>hibernate-validator</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicecomb-governance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-autoconfigure</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n    <!-- test -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/BootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.springframework.core.Ordered;\n\npublic interface BootListener extends Ordered {\n  enum EventType {\n    BEFORE_FILTER,\n    AFTER_FILTER,\n    BEFORE_PRODUCER_PROVIDER,\n    AFTER_PRODUCER_PROVIDER,\n    BEFORE_CONSUMER_PROVIDER,\n    AFTER_CONSUMER_PROVIDER,\n    BEFORE_TRANSPORT,\n    AFTER_TRANSPORT,\n    BEFORE_REGISTRY,\n    AFTER_REGISTRY,\n    BEFORE_CLOSE,\n    AFTER_CLOSE\n  }\n\n  class BootEvent {\n    private SCBEngine scbEngine;\n\n    private EventType eventType;\n\n    public BootEvent() {\n    }\n\n    public BootEvent(SCBEngine scbEngine, EventType eventType) {\n      this.scbEngine = scbEngine;\n      this.eventType = eventType;\n    }\n\n    public SCBEngine getScbEngine() {\n      return scbEngine;\n    }\n\n    public BootEvent setScbEngine(SCBEngine scbEngine) {\n      this.scbEngine = scbEngine;\n      return this;\n    }\n\n    public EventType getEventType() {\n      return eventType;\n    }\n\n    public BootEvent setEventType(EventType eventType) {\n      this.eventType = eventType;\n      return this;\n    }\n  }\n\n  @Override\n  default int getOrder() {\n    return 0;\n  }\n\n  default void onBootEvent(BootEvent event) {\n    switch (event.eventType) {\n      case BEFORE_FILTER:\n        onBeforeFilter(event);\n        return;\n      case AFTER_FILTER:\n        onAfterFilter(event);\n        return;\n      case BEFORE_PRODUCER_PROVIDER:\n        onBeforeProducerProvider(event);\n        return;\n      case AFTER_PRODUCER_PROVIDER:\n        onAfterProducerProvider(event);\n        return;\n      case BEFORE_CONSUMER_PROVIDER:\n        onBeforeConsumerProvider(event);\n        return;\n      case AFTER_CONSUMER_PROVIDER:\n        onAfterConsumerProvider(event);\n        return;\n      case BEFORE_TRANSPORT:\n        onBeforeTransport(event);\n        return;\n      case AFTER_TRANSPORT:\n        onAfterTransport(event);\n        return;\n      case BEFORE_REGISTRY:\n        onBeforeRegistry(event);\n        return;\n      case AFTER_REGISTRY:\n        onAfterRegistry(event);\n        return;\n      case BEFORE_CLOSE:\n        onBeforeClose(event);\n        return;\n      case AFTER_CLOSE:\n        onAfterClose(event);\n        return;\n      default:\n        throw new IllegalStateException(\"unknown boot event type: \" + event.eventType);\n    }\n  }\n\n  default void onBeforeFilter(BootEvent event) {\n\n  }\n\n  default void onAfterFilter(BootEvent event) {\n\n  }\n\n  default void onBeforeProducerProvider(BootEvent event) {\n\n  }\n\n  default void onAfterProducerProvider(BootEvent event) {\n\n  }\n\n  default void onBeforeConsumerProvider(BootEvent event) {\n\n  }\n\n  default void onAfterConsumerProvider(BootEvent event) {\n\n  }\n\n  default void onBeforeTransport(BootEvent event) {\n\n  }\n\n  default void onAfterTransport(BootEvent event) {\n\n  }\n\n  default void onBeforeRegistry(BootEvent event) {\n\n  }\n\n  default void onAfterRegistry(BootEvent event) {\n\n  }\n\n  default void onBeforeClose(BootEvent event) {\n\n  }\n\n  default void onAfterClose(BootEvent event) {\n\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/CoreConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\n\npublic final class CoreConst {\n  private CoreConst() {\n  }\n\n  public static final String CSE_CONTEXT = \"x-cse-context\";\n\n  public static final String TRANSPORT_NAME = \"x-transport-name\";\n\n  public static final String RESTFUL = \"rest\";\n\n  public static final String HIGHWAY = \"highway\";\n\n  public static final String WEBSOCKET = \"websocket\";\n\n  public static final String ANY_TRANSPORT = \"\";\n\n  public static final String VERSION_RULE_LATEST = DefinitionConst.VERSION_RULE_LATEST;\n\n  public static final String DEFAULT_VERSION_RULE = DefinitionConst.VERSION_RULE_ALL;\n\n  public static final String PRODUCER_OPERATION = \"producer-operation\";\n\n  public static final String CONSUMER_OPERATION = \"consumer-operation\";\n\n  public static final String SRC_MICROSERVICE = \"x-cse-src-microservice\";\n\n  public static final String SRC_SERVICE_ID = \"x-src-serviceId\";\n\n  public static final String SRC_INSTANCE_ID = \"x-src-instanceId\";\n\n  public static final String TARGET_MICROSERVICE = \"x-cse-target-microservice\";\n\n  public static final String REMOTE_ADDRESS = \"x-cse-remote-address\";\n\n  public static final String AUTH_TOKEN = \"x-cse-auth-rsatoken\";\n\n  public static final String TRACE_ID_NAME = \"X-B3-TraceId\";\n\n  // controlling whether to print stack information with sensitive errors\n  public static final String PRINT_SENSITIVE_ERROR_MESSAGE = \"servicecomb.error.printSensitiveErrorMessage\";\n\n  public static final String SWAGGER_EXPORT_ENABLED = \"servicecomb.swagger.export.enabled\";\n\n  public static final String SWAGGER_DIRECTORY = \"servicecomb.swagger.export.directory\";\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/Endpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\n\n/**\n * Internal representation for microservice instance address.\n */\npublic class Endpoint {\n  // Registry address: http://192.168.1.1:8080\n  // see: http://www.ietf.org/rfc/rfc2396.txt\n  private final String endpoint;\n\n  private final Transport transport;\n\n  private final DiscoveryInstance instance;\n\n  // Internal address format recognized by Transport\n  private final Object address;\n\n  public Endpoint(Transport transport, String endpoint) {\n    this(transport, endpoint, null);\n  }\n\n  public Endpoint(Transport transport, String endpoint, DiscoveryInstance instance) {\n    this.transport = transport;\n    this.endpoint = endpoint;\n    this.instance = instance;\n    this.address = transport.parseAddress(this.endpoint);\n  }\n\n  public Endpoint(Transport transport, String endpoint, StatefulDiscoveryInstance instance, Object address) {\n    this.transport = transport;\n    this.endpoint = endpoint;\n    this.instance = instance;\n    this.address = address;\n  }\n\n  public String getEndpoint() {\n    return endpoint;\n  }\n\n  public DiscoveryInstance getMicroserviceInstance() {\n    return instance;\n  }\n\n  public Transport getTransport() {\n    return transport;\n  }\n\n  public Object getAddress() {\n    return address;\n  }\n\n  @Override\n  public String toString() {\n    return endpoint;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o instanceof Endpoint) {\n      return this.endpoint.equals(((Endpoint) o).getEndpoint());\n    }\n    return false;\n  }\n\n  @Override\n  public int hashCode() {\n    return this.endpoint.hashCode();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/Invocation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport java.lang.reflect.Method;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.event.InvocationBusinessFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationBusinessMethodStartEvent;\nimport org.apache.servicecomb.core.event.InvocationEncodeResponseStartEvent;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.core.event.InvocationStartSendRequestEvent;\nimport org.apache.servicecomb.core.event.InvocationTimeoutCheckEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.core.tracing.TraceIdGenerator;\nimport org.apache.servicecomb.core.tracing.TraceIdLogger;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic class Invocation extends SwaggerInvocation {\n  private static final Collection<TraceIdGenerator> TRACE_ID_GENERATORS = loadTraceIdGenerators();\n\n  protected static final AtomicLong INVOCATION_ID = new AtomicLong();\n\n  static Collection<TraceIdGenerator> loadTraceIdGenerators() {\n    return SPIServiceUtils.getPriorityHighestServices(TraceIdGenerator::getName, TraceIdGenerator.class);\n  }\n\n  protected ReferenceConfig referenceConfig;\n\n  private InvocationRuntimeType invocationRuntimeType;\n\n  // 本次调用对应的schemaMeta\n  private SchemaMeta schemaMeta;\n\n  // 本次调用对应的operationMeta\n  private OperationMeta operationMeta;\n\n  // loadbalance查询得到的地址，由transport client使用\n  // 之所以不放在handlerContext中，是因为这属于核心数据，没必要走那样的机制\n  private Endpoint endpoint;\n\n  // 只用于handler之间传递数据，是本地数据\n  private final Map<String, Object> handlerContext = localContext;\n\n  // 应答的处理器\n  // 同步模式：避免应答在网络线程中处理解码等等业务级逻辑\n  private Executor responseExecutor;\n\n  private volatile boolean sync = true;\n\n  private final InvocationStageTrace invocationStageTrace = new InvocationStageTrace(this);\n\n  private HttpServletRequestEx requestEx;\n\n  private volatile boolean finished;\n\n  private volatile long invocationId;\n\n  private TraceIdLogger traceIdLogger;\n\n  private Map<String, Object> invocationArguments = Collections.emptyMap();\n\n  private Object[] producerArguments;\n\n  private Map<String, Object> swaggerArguments = Collections.emptyMap();\n\n  public Invocation() {\n    // An empty invocation, used to mock or some other scenario do not need operation information.\n    traceIdLogger = new TraceIdLogger(this);\n  }\n\n  public Invocation(ReferenceConfig referenceConfig, OperationMeta operationMeta,\n      InvocationRuntimeType invocationRuntimeType,\n      Map<String, Object> swaggerArguments) {\n    this.invocationType = InvocationType.CONSUMER;\n    this.referenceConfig = referenceConfig;\n    this.invocationRuntimeType = invocationRuntimeType;\n    init(operationMeta, swaggerArguments);\n  }\n\n  public Invocation(Endpoint endpoint, OperationMeta operationMeta, Map<String, Object> swaggerArguments) {\n    this.invocationType = InvocationType.PROVIDER;\n    this.invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();\n    this.endpoint = endpoint;\n    init(operationMeta, swaggerArguments);\n  }\n\n  private void init(OperationMeta operationMeta, Map<String, Object> swaggerArguments) {\n    this.invocationId = INVOCATION_ID.getAndIncrement();\n    this.schemaMeta = operationMeta.getSchemaMeta();\n    this.operationMeta = operationMeta;\n    this.setSwaggerArguments(swaggerArguments);\n    traceIdLogger = new TraceIdLogger(this);\n  }\n\n  public String getTransportName() {\n    if (endpoint == null || endpoint.getTransport() == null) {\n      return null;\n    }\n    return endpoint.getTransport().getName();\n  }\n\n  public Transport getTransport() {\n    if (endpoint == null) {\n      throw new IllegalStateException(\n          \"Endpoint is empty. Forget to configure \\\"loadbalance\\\" in consumer handler chain?\");\n    }\n    return endpoint.getTransport();\n  }\n\n  public Executor getResponseExecutor() {\n    return responseExecutor;\n  }\n\n  public void setResponseExecutor(Executor responseExecutor) {\n    this.responseExecutor = responseExecutor;\n  }\n\n  public SchemaMeta getSchemaMeta() {\n    return schemaMeta;\n  }\n\n  public OperationMeta getOperationMeta() {\n    return operationMeta;\n  }\n\n  public Map<String, Object> getInvocationArguments() {\n    return this.invocationArguments;\n  }\n\n  public Map<String, Object> getSwaggerArguments() {\n    return this.swaggerArguments;\n  }\n\n  public Object getInvocationArgument(String name) {\n    return this.invocationArguments.get(name);\n  }\n\n  public Object getSwaggerArgument(String name) {\n    return this.swaggerArguments.get(name);\n  }\n\n  public void setInvocationArguments(Map<String, Object> invocationArguments) {\n    if (invocationArguments == null) {\n      // Empty arguments\n      this.invocationArguments = new HashMap<>(0);\n      return;\n    }\n    this.invocationArguments = invocationArguments;\n\n    buildSwaggerArguments();\n  }\n\n  private void buildSwaggerArguments() {\n    if (!this.invocationRuntimeType.isRawConsumer()) {\n      this.swaggerArguments = this.invocationRuntimeType.getArgumentsMapper()\n          .invocationArgumentToSwaggerArguments(this,\n              this.invocationArguments);\n    } else {\n      this.swaggerArguments = invocationArguments;\n    }\n  }\n\n  public void setSwaggerArguments(Map<String, Object> swaggerArguments) {\n    if (swaggerArguments == null) {\n      // Empty arguments\n      this.swaggerArguments = new HashMap<>(0);\n      return;\n    }\n    this.swaggerArguments = swaggerArguments;\n\n    buildInvocationArguments();\n  }\n\n  private void buildInvocationArguments() {\n    if (operationMeta.getSwaggerProducerOperation() != null && !isEdge()) {\n      this.invocationArguments = operationMeta.getSwaggerProducerOperation().getArgumentsMapper()\n          .swaggerArgumentToInvocationArguments(this,\n              swaggerArguments);\n    } else {\n      this.invocationArguments = swaggerArguments;\n    }\n  }\n\n  public Object[] toProducerArguments() {\n    if (producerArguments != null) {\n      return producerArguments;\n    }\n\n    Method method = operationMeta.getSwaggerProducerOperation().getProducerMethod();\n    Object[] args = new Object[method.getParameterCount()];\n    for (int i = 0; i < method.getParameterCount(); i++) {\n      args[i] = this.invocationArguments.get(method.getParameters()[i].getName());\n    }\n    return producerArguments = args;\n  }\n\n  public Endpoint getEndpoint() {\n    return endpoint;\n  }\n\n  public void setEndpoint(Endpoint endpoint) {\n    this.endpoint = endpoint;\n  }\n\n  public Map<String, Object> getHandlerContext() {\n    return handlerContext;\n  }\n\n  public String getSchemaId() {\n    return schemaMeta.getSchemaId();\n  }\n\n  public String getOperationName() {\n    return operationMeta.getOperationId();\n  }\n\n  public String getProviderTransportName() {\n    if (operationMeta.getSwaggerOperation().getExtensions() != null &&\n        operationMeta.getSwaggerOperation().getExtensions().get(CoreConst.TRANSPORT_NAME) != null) {\n      return (String) operationMeta.getSwaggerOperation().getExtensions().get(CoreConst.TRANSPORT_NAME);\n    }\n    if (schemaMeta.getSwagger().getExtensions() != null &&\n        schemaMeta.getSwagger().getExtensions().get(CoreConst.TRANSPORT_NAME) != null) {\n      return (String) schemaMeta.getSwagger().getExtensions().get(CoreConst.TRANSPORT_NAME);\n    }\n    return null;\n  }\n\n  public String getConfigTransportName() {\n    if (getProviderTransportName() != null) {\n      return getProviderTransportName();\n    }\n    return referenceConfig.getTransport();\n  }\n\n  public String getRealTransportName() {\n    return (endpoint != null) ? endpoint.getTransport().getName() : getConfigTransportName();\n  }\n\n  public String getMicroserviceName() {\n    return schemaMeta.getMicroserviceName();\n  }\n\n  public String getAppId() {\n    return schemaMeta.getMicroserviceMeta().getAppId();\n  }\n\n  public MicroserviceMeta getMicroserviceMeta() {\n    return schemaMeta.getMicroserviceMeta();\n  }\n\n  public InvocationRuntimeType getInvocationRuntimeType() {\n    return this.invocationRuntimeType;\n  }\n\n  public JavaType findResponseType(int statusCode) {\n    return this.invocationRuntimeType.findResponseType(statusCode);\n  }\n\n  public void setSuccessResponseType(JavaType javaType) {\n    this.invocationRuntimeType.setSuccessResponseType(javaType);\n  }\n\n  @Override\n  public String getInvocationQualifiedName() {\n    return invocationType.name() + \" \" + getRealTransportName() + \" \"\n        + getOperationMeta().getMicroserviceQualifiedName();\n  }\n\n  public String getMicroserviceQualifiedName() {\n    return operationMeta.getMicroserviceQualifiedName();\n  }\n\n  protected void initTraceId() {\n    for (TraceIdGenerator traceIdGenerator : TRACE_ID_GENERATORS) {\n      initTraceId(traceIdGenerator);\n    }\n  }\n\n  protected void initTraceId(TraceIdGenerator traceIdGenerator) {\n    if (!StringUtils.isEmpty(getTraceId(traceIdGenerator.getTraceIdKeyName()))) {\n      // if invocation context contains traceId, nothing needed to do\n      return;\n    }\n\n    if (requestEx == null) {\n      // it's a new consumer invocation, must generate a traceId\n      addContext(traceIdGenerator.getTraceIdKeyName(), traceIdGenerator.generate());\n      return;\n    }\n\n    String traceId = requestEx.getHeader(traceIdGenerator.getTraceIdKeyName());\n    if (!StringUtils.isEmpty(traceId)) {\n      // if request header contains traceId, save traceId into invocation context\n      addContext(traceIdGenerator.getTraceIdKeyName(), traceId);\n      return;\n    }\n\n    // if traceId not found, generate a traceId\n    addContext(traceIdGenerator.getTraceIdKeyName(), traceIdGenerator.generate());\n  }\n\n  public void onStart() {\n    initTraceId();\n    EventManager.post(new InvocationStartEvent(this));\n  }\n\n  public void onStart(HttpServletRequestEx requestEx) {\n    this.requestEx = requestEx;\n\n    onStart();\n  }\n\n  public void onStartSendRequest() {\n    EventManager.post(new InvocationStartSendRequestEvent(this));\n  }\n\n  public void onBusinessMethodStart() {\n    invocationStageTrace.startBusinessExecute();\n    EventManager.post(new InvocationBusinessMethodStartEvent(this));\n  }\n\n  public void onEncodeResponseStart(Response response) {\n    invocationStageTrace.startProviderEncodeResponse();\n    EventManager.post(new InvocationEncodeResponseStartEvent(this, response));\n  }\n\n  public void onEncodeResponseFinish() {\n    invocationStageTrace.finishProviderEncodeResponse();\n  }\n\n  public void onBusinessFinish() {\n    invocationStageTrace.finishBusinessExecute();\n    EventManager.post(new InvocationBusinessFinishEvent(this));\n  }\n\n  public void onFinish(Response response) {\n    if (finished) {\n      // avoid to post repeated event\n      return;\n    }\n\n    finished = true;\n    invocationStageTrace.finish();\n    EventManager.post(new InvocationFinishEvent(this, response));\n  }\n\n  // for retry, reset invocation and try it again\n  public void reset() {\n    finished = false;\n  }\n\n  public boolean isFinished() {\n    return finished;\n  }\n\n  public boolean isSync() {\n    return sync;\n  }\n\n  public void setSync(boolean sync) {\n    this.sync = sync;\n  }\n\n  public boolean isConsumer() {\n    return InvocationType.CONSUMER.equals(invocationType);\n  }\n\n  public boolean isProducer() {\n    return InvocationType.PROVIDER.equals(invocationType);\n  }\n\n  public boolean isEdge() {\n    return InvocationType.EDGE.equals(invocationType);\n  }\n\n  public void setEdge() {\n    this.invocationType = InvocationType.EDGE;\n  }\n\n  public long getInvocationId() {\n    return invocationId;\n  }\n\n  public TraceIdLogger getTraceIdLogger() {\n    return this.traceIdLogger;\n  }\n\n  public HttpServletRequestEx getRequestEx() {\n    return requestEx;\n  }\n\n  public InvocationStageTrace getInvocationStageTrace() {\n    return invocationStageTrace;\n  }\n\n  public String getTraceId() {\n    return getContext(CoreConst.TRACE_ID_NAME);\n  }\n\n  public String getTraceId(String traceIdName) {\n    return getContext(traceIdName);\n  }\n\n  // ensure sync consumer invocation response flow not run in eventLoop\n  public <T> CompletableFuture<T> optimizeSyncConsumerThread(CompletableFuture<T> future) {\n    if (sync && !InvokerUtils.isInEventLoop()) {\n      return AsyncUtils.tryCatchSupplier(() -> InvokerUtils.toSync(future, getWaitTime()));\n    }\n\n    return future;\n  }\n\n  public long getWaitTime() {\n    if (getOperationMeta().getConfig().getMsInvocationTimeout() > 0) {\n      // if invocation timeout configured, use it.\n      return getOperationMeta().getConfig().getMsInvocationTimeout();\n    }\n\n    // In invocation handlers, may call other microservices, invocation\n    // timeout may be much longer than request timeout.\n    // But this is quite rare, for simplicity, default two times of request timeout.\n    // If users need longer timeout, can configure invocation timeout.\n    return getOperationMeta().getConfig().getMsRequestTimeout() * 2;\n  }\n\n  /**\n   * Check if invocation is timeout.\n   *\n   * NOTICE: this method only trigger event to ask the target checker to do the real check. So this method\n   * will only take effect when timeout checker is enabled.\n   *\n   * e.g. InvocationTimeoutBootListener.ENABLE_TIMEOUT_CHECK is enabled.\n   *\n   * @throws InvocationException if timeout, throw an exception. Will not throw exception twice if this method called\n   *  after timeout.\n   */\n  public void ensureInvocationNotTimeout() throws InvocationException {\n    EventManager.post(new InvocationTimeoutCheckEvent(this));\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/NonSwaggerInvocation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\npublic class NonSwaggerInvocation extends Invocation {\n  private final String appId;\n\n  private final String microserviceName;\n\n  public NonSwaggerInvocation(String appId, String microserviceName) {\n    this.appId = appId;\n    this.microserviceName = microserviceName;\n  }\n\n  @Override\n  public String getSchemaId() {\n    return \"third-schema\";\n  }\n\n  @Override\n  public String getOperationName() {\n    return \"third-operation\";\n  }\n\n  @Override\n  public String getInvocationQualifiedName() {\n    return microserviceName;\n  }\n\n  @Override\n  public String getConfigTransportName() {\n    return CoreConst.RESTFUL;\n  }\n\n  @Override\n  public String getMicroserviceName() {\n    return microserviceName;\n  }\n\n  @Override\n  public String getAppId() {\n    return appId;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/ProducerProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.provider.producer.ProducerMeta;\n\npublic interface ProducerProvider {\n  List<ProducerMeta> init();\n\n  String getName();\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/SCBApplicationListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.apache.servicecomb.config.priority.PriorityPropertyManager;\nimport org.apache.servicecomb.core.filter.FilterChainsManager;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.springframework.beans.BeansException;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\nimport org.springframework.context.ApplicationEvent;\nimport org.springframework.context.ApplicationListener;\nimport org.springframework.context.EnvironmentAware;\nimport org.springframework.context.event.ContextClosedEvent;\nimport org.springframework.context.event.ContextRefreshedEvent;\nimport org.springframework.context.support.AbstractApplicationContext;\nimport org.springframework.core.Ordered;\nimport org.springframework.core.env.Environment;\n\npublic class SCBApplicationListener\n    implements ApplicationListener<ApplicationEvent>, Ordered, ApplicationContextAware, EnvironmentAware {\n  private Class<?> initEventClass = ContextRefreshedEvent.class;\n\n  private ApplicationContext applicationContext;\n\n  private final SCBEngine scbEngine;\n\n  public SCBApplicationListener(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  @Override\n  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n    if (this.applicationContext == applicationContext) {\n      // same object. avoid initialize many times.\n      return;\n    }\n    this.applicationContext = applicationContext;\n    BeanUtils.setContext(applicationContext);\n    HttpClients.load();\n  }\n\n  @Override\n  public void setEnvironment(Environment environment) {\n    scbEngine.init();\n  }\n\n  public void setInitEventClass(Class<?> initEventClass) {\n    this.initEventClass = initEventClass;\n  }\n\n  @Override\n  public int getOrder() {\n    // should run before default listener, eg: ZuulConfiguration\n    return -1000;\n  }\n\n  @Override\n  public void onApplicationEvent(ApplicationEvent event) {\n    if (initEventClass.isInstance(event)) {\n      if (applicationContext instanceof AbstractApplicationContext) {\n        ((AbstractApplicationContext) applicationContext).registerShutdownHook();\n      }\n\n      scbEngine.setPriorityPropertyManager(applicationContext.getBean(PriorityPropertyManager.class));\n      scbEngine.setFilterChainsManager(applicationContext.getBean(FilterChainsManager.class));\n      scbEngine.getProducerProviderManager().getProducerProviderList()\n          .addAll(applicationContext.getBeansOfType(ProducerProvider.class).values());\n\n      scbEngine.run();\n    } else if (event instanceof ContextClosedEvent) {\n      if (SCBEngine.getInstance() != null) {\n        SCBEngine.getInstance().destroy();\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/SCBEngine.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.priority.PriorityPropertyManager;\nimport org.apache.servicecomb.core.BootListener.BootEvent;\nimport org.apache.servicecomb.core.BootListener.EventType;\nimport org.apache.servicecomb.core.bootup.BootUpInformationCollector;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.MicroserviceVersionsMeta;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.filter.FilterChainsManager;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager;\nimport org.apache.servicecomb.core.provider.consumer.ConsumerProviderManager;\nimport org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfigManager;\nimport org.apache.servicecomb.core.provider.producer.ProducerProviderManager;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class SCBEngine {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SCBEngine.class);\n\n  public static final String CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC = \"servicecomb.boot.turnDown.waitInSeconds\";\n\n  public static final long DEFAULT_TURN_DOWN_STATUS_WAIT_SEC = 0;\n\n  // TODO: will remove in future. Too many codes need refactor.\n  private static volatile SCBEngine INSTANCE;\n\n  private ApplicationContext applicationContext;\n\n  private FilterChainsManager filterChainsManager;\n\n  private ProducerProviderManager producerProviderManager;\n\n  private ConsumerProviderManager consumerProviderManager;\n\n  private MicroserviceMeta producerMicroserviceMeta;\n\n  private TransportManager transportManager;\n\n  private List<BootListener> bootListeners;\n\n  private final AtomicLong invocationStartedCounter = new AtomicLong();\n\n  private final AtomicLong invocationFinishedCounter = new AtomicLong();\n\n  private volatile SCBStatus status = SCBStatus.DOWN;\n\n  private final EventBus eventBus;\n\n  private ExecutorManager executorManager;\n\n  private PriorityPropertyManager priorityPropertyManager;\n\n  private List<BootUpInformationCollector> bootUpInformationCollectors;\n\n  private final SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();\n\n  private OpenAPIRegistryManager openAPIRegistryManager;\n\n  private RegistrationManager registrationManager;\n\n  private DiscoveryManager discoveryManager;\n\n  private Environment environment;\n\n  private ReferenceConfigManager referenceConfigManager;\n\n  public SCBEngine() {\n    eventBus = EventManager.getEventBus();\n\n    eventBus.register(this);\n\n    INSTANCE = this;\n\n    producerProviderManager = new ProducerProviderManager(this);\n  }\n\n  public static SCBEngine getInstance() {\n    if (INSTANCE == null) {\n      throw new InvocationException(Status.SERVICE_UNAVAILABLE,\n          new CommonExceptionData(\"SCBEngine is not initialized yet.\"));\n    }\n    return INSTANCE;\n  }\n\n  @Autowired\n  public void setReferenceConfigManager(ReferenceConfigManager referenceConfigManager) {\n    this.referenceConfigManager = referenceConfigManager;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  public Environment getEnvironment() {\n    return this.environment;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setBootUpInformationCollectors(List<BootUpInformationCollector> bootUpInformationCollectors) {\n    this.bootUpInformationCollectors = bootUpInformationCollectors;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setBootListeners(List<BootListener> listeners) {\n    this.bootListeners = listeners;\n  }\n\n  @Autowired\n  public void setApplicationContext(ApplicationContext applicationContext) {\n    this.applicationContext = applicationContext;\n  }\n\n  @Autowired\n  public void setRegistrationManager(RegistrationManager registrationManager) {\n    this.registrationManager = registrationManager;\n  }\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Autowired\n  public void setOpenAPIRegistryManager(OpenAPIRegistryManager openAPIRegistryManager) {\n    this.openAPIRegistryManager = openAPIRegistryManager;\n  }\n\n  @Autowired\n  public void setConsumerProviderManager(ConsumerProviderManager consumerProviderManager) {\n    this.consumerProviderManager = consumerProviderManager;\n  }\n\n  @Autowired\n  public void setExecutorManager(ExecutorManager executorManager) {\n    this.executorManager = executorManager;\n  }\n\n  @Autowired\n  public void setTransportManager(TransportManager transportManager) {\n    this.transportManager = transportManager;\n  }\n\n  public RegistrationManager getRegistrationManager() {\n    return this.registrationManager;\n  }\n\n  public ApplicationContext getApplicationContext() {\n    return applicationContext;\n  }\n\n  public String getAppId() {\n    return BootStrapProperties.readApplication(environment);\n  }\n\n  public void setStatus(SCBStatus status) {\n    this.status = status;\n  }\n\n  public SCBStatus getStatus() {\n    return status;\n  }\n\n  public OpenAPIRegistryManager getOpenAPIRegistryManager() {\n    return this.openAPIRegistryManager;\n  }\n\n  public FilterChainsManager getFilterChainsManager() {\n    return filterChainsManager;\n  }\n\n  public SCBEngine setFilterChainsManager(FilterChainsManager filterChainsManager) {\n    this.filterChainsManager = filterChainsManager;\n    return this;\n  }\n\n  public PriorityPropertyManager getPriorityPropertyManager() {\n    return priorityPropertyManager;\n  }\n\n  public SCBEngine setPriorityPropertyManager(PriorityPropertyManager priorityPropertyManager) {\n    this.priorityPropertyManager = priorityPropertyManager;\n    return this;\n  }\n\n  public EventBus getEventBus() {\n    return eventBus;\n  }\n\n  public ExecutorManager getExecutorManager() {\n    return executorManager;\n  }\n\n  public ProducerProviderManager getProducerProviderManager() {\n    return producerProviderManager;\n  }\n\n  public void setProducerProviderManager(ProducerProviderManager producerProviderManager) {\n    this.producerProviderManager = producerProviderManager;\n  }\n\n  public ConsumerProviderManager getConsumerProviderManager() {\n    return consumerProviderManager;\n  }\n\n  public TransportManager getTransportManager() {\n    return transportManager;\n  }\n\n  public SwaggerEnvironment getSwaggerEnvironment() {\n    return swaggerEnvironment;\n  }\n\n  public SCBEngine addProducerMeta(String schemaId, Object instance) {\n    getProducerProviderManager().addProducerMeta(schemaId, instance);\n    return this;\n  }\n\n  protected void triggerEvent(EventType eventType) {\n    BootEvent event = new BootEvent();\n    event.setScbEngine(this);\n    event.setEventType(eventType);\n\n    for (BootListener listener : bootListeners) {\n      listener.onBootEvent(event);\n    }\n  }\n\n  protected void safeTriggerEvent(EventType eventType) {\n    BootEvent event = new BootEvent();\n    event.setScbEngine(this);\n    event.setEventType(eventType);\n\n    for (BootListener listener : bootListeners) {\n      try {\n        listener.onBootEvent(event);\n        LOGGER.info(\"BootListener {} succeed to process {}.\", listener.getClass().getName(), eventType);\n      } catch (Throwable e) {\n        LOGGER.error(\"BootListener {} failed to process {}.\", listener.getClass().getName(), eventType, e);\n      }\n    }\n  }\n\n  @AllowConcurrentEvents\n  @Subscribe\n  @SuppressWarnings(\"unused\")\n  public void onInvocationStart(InvocationStartEvent event) {\n    invocationStartedCounter.incrementAndGet();\n  }\n\n  @AllowConcurrentEvents\n  @Subscribe\n  @SuppressWarnings(\"unused\")\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    invocationFinishedCounter.incrementAndGet();\n  }\n\n  public synchronized SCBEngine init() {\n    this.discoveryManager.init();\n    this.registrationManager.init();\n    return this;\n  }\n\n  public synchronized SCBEngine run() {\n    if (SCBStatus.DOWN.equals(status)) {\n      try {\n        doRun();\n        printServiceInfo();\n      } catch (Throwable e) {\n        LOGGER.error(\"Failed to start ServiceComb due to errors and close\", e);\n        try {\n          destroy();\n        } catch (Exception exception) {\n          LOGGER.info(\"destroy has some error.\", exception);\n        }\n        status = SCBStatus.FAILED;\n        throw new IllegalStateException(\"ServiceComb init failed.\", e);\n      }\n    }\n\n    return this;\n  }\n\n  private void printServiceInfo() {\n    StringBuilder serviceInfo = new StringBuilder();\n    serviceInfo.append(\"Service information is shown below:\\n\");\n    for (BootUpInformationCollector bootUpInformationCollector : bootUpInformationCollectors) {\n      String info = bootUpInformationCollector.collect(this);\n      if (StringUtils.isEmpty(info)) {\n        continue;\n      }\n\n      serviceInfo.append(info);\n      if (!info.endsWith(\"\\n\")) {\n        serviceInfo.append('\\n');\n      }\n    }\n    LOGGER.info(serviceInfo.toString());\n  }\n\n  private void doRun() throws Exception {\n    status = SCBStatus.STARTING;\n\n    triggerEvent(EventType.BEFORE_FILTER);\n    filterChainsManager.init();\n    triggerEvent(EventType.AFTER_FILTER);\n\n    createProducerMicroserviceMeta();\n\n    triggerEvent(EventType.BEFORE_PRODUCER_PROVIDER);\n    producerProviderManager.init();\n    triggerEvent(EventType.AFTER_PRODUCER_PROVIDER);\n\n    triggerEvent(EventType.BEFORE_CONSUMER_PROVIDER);\n    consumerProviderManager.init();\n    triggerEvent(EventType.AFTER_CONSUMER_PROVIDER);\n\n    triggerEvent(EventType.BEFORE_TRANSPORT);\n    transportManager.init(this);\n    triggerEvent(EventType.AFTER_TRANSPORT);\n\n    triggerEvent(EventType.BEFORE_REGISTRY);\n    registrationManager.run();\n    discoveryManager.run();\n    status = SCBStatus.UP;\n    triggerEvent(EventType.AFTER_REGISTRY);\n\n    // Keep this message for tests cases work.\n    LOGGER.warn(\"ServiceComb is ready.\");\n  }\n\n  private void createProducerMicroserviceMeta() {\n    String microserviceName = BootStrapProperties.readServiceName(environment);\n    producerMicroserviceMeta = new MicroserviceMeta(this,\n        BootStrapProperties.readApplication(environment), microserviceName, false);\n    producerMicroserviceMeta.setProviderFilterChain(filterChainsManager.findProducerChain(\n        BootStrapProperties.readApplication(environment), microserviceName));\n    producerMicroserviceMeta.setMicroserviceVersionsMeta(new MicroserviceVersionsMeta(this));\n  }\n\n  /**\n   * not allow throw any exception\n   * even some step throw exception, must catch it and go on, otherwise shutdown process will be broken.\n   */\n  public synchronized void destroy() {\n    if (SCBStatus.UP.equals(status) || SCBStatus.STARTING.equals(status)) {\n      LOGGER.info(\"ServiceComb is closing now...\");\n      doDestroy();\n      status = SCBStatus.DOWN;\n      LOGGER.info(\"ServiceComb had closed\");\n    }\n  }\n\n  private void doDestroy() {\n    //Step 0: turn down the status of this instance in service center,\n    // so that the consumers can remove this instance record in advance\n    turnDownInstanceStatus();\n    blockShutDownOperationForConsumerRefresh();\n\n    //Step 1: notify all component stop invoke via BEFORE_CLOSE Event\n    safeTriggerEvent(EventType.BEFORE_CLOSE);\n\n    //Step 2: forbid create new consumer invocation\n    status = SCBStatus.STOPPING;\n\n    //Step 3: Unregister microservice instance from Service Center and close vertx\n    // Forbidden other consumers find me\n    registrationManager.destroy();\n    discoveryManager.destroy();\n\n    //Step 4: wait all invocation finished\n    try {\n      validAllInvocationFinished();\n    } catch (InterruptedException e) {\n      LOGGER.error(\"wait all invocation finished interrupted\", e);\n    }\n\n    //Step 5: destroy config source\n    // only be null for some test cases\n    if (priorityPropertyManager != null) {\n      priorityPropertyManager.close();\n    }\n\n    //Step 6: Stop vertx to prevent blocking exit\n    // delete the following one line when every refactor is done.\n    VertxUtils.blockCloseVertxByName(\"transport\");\n\n    HttpClients.destroy();\n\n    //Step 7: notify all component do clean works via AFTER_CLOSE Event\n    safeTriggerEvent(EventType.AFTER_CLOSE);\n  }\n\n  private void turnDownInstanceStatus() {\n    try {\n      registrationManager.updateMicroserviceInstanceStatus(MicroserviceInstanceStatus.DOWN);\n    } catch (Throwable e) {\n      LOGGER.warn(\"turn down instance status fail: {}\", e.getMessage());\n    }\n  }\n\n  private void blockShutDownOperationForConsumerRefresh() {\n    try {\n      long turnDownWaitSeconds = environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n          long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n      if (turnDownWaitSeconds <= 0) {\n        return;\n      }\n      Thread.sleep(TimeUnit.SECONDS.toMillis(turnDownWaitSeconds));\n    } catch (InterruptedException e) {\n      LOGGER.warn(\"failed to block the shutdown procedure\", e);\n    }\n  }\n\n  private void validAllInvocationFinished() throws InterruptedException {\n    long start = System.currentTimeMillis();\n    while (true) {\n      long remaining = invocationStartedCounter.get() - invocationFinishedCounter.get();\n      if (remaining <= 0) {\n        return;\n      }\n\n      if (System.currentTimeMillis() - start > TimeUnit.SECONDS.toMillis(30)) {\n        LOGGER.error(\"wait for all requests timeout, abandon waiting, remaining requests: {}.\", remaining);\n        return;\n      }\n      TimeUnit.SECONDS.sleep(1);\n    }\n  }\n\n  public void ensureStatusUp() {\n    SCBStatus currentStatus = getStatus();\n    if (!SCBStatus.UP.equals(currentStatus)) {\n      String message =\n          \"The request is rejected. Cannot process the request due to STATUS = \" + currentStatus;\n      throw new InvocationException(Status.SERVICE_UNAVAILABLE, new CommonExceptionData(message));\n    }\n  }\n\n  public CompletableFuture<MicroserviceReferenceConfig> getOrCreateReferenceConfigAsync(\n      String microserviceName) {\n    return referenceConfigManager.getOrCreateReferenceConfigAsync(this, microserviceName);\n  }\n\n  public MicroserviceReferenceConfig getOrCreateReferenceConfig(\n      String microserviceName) {\n    ensureStatusUp();\n    return referenceConfigManager.getOrCreateReferenceConfig(this, microserviceName);\n  }\n\n  public MicroserviceMeta getProducerMicroserviceMeta() {\n    return producerMicroserviceMeta;\n  }\n\n  public void setProducerMicroserviceMeta(MicroserviceMeta producerMicroserviceMeta) {\n    this.producerMicroserviceMeta = producerMicroserviceMeta;\n  }\n\n\n  public static class CreateMicroserviceMetaEvent {\n    private final MicroserviceMeta microserviceMeta;\n\n    public CreateMicroserviceMetaEvent(MicroserviceMeta microserviceMeta) {\n      this.microserviceMeta = microserviceMeta;\n    }\n\n    public MicroserviceMeta getMicroserviceMeta() {\n      return this.microserviceMeta;\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/SCBStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\n//DOWN -> STARTING -> UP -> STOPPING -> DOWN\npublic enum SCBStatus {\n  //Chassis is Down\n  DOWN,\n  //Chassis is Starting (progressing)\n  STARTING,\n  //Chassis is Running\n  UP,\n  //Chassis is Stopping (progressing)\n  STOPPING,\n  //Chassis Init Failed\n  FAILED\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/ServiceCombCoreConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport org.apache.servicecomb.core.bootup.ConfigurationProblemsCollector;\nimport org.apache.servicecomb.core.bootup.FilterChainCollector;\nimport org.apache.servicecomb.core.bootup.ServiceInformationCollector;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.executor.GroupExecutor;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager;\nimport org.apache.servicecomb.core.provider.RegistryOpenAPIRegistry;\nimport org.apache.servicecomb.core.provider.consumer.ConsumerProviderManager;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfigManager;\nimport org.apache.servicecomb.core.provider.producer.ProducerBootListener;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.springframework.boot.context.event.ApplicationReadyEvent;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\n@SuppressWarnings(\"unused\")\npublic class ServiceCombCoreConfiguration {\n  @Bean\n  public SCBApplicationListener scbApplicationListener(SCBEngine scbEngine) {\n    SCBApplicationListener scbApplicationListener = new SCBApplicationListener(scbEngine);\n    scbApplicationListener.setInitEventClass(ApplicationReadyEvent.class);\n    return scbApplicationListener;\n  }\n\n  @Bean\n  public SCBEngine scbEngine() {\n    return new SCBEngine();\n  }\n\n  @Bean\n  public ConsumerProviderManager scbConsumerProviderManager(Environment environment,\n      OpenAPIRegistryManager openAPIRegistryManager) {\n    return new ConsumerProviderManager(environment, openAPIRegistryManager);\n  }\n\n  @Bean\n  public ReferenceConfigManager scbReferenceConfigManager() {\n    return new ReferenceConfigManager();\n  }\n\n  @Bean\n  public OpenAPIRegistryManager scbOpenAPIRegistryManager() {\n    return new OpenAPIRegistryManager();\n  }\n\n  @Bean\n  public LocalOpenAPIRegistry scbLocalOpenAPIRegistry(Environment environment) {\n    return new LocalOpenAPIRegistry(environment);\n  }\n\n  @Bean\n  public RegistryOpenAPIRegistry scbRegistryOpenAPIRegistry() {\n    return new RegistryOpenAPIRegistry();\n  }\n\n  @Bean\n  public ProducerBootListener scbProducerBootListener() {\n    return new ProducerBootListener();\n  }\n\n  @Bean\n  public FilterChainCollector scbFilterChainCollector() {\n    return new FilterChainCollector();\n  }\n\n  @Bean\n  public ConfigurationProblemsCollector scbConfigurationProblemsCollector() {\n    return new ConfigurationProblemsCollector();\n  }\n\n  @Bean\n  public ServiceInformationCollector scbServiceInformationCollector() {\n    return new ServiceInformationCollector();\n  }\n\n  @Bean\n  public ExecutorManager scbExecutorManager() {\n    return new ExecutorManager();\n  }\n\n  @Bean(value = {\"cse.executor.groupThreadPool\", \"cse.executor.default\", \"servicecomb.executor.groupThreadPool\"})\n  public GroupExecutor scbGroupExecutor(Environment environment) {\n    GroupExecutor groupExecutor = new GroupExecutor(environment);\n    groupExecutor.init();\n    return groupExecutor;\n  }\n\n  @Bean\n  public TransportManager scbTransportManager() {\n    return new TransportManager();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/Transport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.springframework.core.env.Environment;\n\npublic interface Transport {\n  String getName();\n\n  default int getOrder() {\n    return 0;\n  }\n\n  default boolean canInit() {\n    return true;\n  }\n\n  boolean init() throws Exception;\n\n  void setEnvironment(Environment environment);\n\n  /*\n   * endpoint的格式为 URI，比如rest://192.168.1.1:8080\n   */\n  Object parseAddress(String endpoint);\n\n  /*\n   * 本transport的监听地址\n   */\n  Endpoint getEndpoint();\n\n  /*\n   * 用于上报到服务中心，要求是其他节点可访问的地址\n   */\n  Endpoint getPublishEndpoint() throws Exception;\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/annotation/Transport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.annotation;\n\nimport static java.lang.annotation.ElementType.ANNOTATION_TYPE;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.ElementType.TYPE;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport org.springframework.stereotype.Component;\n\n@Inherited\n@Documented\n@Retention(RUNTIME)\n@Target({TYPE, METHOD, ANNOTATION_TYPE})\n@Component\npublic @interface Transport {\n  /**\n   * Transport name. e.g. rest, highway.\n   */\n  String name();\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootstrap/SCBBootstrap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.bootstrap;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager;\nimport org.apache.servicecomb.core.provider.consumer.ConsumerProviderManager;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.apache.servicecomb.registry.discovery.TelnetInstancePing;\nimport org.springframework.core.env.Environment;\n\npublic class SCBBootstrap {\n  public static SCBEngine createSCBEngineForTest(Environment environment) {\n    LegacyPropertyFactory.setEnvironment(environment);\n    RegistrationManager registrationManager = new RegistrationManager(Collections.emptyList());\n    DiscoveryManager discoveryManager = new DiscoveryManager(Collections.emptyList(),\n        List.of(new TelnetInstancePing()));\n    registrationManager.init();\n    discoveryManager.init();\n    SCBEngine result = new SCBEngineForTest(environment);\n    result.setDiscoveryManager(discoveryManager);\n    result.setRegistrationManager(registrationManager);\n    result.setBootListeners(Collections.emptyList());\n    result.setBootUpInformationCollectors(Collections.emptyList());\n    result.setExecutorManager(new ExecutorManager());\n    result.setTransportManager(new TransportManager());\n    result.setEnvironment(environment);\n    OpenAPIRegistryManager openAPIRegistryManager = new OpenAPIRegistryManager();\n    openAPIRegistryManager.setOpenAPIRegistries(List.of(new LocalOpenAPIRegistry(environment)));\n    result.setConsumerProviderManager(new ConsumerProviderManager(environment, openAPIRegistryManager));\n    result.setOpenAPIRegistryManager(openAPIRegistryManager);\n    return result;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootstrap/SCBEngineForTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.bootstrap;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.config.priority.ConfigObjectFactory;\nimport org.apache.servicecomb.config.priority.PriorityPropertyFactory;\nimport org.apache.servicecomb.config.priority.PriorityPropertyManager;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.filter.FilterChainsManager;\nimport org.apache.servicecomb.core.filter.impl.EmptyFilter;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.event.SimpleEventBus;\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.springframework.core.env.Environment;\n\n/**\n * not depend on remote service registry and spring context\n */\npublic class SCBEngineForTest extends SCBEngine {\n  public SCBEngineForTest(Environment environment) {\n    EmptyFilter emptyFilter = new EmptyFilter();\n    emptyFilter.setEnvironment(environment);\n    setFilterChainsManager(new FilterChainsManager()\n        .setProviderFilters(List.of(emptyFilter))\n        .setConsumerFilters(List.of(emptyFilter))\n        .setEdgeFilters(List.of(emptyFilter)));\n\n    PriorityPropertyFactory propertyFactory = new PriorityPropertyFactory(environment);\n    ConfigObjectFactory configObjectFactory = new ConfigObjectFactory(propertyFactory);\n    setPriorityPropertyManager(new PriorityPropertyManager(configObjectFactory));\n    setEnvironment(environment);\n  }\n\n  @Override\n  public synchronized void destroy() {\n    super.destroy();\n\n    ReflectUtils.setField(SCBEngine.class, null, \"INSTANCE\", null);\n\n    EventManager.eventBus = new SimpleEventBus();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootup/BootUpInformationCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.bootup;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.springframework.core.Ordered;\n\npublic interface BootUpInformationCollector extends Ordered {\n  default String collect(SCBEngine engine) {\n    return collect();\n  }\n\n  String collect();\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootup/ConfigurationProblemsAlarmEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.bootup;\n\nimport org.apache.servicecomb.foundation.common.event.AlarmEvent;\n\npublic class ConfigurationProblemsAlarmEvent extends AlarmEvent {\n  private final String problems;\n\n  public ConfigurationProblemsAlarmEvent(Type type, String problems) {\n    super(type);\n    this.problems = problems;\n  }\n\n  public String getProblems() {\n    return problems;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootup/ConfigurationProblemsCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.bootup;\n\nimport java.util.Arrays;\nimport java.util.Set;\nimport java.util.regex.Pattern;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.foundation.common.event.AlarmEvent.Type;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.springframework.core.env.Environment;\n\n/**\n * Detect deprecated and wrong usages of configurations\n * and print warning messages\n * and sending ConfigurationProblemsAlarmEvent.\n */\npublic class ConfigurationProblemsCollector implements BootUpInformationCollector {\n  private static final String SERVICE_NAME_PATTERN_STRING = \"([A-Za-z])|([A-Za-z][A-Za-z0-9_\\\\-.]*[A-Za-z0-9])\";\n\n  private static final Pattern SERVICE_NAME_PATTERN = Pattern.compile(SERVICE_NAME_PATTERN_STRING);\n\n  @Override\n  public String collect(SCBEngine engine) {\n    StringBuilder result = new StringBuilder();\n    collectCsePrefix(engine.getEnvironment(), result);\n    collectServiceDefinition(engine.getEnvironment(), result);\n    collectServiceDefinitionValidation(engine.getEnvironment(), result);\n    collectTimeoutConfiguration(engine.getEnvironment(), result);\n    collectIsolationConfiguration(engine.getEnvironment(), result);\n    if (result.isEmpty()) {\n      return null;\n    }\n    String warnings = \"[WARN]Configurations warnings:\\n\" + result;\n    EventManager.post(new ConfigurationProblemsAlarmEvent(Type.OPEN, warnings));\n    return warnings;\n  }\n\n  private void collectServiceDefinitionValidation(Environment environment, StringBuilder result) {\n    String application = BootStrapProperties.readApplication(environment);\n    if (!SERVICE_NAME_PATTERN.matcher(application).matches()) {\n      result.append(\"application does not match pattern \").append(SERVICE_NAME_PATTERN_STRING).append(\".\");\n    }\n    String serviceName = BootStrapProperties.readServiceName(environment);\n    if (!SERVICE_NAME_PATTERN.matcher(serviceName).matches()) {\n      result.append(\"service name does not match pattern \").append(SERVICE_NAME_PATTERN_STRING).append(\".\");\n    }\n  }\n\n  private void collectIsolationConfiguration(Environment environment, StringBuilder result) {\n    int percentage = environment.getProperty(\n        \"servicecomb.loadbalance.isolation.errorThresholdPercentage\", int.class, -1);\n    int continuous = environment.getProperty(\n        \"servicecomb.loadbalance.isolation.continuousFailureThreshold\", int.class, -1);\n    if (percentage == -1 && continuous == -1) {\n      return;\n    }\n    result.append(\"Configuration `servicecomb.loadbalance.isolation.*` is removed, use governance instead. \"\n        + \"See https://servicecomb.apache.org/references/java-chassis/\"\n        + \"zh_CN/references-handlers/governance-best-practise.html\");\n  }\n\n  private void collectTimeoutConfiguration(Environment environment, StringBuilder result) {\n    int keepAliveTimeoutInSeconds = environment.getProperty(\n        \"servicecomb.rest.client.connection.keepAliveTimeoutInSeconds\", int.class, 60);\n    int idleTimeoutInSeconds = environment.getProperty(\n        \"servicecomb.rest.client.connection.idleTimeoutInSeconds\", int.class, 150);\n    if (keepAliveTimeoutInSeconds >= idleTimeoutInSeconds) {\n      result.append(\"Configuration `servicecomb.rest.client.connection.keepAliveTimeoutInSeconds` is longer than \"\n          + \"servicecomb.rest.client.connection.idleTimeoutInSeconds.\");\n      result.append(\"[\").append(keepAliveTimeoutInSeconds).append(\",\").append(idleTimeoutInSeconds).append(\"]\\n\");\n    }\n    keepAliveTimeoutInSeconds = environment.getProperty(\n        \"servicecomb.rest.client.http2.connection.keepAliveTimeoutInSeconds\", int.class, 60);\n    idleTimeoutInSeconds = environment.getProperty(\n        \"servicecomb.rest.client.http2.connection.idleTimeoutInSeconds\", int.class, 150);\n    if (keepAliveTimeoutInSeconds >= idleTimeoutInSeconds) {\n      result.append(\"Configuration `servicecomb.rest.client.http2.connection.keepAliveTimeoutInSeconds` is longer than \"\n          + \"servicecomb.rest.client.http2.connection.idleTimeoutInSeconds.\");\n      result.append(\"[\").append(keepAliveTimeoutInSeconds).append(\",\").append(idleTimeoutInSeconds).append(\"]\\n\");\n    }\n  }\n\n  private void collectServiceDefinition(Environment environment, StringBuilder result) {\n    if (environment.getProperty(\"APPLICATION_ID\") != null) {\n      result.append(\"Configurations `APPLICATION_ID` is deprecated, \"\n          + \"use `servicecomb.service.application` instead.\\n\");\n    }\n    Set<String> names = ConfigUtil.propertiesWithPrefix(environment, \"service_description.\");\n    if (!names.isEmpty()) {\n      result.append(\"Configurations with prefix `service_description` is deprecated, \"\n          + \"use `servicecomb.service` instead. Find keys \");\n      result.append(Arrays.toString(names.toArray()));\n      result.append(\"\\n\");\n    }\n  }\n\n  private void collectCsePrefix(Environment environment, StringBuilder result) {\n    Set<String> names = ConfigUtil.propertiesWithPrefix(environment, \"cse.\");\n    if (!names.isEmpty()) {\n      result.append(\"Configurations with prefix `cse` is deprecated, use `servicecomb` instead. Find keys \");\n      result.append(Arrays.toString(names.toArray()));\n      result.append(\"\\n\");\n    }\n  }\n\n  @Override\n  public String collect() {\n    return null;\n  }\n\n  @Override\n  public int getOrder() {\n    return 1000;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootup/FilterChainCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.bootup;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.filter.FilterChainsManager;\n\npublic class FilterChainCollector implements BootUpInformationCollector {\n  @Override\n  public String collect(SCBEngine engine) {\n    FilterChainsManager mgr = engine.getFilterChainsManager();\n    return mgr.collectResolvedChains();\n  }\n\n  @Override\n  public String collect() {\n    return null;\n  }\n\n  @Override\n  public int getOrder() {\n    return 300;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/bootup/ServiceInformationCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.bootup;\n\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class ServiceInformationCollector implements BootUpInformationCollector {\n  private RegistrationManager registrationManager;\n\n  private DiscoveryManager discoveryManager;\n\n  public ServiceInformationCollector() {\n  }\n\n  @Autowired\n  public void setRegistrationManager(RegistrationManager registrationManager) {\n    this.registrationManager = registrationManager;\n  }\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Override\n  public String collect() {\n    return registrationManager.info() + \"\\n\" + discoveryManager.info();\n  }\n\n  @Override\n  public int getOrder() {\n    return 200;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/ConsumerMicroserviceVersionsMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport org.apache.servicecomb.core.SCBEngine;\n\npublic class ConsumerMicroserviceVersionsMeta extends MicroserviceVersionsMeta {\n  public ConsumerMicroserviceVersionsMeta(SCBEngine scbEngine) {\n    super(scbEngine);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/CoreMetaUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\npublic final class CoreMetaUtils {\n\n  public static final String SWAGGER_PRODUCER = \"scb_swagger-producer\";\n\n  private CoreMetaUtils() {\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/InvocationRuntimeType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.response.ResponsesMeta;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n/**\n * An InvocationRuntimeType indicates the associated java type information of this invocation.\n *\n * For producer, java type information NOT be changed for each invocation.\n *\n * For Consumer, java type information depend on method signature, or not available when in edge or\n * invoked by raw type way like RestTemplate or InvokerUtils.\n */\npublic class InvocationRuntimeType {\n  private Class<?> associatedClass;\n\n  private Method associatedMethod;\n\n  private final ResponsesMeta responsesMeta;\n\n  private ArgumentsMapper argumentsMapper;\n\n  public InvocationRuntimeType(Class<?> associatedClass, Method associatedMethod, ResponsesMeta responsesMeta,\n      ArgumentsMapper argumentsMapper) {\n    this.associatedClass = associatedClass;\n    this.associatedMethod = associatedMethod;\n    this.argumentsMapper = argumentsMapper;\n    this.responsesMeta = responsesMeta;\n  }\n\n  public InvocationRuntimeType(ResponsesMeta responsesMeta) {\n    this.responsesMeta = responsesMeta;\n  }\n\n  public Class<?> getAssociatedClass() {\n    return this.associatedClass;\n  }\n\n  public Method getAssociatedMethod() {\n    return this.associatedMethod;\n  }\n\n  public ArgumentsMapper getArgumentsMapper() {\n    return this.argumentsMapper;\n  }\n\n  public JavaType findResponseType(int statusCode) {\n    return responsesMeta.findResponseType(statusCode);\n  }\n\n  public void setSuccessResponseType(JavaType javaType) {\n    if (javaType != null) {\n      // when javaType is null , using swagger type, do not override\n      responsesMeta.setResponseType(Status.OK.getStatusCode(), javaType);\n    }\n  }\n\n  public void setSuccessResponseType(Type type) {\n    if (type != null) {\n      // when javaType is null , using swagger type, do not override\n      responsesMeta.setResponseType(Status.OK.getStatusCode(), TypeFactory.defaultInstance().constructType(type));\n    }\n  }\n\n  public void setAssociatedClass(Class<?> associatedClass) {\n    this.associatedClass = associatedClass;\n  }\n\n  public void setAssociatedMethod(Method associatedMethod) {\n    this.associatedMethod = associatedMethod;\n  }\n\n  public void setArgumentsMapper(ArgumentsMapper argumentsMapper) {\n    this.argumentsMapper = argumentsMapper;\n  }\n\n  public boolean isRawConsumer() {\n    return this.associatedClass == null;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/MicroserviceMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.VendorExtensions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class MicroserviceMeta {\n  private final SCBEngine scbEngine;\n\n  private MicroserviceVersionsMeta microserviceVersionsMeta;\n\n  private final String appId;\n\n  private final String microserviceName;\n\n  // key is schemaId, this is all schemas\n  private final Map<String, SchemaMeta> schemaMetas = new HashMap<>();\n\n  // key is OperationMeta.getMicroserviceQualifiedName()\n  private final Map<String, OperationMeta> operationMetas = new HashMap<>();\n\n  // Used to indicate configuration items type. EDGE & CONSUMER chain are all consumer.\n  private final boolean consumer;\n\n  private FilterNode consumerFilterChain = FilterNode.EMPTY;\n\n  private FilterNode providerFilterChain = FilterNode.EMPTY;\n\n  private FilterNode edgeFilterChain = FilterNode.EMPTY;\n\n  private final VendorExtensions vendorExtensions = new VendorExtensions();\n\n  public MicroserviceMeta(SCBEngine scbEngine, String application, String serviceName, boolean consumer) {\n    this.scbEngine = scbEngine;\n    this.appId = application;\n    this.microserviceName = serviceName;\n    this.consumer = consumer;\n  }\n\n  public MicroserviceVersionsMeta getMicroserviceVersionsMeta() {\n    return microserviceVersionsMeta;\n  }\n\n  public void setMicroserviceVersionsMeta(MicroserviceVersionsMeta microserviceVersionsMeta) {\n    this.microserviceVersionsMeta = microserviceVersionsMeta;\n  }\n\n  public SCBEngine getScbEngine() {\n    return scbEngine;\n  }\n\n  public boolean isConsumer() {\n    return consumer;\n  }\n\n  public String getMicroserviceName() {\n    return microserviceName;\n  }\n\n  public String getAppId() {\n    return appId;\n  }\n\n  public SchemaMeta registerSchemaMeta(String schemaId, OpenAPI swagger) {\n    SchemaMeta schemaMeta = new SchemaMeta(this, schemaId, swagger);\n\n    if (schemaMetas.putIfAbsent(schemaMeta.getSchemaId(), schemaMeta) != null) {\n      throw new IllegalStateException(String.format(\n          \"failed to register SchemaMeta caused by duplicated schemaId, appId=%s, microserviceName=%s, schemaId=%s.\",\n          appId, microserviceName, schemaMeta.getSchemaId()));\n    }\n\n    schemaMeta.getOperations().values()\n        .forEach(operationMeta -> operationMetas.put(operationMeta.getMicroserviceQualifiedName(), operationMeta));\n\n    return schemaMeta;\n  }\n\n  public Map<String, OperationMeta> operationMetas() {\n    return operationMetas;\n  }\n\n  public Collection<OperationMeta> getOperations() {\n    return operationMetas.values();\n  }\n\n  public SchemaMeta ensureFindSchemaMeta(String schemaId) {\n    SchemaMeta schemaMeta = schemaMetas.get(schemaId);\n    if (schemaMeta == null) {\n      throw new IllegalStateException(String.format(\n          \"failed to find SchemaMeta by schemaId, appId=%s, microserviceName=%s, schemaId=%s.\",\n          appId, microserviceName, schemaId));\n    }\n\n    return schemaMeta;\n  }\n\n  public SchemaMeta findSchemaMeta(String schemaId) {\n    return schemaMetas.get(schemaId);\n  }\n\n  public Map<String, SchemaMeta> getSchemaMetas() {\n    return schemaMetas;\n  }\n\n  public void putExtData(String key, Object data) {\n    vendorExtensions.put(key, data);\n  }\n\n  public <T> T getExtData(String key) {\n    return vendorExtensions.get(key);\n  }\n\n  public FilterNode getConsumerFilterChain() {\n    return consumerFilterChain;\n  }\n\n  public void setConsumerFilterChain(FilterNode consumerFilterChain) {\n    this.consumerFilterChain = consumerFilterChain;\n  }\n\n  public FilterNode getProviderFilterChain() {\n    return providerFilterChain;\n  }\n\n  public void setProviderFilterChain(FilterNode providerFilterChain) {\n    this.providerFilterChain = providerFilterChain;\n  }\n\n  public FilterNode getEdgeFilterChain() {\n    return edgeFilterChain;\n  }\n\n  public void setEdgeFilterChain(FilterNode edgeFilterChain) {\n    this.edgeFilterChain = edgeFilterChain;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/MicroserviceVersionsMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\npublic class MicroserviceVersionsMeta {\n  protected final SCBEngine scbEngine;\n\n  // key is operationMeta.getMicroserviceQualifiedName()\n  private final Map<String, OperationConfig> configs = new ConcurrentHashMapEx<>();\n\n  public MicroserviceVersionsMeta(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  public OperationConfig getOrCreateOperationConfig(OperationMeta operationMeta) {\n    return configs.computeIfAbsent(operationMeta.getMicroserviceQualifiedName(),\n        name -> createOperationConfig(operationMeta));\n  }\n\n  private OperationConfig createOperationConfig(OperationMeta operationMeta) {\n    boolean consumer = operationMeta.getMicroserviceMeta().isConsumer();\n    return scbEngine.getPriorityPropertyManager().createConfigObject(\n        OperationConfig.class,\n        \"op-any-priority\", consumer ?\n            OperationConfig.CONSUMER_OP_ANY_PRIORITY : OperationConfig.PRODUCER_OP_ANY_PRIORITY,\n        \"consumer-op-any_priority\", OperationConfig.CONSUMER_OP_ANY_PRIORITY,\n        \"producer-op-any_priority\", OperationConfig.PRODUCER_OP_ANY_PRIORITY,\n\n        \"op-priority\", consumer ?\n            OperationConfig.CONSUMER_OP_PRIORITY : OperationConfig.PRODUCER_OP_PRIORITY,\n        \"consumer-op-priority\", OperationConfig.CONSUMER_OP_PRIORITY,\n        \"producer-op-priority\", OperationConfig.PRODUCER_OP_PRIORITY,\n\n        \"consumer-producer\", consumer ? \"Consumer\" : \"Provider\",\n        \"consumer-provider\", consumer ? \"Consumer\" : \"Provider\",\n\n        \"service\", operationMeta.getMicroserviceName(),\n        \"schema\", operationMeta.getSchemaId(),\n        \"operation\", operationMeta.getOperationId());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.config.inject.InjectProperties;\nimport org.apache.servicecomb.config.inject.InjectProperty;\nimport org.apache.servicecomb.core.CoreConst;\n\n@InjectProperties(prefix = \"servicecomb\")\npublic class OperationConfig {\n  public static final List<String> CONSUMER_OP_ANY_PRIORITY = Arrays.asList(\n      \"${service}.${schema}.${operation}\",\n      \"${service}.${schema}\",\n      \"${service}\");\n\n  public static final List<String> PRODUCER_OP_ANY_PRIORITY = Arrays.asList(\n      \"${schema}.${operation}\",\n      \"${schema}\");\n\n  public static final List<String> CONSUMER_OP_PRIORITY = Arrays.asList(\n      \".${service}.${schema}.${operation}\",\n      \".${service}.${schema}\",\n      \".${service}\",\n      \"\");\n\n  public static final List<String> PRODUCER_OP_PRIORITY = Arrays.asList(\n      \".${schema}.${operation}\",\n      \".${schema}\",\n      \"\");\n\n  @InjectProperty(keys = {\"metrics.${consumer-producer}.invocation.slow.enabled${op-priority}\",\n      \"${consumer-producer}.invocation.slow.enabled${op-priority}\"}, defaultValue = \"false\")\n  private boolean slowInvocationEnabled;\n\n  @InjectProperty(keys = {\"metrics.${consumer-producer}.invocation.slow.msTime${op-priority}\",\n      \"${consumer-producer}.invocation.slow.msTime${op-priority}\"}, defaultValue = \"1000\")\n  private long msSlowInvocation;\n\n  private long nanoSlowInvocation;\n\n  /**\n   * consumer request timeout\n   */\n  @InjectProperty(keys = {\"request.${op-any-priority}.timeout\", \"request.timeout\"}, defaultValue = \"30000\")\n  private long msRequestTimeout;\n\n  /**\n   * Invocation timeout.\n   */\n  @InjectProperty(keys = {\"invocation.${op-any-priority}.timeout\", \"invocation.timeout\"}, defaultValue = \"-1\")\n  private long msInvocationTimeout;\n\n  private long nanoInvocationTimeout;\n\n  /**\n   * whether to remove certain headers from the 3rd party invocations\n   */\n  @InjectProperty(keys = {\"request.clientRequestHeaderFilterEnabled${consumer-op-priority}\"}, defaultValue = \"false\")\n  private boolean clientRequestHeaderFilterEnabled = false;\n\n  /**\n   * producer wait in thread pool timeout\n   */\n  private final Map<String, Long> nanoRequestWaitInPoolTimeoutByTransport = new HashMap<>();\n\n  @InjectProperty(keys = \"Provider.requestWaitInPoolTimeout${op-priority}\", defaultValue = \"30000\")\n  private long msDefaultRequestWaitInPoolTimeout;\n\n  private long nanoDefaultRequestWaitInPoolTimeout;\n\n  @InjectProperty(keys = {\n      \"Provider.requestWaitInPoolTimeout${op-priority}\",\n      \"highway.server.requestWaitInPoolTimeout\"}, defaultValue = \"30000\")\n  private long msHighwayRequestWaitInPoolTimeout;\n\n  private long nanoHighwayRequestWaitInPoolTimeout;\n\n  @InjectProperty(keys = {\n      \"Provider.requestWaitInPoolTimeout${op-priority}\",\n      \"rest.server.requestWaitInPoolTimeout\"}, defaultValue = \"30000\")\n  private long msRestRequestWaitInPoolTimeout;\n\n  private long nanoRestRequestWaitInPoolTimeout;\n\n  @InjectProperty(keys = {\n      \"operation${op-priority}.transport\", // Deprecated\n      \"references.transport${op-priority}\"\n  })\n  private String transport;\n\n  @InjectProperty(keys = {\"governance.${op-any-priority}.matchType\", \"governance.matchType\"}, defaultValue = \"rest\")\n  private String governanceMatchType;\n\n  public boolean isSlowInvocationEnabled() {\n    return slowInvocationEnabled;\n  }\n\n  public void setSlowInvocationEnabled(boolean slowInvocationEnabled) {\n    this.slowInvocationEnabled = slowInvocationEnabled;\n  }\n\n  public long getMsSlowInvocation() {\n    return msSlowInvocation;\n  }\n\n  public void setMsSlowInvocation(long msSlowInvocation) {\n    this.msSlowInvocation = msSlowInvocation;\n    this.nanoSlowInvocation = TimeUnit.MILLISECONDS.toNanos(msSlowInvocation);\n  }\n\n  public long getNanoSlowInvocation() {\n    return nanoSlowInvocation;\n  }\n\n  public long getMsRequestTimeout() {\n    return msRequestTimeout;\n  }\n\n  public void setMsRequestTimeout(long msRequestTimeout) {\n    this.msRequestTimeout = msRequestTimeout;\n  }\n\n  public long getNanoRequestWaitInPoolTimeout(String transport) {\n    return nanoRequestWaitInPoolTimeoutByTransport.getOrDefault(transport, nanoDefaultRequestWaitInPoolTimeout);\n  }\n\n  public void registerRequestWaitInPoolTimeout(String transport, long msTimeout) {\n    nanoRequestWaitInPoolTimeoutByTransport.put(transport, TimeUnit.MILLISECONDS.toNanos(msTimeout));\n  }\n\n  public long getMsDefaultRequestWaitInPoolTimeout() {\n    return msDefaultRequestWaitInPoolTimeout;\n  }\n\n  public void setMsDefaultRequestWaitInPoolTimeout(long msDefaultRequestWaitInPoolTimeout) {\n    this.msDefaultRequestWaitInPoolTimeout = msDefaultRequestWaitInPoolTimeout;\n    this.nanoDefaultRequestWaitInPoolTimeout = TimeUnit.MILLISECONDS.toNanos(msDefaultRequestWaitInPoolTimeout);\n  }\n\n  public long getNanoDefaultRequestWaitInPoolTimeout() {\n    return nanoDefaultRequestWaitInPoolTimeout;\n  }\n\n  public long getMsHighwayRequestWaitInPoolTimeout() {\n    return msHighwayRequestWaitInPoolTimeout;\n  }\n\n  public void setMsHighwayRequestWaitInPoolTimeout(long msHighwayRequestWaitInPoolTimeout) {\n    this.msHighwayRequestWaitInPoolTimeout = msHighwayRequestWaitInPoolTimeout;\n    this.nanoHighwayRequestWaitInPoolTimeout = TimeUnit.MILLISECONDS.toNanos(msHighwayRequestWaitInPoolTimeout);\n    registerRequestWaitInPoolTimeout(CoreConst.HIGHWAY, msHighwayRequestWaitInPoolTimeout);\n  }\n\n  public long getNanoHighwayRequestWaitInPoolTimeout() {\n    return nanoHighwayRequestWaitInPoolTimeout;\n  }\n\n  public long getMsRestRequestWaitInPoolTimeout() {\n    return msRestRequestWaitInPoolTimeout;\n  }\n\n  public void setMsRestRequestWaitInPoolTimeout(long msRestRequestWaitInPoolTimeout) {\n    this.msRestRequestWaitInPoolTimeout = msRestRequestWaitInPoolTimeout;\n    this.nanoRestRequestWaitInPoolTimeout = TimeUnit.MILLISECONDS.toNanos(msRestRequestWaitInPoolTimeout);\n    registerRequestWaitInPoolTimeout(CoreConst.RESTFUL, msRestRequestWaitInPoolTimeout);\n  }\n\n  public long getNanoRestRequestWaitInPoolTimeout() {\n    return nanoRestRequestWaitInPoolTimeout;\n  }\n\n  public long getMsInvocationTimeout() {\n    return msInvocationTimeout;\n  }\n\n  public void setMsInvocationTimeout(long msInvocationTimeout) {\n    this.msInvocationTimeout = msInvocationTimeout;\n    this.nanoInvocationTimeout = TimeUnit.MILLISECONDS.toNanos(msInvocationTimeout);\n  }\n\n  public String getGovernanceMatchType() {\n    return governanceMatchType;\n  }\n\n  public void setGovernanceMatchType(String governanceMatchType) {\n    this.governanceMatchType = governanceMatchType;\n  }\n\n  public long getNanoInvocationTimeout() {\n    return this.nanoInvocationTimeout;\n  }\n\n  public boolean isClientRequestHeaderFilterEnabled() {\n    return clientRequestHeaderFilterEnabled;\n  }\n\n  public void setClientRequestHeaderFilterEnabled(boolean clientRequestHeaderFilterEnabled) {\n    this.clientRequestHeaderFilterEnabled = clientRequestHeaderFilterEnabled;\n  }\n\n  public String getTransport() {\n    return transport;\n  }\n\n  public void setTransport(String transport) {\n    if (transport == null) {\n      transport = CoreConst.ANY_TRANSPORT;\n    }\n    this.transport = transport;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/OperationMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport java.util.concurrent.Executor;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.foundation.common.VendorExtensions;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.invocation.response.ResponsesMeta;\n\nimport io.swagger.v3.oas.models.Operation;\n\n\npublic class OperationMeta {\n  private SchemaMeta schemaMeta;\n\n  // schemaId.operation\n  private String schemaQualifiedName;\n\n  // microserviceName.schemaId.operation\n  private String microserviceQualifiedName;\n\n  private String httpMethod;\n\n  private String operationPath;\n\n  private Operation swaggerOperation;\n\n  // run in this executor\n  private Executor executor;\n\n  private final ResponsesMeta responsesMeta = new ResponsesMeta();\n\n  private final VendorExtensions vendorExtensions = new VendorExtensions();\n\n  public OperationMeta init(SchemaMeta schemaMeta, SwaggerOperation swaggerOperation) {\n    this.schemaMeta = schemaMeta;\n    this.schemaQualifiedName = schemaMeta.getSchemaId() + \".\" + swaggerOperation.getOperationId();\n    this.microserviceQualifiedName =\n        schemaMeta.getMicroserviceQualifiedName() + \".\" + swaggerOperation.getOperationId();\n    this.httpMethod = swaggerOperation.getHttpMethod().name();\n    this.operationPath = swaggerOperation.getPath();\n    this.swaggerOperation = swaggerOperation.getOperation();\n    this.executor = schemaMeta.getMicroserviceMeta().getScbEngine().getExecutorManager().findExecutor(this);\n    this.responsesMeta.init(schemaMeta.getSwagger(), swaggerOperation.getOperation());\n\n    return this;\n  }\n\n  public void setSwaggerProducerOperation(SwaggerProducerOperation swaggerProducerOperation) {\n    this.putExtData(CoreConst.PRODUCER_OPERATION, swaggerProducerOperation);\n  }\n\n  public SwaggerProducerOperation getSwaggerProducerOperation() {\n    return (SwaggerProducerOperation) this.getExtData(CoreConst.PRODUCER_OPERATION);\n  }\n\n  public OperationConfig getConfig() {\n    return schemaMeta.getMicroserviceMeta().getMicroserviceVersionsMeta().getOrCreateOperationConfig(this);\n  }\n\n  public String getHttpMethod() {\n    return httpMethod;\n  }\n\n  public String getOperationPath() {\n    return operationPath;\n  }\n\n  public Operation getSwaggerOperation() {\n    return swaggerOperation;\n  }\n\n  public ResponsesMeta getResponsesMeta() {\n    // TODO : this method now called by highway, and highway always use swagger type\n    // in the future improvement , highway can use runtime type and this method can be removed\n    return responsesMeta;\n  }\n\n  public int parameterCount() {\n    int result = 0;\n    if (swaggerOperation.getRequestBody() != null) {\n      result++;\n    }\n    if (swaggerOperation.getParameters() != null) {\n      result += swaggerOperation.getParameters().size();\n    }\n    return result;\n  }\n\n  private ResponsesMeta cloneResponseMeta() {\n    ResponsesMeta result = new ResponsesMeta();\n    this.responsesMeta.cloneTo(result);\n    return result;\n  }\n\n  public MicroserviceMeta getMicroserviceMeta() {\n    return schemaMeta.getMicroserviceMeta();\n  }\n\n  public SchemaMeta getSchemaMeta() {\n    return schemaMeta;\n  }\n\n  public String getSchemaQualifiedName() {\n    return schemaQualifiedName;\n  }\n\n  public String getMicroserviceQualifiedName() {\n    return microserviceQualifiedName;\n  }\n\n  public String getMicroserviceName() {\n    return schemaMeta.getMicroserviceName();\n  }\n\n  public String getSchemaId() {\n    return schemaMeta.getSchemaId();\n  }\n\n  public String getOperationId() {\n    return swaggerOperation.getOperationId();\n  }\n\n  // invoker make sure idx is valid\n  public String getParamName(int idx) {\n    return swaggerOperation.getParameters().get(idx).getName();\n  }\n\n  public void putExtData(String key, Object data) {\n    vendorExtensions.put(key, data);\n  }\n\n  public <T> T getExtData(String key) {\n    return vendorExtensions.get(key);\n  }\n\n  public VendorExtensions getVendorExtensions() {\n    return vendorExtensions;\n  }\n\n  public Executor getExecutor() {\n    return executor;\n  }\n\n  public void setExecutor(Executor executor) {\n    this.executor = executor;\n  }\n\n  public InvocationRuntimeType buildBaseProviderRuntimeType() {\n    SwaggerProducerOperation swaggerProducerOperation = this.getSwaggerProducerOperation();\n    return new InvocationRuntimeType(swaggerProducerOperation.getProducerClass(),\n        swaggerProducerOperation.getProducerMethod(), this.cloneResponseMeta(),\n        swaggerProducerOperation.getArgumentsMapper());\n  }\n\n  public InvocationRuntimeType buildBaseConsumerRuntimeType() {\n    return new InvocationRuntimeType(this.cloneResponseMeta());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/definition/SchemaMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.definition;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.VendorExtensions;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class SchemaMeta {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SchemaMeta.class);\n\n  private final MicroserviceMeta microserviceMeta;\n\n  private final OpenAPI swagger;\n\n  private final String schemaId;\n\n  // microserviceName.schemaId\n  private final String microserviceQualifiedName;\n\n  private final Map<String, OperationMeta> operations = new HashMap<>();\n\n  private final VendorExtensions vendorExtensions = new VendorExtensions();\n\n  public SchemaMeta(MicroserviceMeta microserviceMeta, String schemaId, OpenAPI swagger) {\n    this.microserviceMeta = microserviceMeta;\n    this.schemaId = schemaId;\n    this.swagger = swagger;\n    this.microserviceQualifiedName = microserviceMeta.getMicroserviceName() + \".\" + schemaId;\n\n    try {\n      initOperationMetas();\n    } catch (Throwable e) {\n      LOGGER.error(\"Unhandled exception to {}.\", microserviceQualifiedName, e);\n      throw e;\n    }\n  }\n\n  private SchemaMeta initOperationMetas() {\n    SwaggerOperations swaggerOperations = new SwaggerOperations(swagger);\n    for (SwaggerOperation swaggerOperation : swaggerOperations.getOperations().values()) {\n      operations.put(swaggerOperation.getOperationId(), new OperationMeta().init(this, swaggerOperation));\n    }\n    return this;\n  }\n\n  public MicroserviceMeta getMicroserviceMeta() {\n    return microserviceMeta;\n  }\n\n  public OpenAPI getSwagger() {\n    return swagger;\n  }\n\n  public String getAppId() {\n    return microserviceMeta.getAppId();\n  }\n\n  public String getMicroserviceName() {\n    return microserviceMeta.getMicroserviceName();\n  }\n\n  public String getSchemaId() {\n    return schemaId;\n  }\n\n  public String getMicroserviceQualifiedName() {\n    return microserviceQualifiedName;\n  }\n\n  public Map<String, OperationMeta> getOperations() {\n    return operations;\n  }\n\n  public void putExtData(String key, Object data) {\n    vendorExtensions.put(key, data);\n  }\n\n  public <T> T getExtData(String key) {\n    return vendorExtensions.get(key);\n  }\n\n  public OperationMeta findOperation(String operationId) {\n    return operations.get(operationId);\n  }\n\n  public OperationMeta ensureFindOperation(String operationId) {\n    OperationMeta value = operations.get(operationId);\n    if (value == null) {\n      throw new IllegalStateException(String\n          .format(\"Can not find OperationMeta, microserviceName=%s, schemaId=%s, operationId=%s.\",\n              getMicroserviceName(), getSchemaId(), operationId));\n    }\n\n    return value;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationBaseEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationBaseEvent {\n  private final Invocation invocation;\n\n  public InvocationBaseEvent(Invocation invocation) {\n    this.invocation = invocation;\n  }\n\n  public Invocation getInvocation() {\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessFinishEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationBusinessFinishEvent extends InvocationBaseEvent {\n  public InvocationBusinessFinishEvent(Invocation invocation) {\n    super(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodFinishEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationBusinessMethodFinishEvent extends InvocationBaseEvent {\n  public InvocationBusinessMethodFinishEvent(Invocation invocation) {\n    super(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodStartEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationBusinessMethodStartEvent extends InvocationBaseEvent {\n  public InvocationBusinessMethodStartEvent(Invocation invocation) {\n    super(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationEncodeResponseStartEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class InvocationEncodeResponseStartEvent extends InvocationWithResponseEvent {\n  public InvocationEncodeResponseStartEvent(Invocation invocation, Response response) {\n    super(invocation, response);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationFinishEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class InvocationFinishEvent extends InvocationWithResponseEvent {\n  public InvocationFinishEvent(Invocation invocation, Response response) {\n    super(invocation, response);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationStartEvent extends InvocationBaseEvent {\n  public InvocationStartEvent(Invocation invocation) {\n    super(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationStartSendRequestEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationStartSendRequestEvent extends InvocationBaseEvent {\n  public InvocationStartSendRequestEvent(Invocation invocation) {\n    super(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationTimeoutCheckEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic class InvocationTimeoutCheckEvent extends InvocationBaseEvent {\n  public InvocationTimeoutCheckEvent(Invocation invocation) {\n    super(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/InvocationWithResponseEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class InvocationWithResponseEvent extends InvocationBaseEvent {\n  protected Response response;\n\n  public InvocationWithResponseEvent(Invocation invocation, Response response) {\n    super(invocation);\n    this.response = response;\n  }\n\n  public Response getResponse() {\n    return response;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/event/ServerAccessLogEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class ServerAccessLogEvent {\n  private long milliStartTime;\n\n  private long milliEndTime;\n\n  private RoutingContext routingContext;\n\n  /**\n   * If client send request via a short-lived connection, the connection may be closed before the corresponding\n   * access log is generated, and then we can not get valid host ip\n   * may get \"0.0.0.0\" as result. So we need to get local address before the connection is closed.\n   */\n  private String localAddress;\n\n  public ServerAccessLogEvent() {\n  }\n\n  public long getMilliStartTime() {\n    return milliStartTime;\n  }\n\n  public ServerAccessLogEvent setMilliStartTime(long milliStartTime) {\n    this.milliStartTime = milliStartTime;\n    return this;\n  }\n\n  public long getMilliEndTime() {\n    return milliEndTime;\n  }\n\n  public ServerAccessLogEvent setMilliEndTime(long milliEndTime) {\n    this.milliEndTime = milliEndTime;\n    return this;\n  }\n\n  public RoutingContext getRoutingContext() {\n    return routingContext;\n  }\n\n  public ServerAccessLogEvent setRoutingContext(RoutingContext routingContext) {\n    this.routingContext = routingContext;\n    return this;\n  }\n\n  public String getLocalAddress() {\n    return localAddress;\n  }\n\n  public ServerAccessLogEvent setLocalAddress(String localAddress) {\n    this.localAddress = localAddress;\n    return this;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/CoreExceptionConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class CoreExceptionConfiguration {\n  @Bean\n  public Exceptions scbExceptions() {\n    return new Exceptions();\n  }\n\n  @Bean\n  public DefaultExceptionProcessor scbDefaultExceptionProcessor() {\n    return new DefaultExceptionProcessor();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/CseException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.exception;\n\npublic class CseException extends RuntimeException {\n\n  private static final long serialVersionUID = 8027482777502649656L;\n\n  private final String code;\n\n  public CseException(String code, String message) {\n    super(message);\n    this.code = code;\n  }\n\n  public CseException(String code, String message, Throwable cause) {\n    super(message, cause);\n    this.code = code;\n  }\n\n  public String getCode() {\n    return code;\n  }\n\n  @Override\n  public String toString() {\n    return \"ServiceDefinitionException Code:\" + code + \", Message:\" + getMessage();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/DefaultExceptionProcessor.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.exception;\r\n\r\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\r\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\r\nimport static jakarta.ws.rs.core.Response.Status.TOO_MANY_REQUESTS;\r\nimport static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;\r\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.GENERIC_SERVER;\r\nimport static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER;\r\n\r\nimport java.util.Comparator;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.stream.Collectors;\r\n\r\nimport org.apache.servicecomb.config.inject.InjectProperties;\r\nimport org.apache.servicecomb.config.inject.InjectProperty;\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.core.tracing.TraceIdLogger;\r\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\r\nimport org.apache.servicecomb.foundation.common.utils.ExceptionUtils;\r\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\r\nimport org.apache.servicecomb.swagger.invocation.Response;\r\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\r\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\r\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\n\r\nimport com.fasterxml.jackson.annotation.JsonIgnore;\r\n\r\nimport jakarta.ws.rs.core.Response.StatusType;\r\n\r\n@InjectProperties(prefix = \"servicecomb.invocation.exception\")\r\npublic class DefaultExceptionProcessor implements ExceptionProcessor {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExceptionProcessor.class);\r\n\r\n  public static final int ORDER = Integer.MAX_VALUE;\r\n\r\n  @JsonIgnore\r\n  @SuppressWarnings(\"unchecked\")\r\n  private final List<ExceptionConverter<Throwable>> converters = SPIServiceUtils\r\n      .getOrLoadSortedService(ExceptionConverter.class).stream()\r\n      .map(converter -> (ExceptionConverter<Throwable>) converter)\r\n      .collect(Collectors.toList());\r\n\r\n  @InjectProperty(keys = \"print-stack-trace\", defaultValue = \"true\")\r\n  protected boolean printStackTrace;\r\n\r\n  @InjectProperty(keys = \"print-rate-limit\", defaultValue = \"false\")\r\n  protected boolean printRateLimit;\r\n\r\n  private final Map<Class<?>, ExceptionConverter<Throwable>> converterCache = new ConcurrentHashMapEx<>();\r\n\r\n  @Override\r\n  public int getOrder() {\r\n    return ORDER;\r\n  }\r\n\r\n  @Override\r\n  public boolean isPrintStackTrace() {\r\n    return printStackTrace;\r\n  }\r\n\r\n  public DefaultExceptionProcessor setPrintStackTrace(boolean printStackTrace) {\r\n    this.printStackTrace = printStackTrace;\r\n    return this;\r\n  }\r\n\r\n  public boolean isPrintRateLimit() {\r\n    return printRateLimit;\r\n  }\r\n\r\n  public DefaultExceptionProcessor setPrintRateLimit(boolean printRateLimit) {\r\n    this.printRateLimit = printRateLimit;\r\n    return this;\r\n  }\r\n\r\n  @SuppressWarnings(\"unchecked\")\r\n  @Autowired(required = false)\r\n  public DefaultExceptionProcessor setConverters(List<ExceptionConverter<? extends Throwable>> converters) {\r\n    converters.forEach(converter -> this.converters.add((ExceptionConverter<Throwable>) converter));\r\n    this.converters.sort(Comparator.comparingInt(ExceptionConverter::getOrder));\r\n    this.converterCache.clear();\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public InvocationException convert(Invocation invocation, Throwable throwable) {\r\n    StatusType genericStatus = CONSUMER.equals(invocation.getInvocationType()) ? BAD_REQUEST : INTERNAL_SERVER_ERROR;\r\n    return convert(invocation, throwable, genericStatus);\r\n  }\r\n\r\n  @Override\r\n  public InvocationException convert(Invocation invocation, Throwable throwable, StatusType genericStatus) {\r\n    Throwable unwrapped = ExceptionFactory.unwrap(throwable);\r\n    try {\r\n      ExceptionConverter<Throwable> converter =\r\n          converterCache.computeIfAbsent(unwrapped.getClass(), clazz -> findConverter(unwrapped));\r\n      if (invocation == null) {\r\n        LOGGER.warn(\"Convert unknown operation exception {}/{} using {}.\",\r\n            throwable.getClass().getSimpleName(), unwrapped.getClass().getSimpleName(),\r\n            converter.getClass().getSimpleName());\r\n      } else {\r\n        invocation.getTraceIdLogger().warn(\"{} Convert operation {} exception {}/{} using {}.\",\r\n            TraceIdLogger.constructSource(DefaultExceptionProcessor.class.getSimpleName()),\r\n            invocation.getMicroserviceQualifiedName(),\r\n            throwable.getClass().getSimpleName(), unwrapped.getClass().getSimpleName(),\r\n            converter.getClass().getSimpleName());\r\n      }\r\n      return converter.convert(invocation, unwrapped, genericStatus);\r\n    } catch (Exception e) {\r\n      LOGGER.error(\"BUG: ExceptionConverter.convert MUST not throw exception, please fix it.\\n\"\r\n              + \"original exception :{}\"\r\n              + \"converter exception:{}\",\r\n          getStackTrace(throwable),\r\n          getStackTrace(e));\r\n      return new InvocationException(INTERNAL_SERVER_ERROR,\r\n          new CommonExceptionData(GENERIC_SERVER, INTERNAL_SERVER_ERROR.getReasonPhrase()));\r\n    }\r\n  }\r\n\r\n  private ExceptionConverter<Throwable> findConverter(Throwable throwable) {\r\n    for (ExceptionConverter<Throwable> converter : converters) {\r\n      if (converter.canConvert(throwable)) {\r\n        return converter;\r\n      }\r\n    }\r\n\r\n    throw new IllegalStateException(\"never happened: can not find converter for \" + throwable.getClass().getName());\r\n  }\r\n\r\n  @Override\r\n  public Response toConsumerResponse(Invocation invocation, Throwable throwable) {\r\n    InvocationException exception = convert(invocation, throwable, BAD_REQUEST);\r\n    logConsumerException(invocation, exception);\r\n    return Response.failResp(exception);\r\n  }\r\n\r\n  @Override\r\n  public void logConsumerException(Invocation invocation, InvocationException exception) {\r\n    if (isIgnoreLog(invocation, exception)) {\r\n      return;\r\n    }\r\n\r\n    if (isPrintStackTrace()) {\r\n      invocation.getTraceIdLogger().error(\"{} Failed to invoke {}, endpoint={}.\",\r\n          TraceIdLogger.constructSource(DefaultExceptionProcessor.class.getSimpleName()),\r\n          invocation.getMicroserviceQualifiedName(),\r\n          invocation.getEndpoint(),\r\n          exception);\r\n      return;\r\n    }\r\n\r\n    invocation.getTraceIdLogger().error(\"{} Failed to invoke {}, endpoint={}, message={}.\",\r\n        TraceIdLogger.constructSource(DefaultExceptionProcessor.class.getSimpleName()),\r\n        invocation.getMicroserviceQualifiedName(),\r\n        invocation.getEndpoint(),\r\n        ExceptionUtils.getExceptionMessageWithoutTrace(exception));\r\n  }\r\n\r\n  @Override\r\n  public boolean isIgnoreLog(Invocation invocation, InvocationException exception) {\r\n    if (!isPrintRateLimit() && exception.getStatusCode() == TOO_MANY_REQUESTS.getStatusCode()) {\r\n      return true;\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  @Override\r\n  public Response toProducerResponse(Invocation invocation, Throwable exception) {\r\n    InvocationException invocationException = convert(invocation, exception, INTERNAL_SERVER_ERROR);\r\n    if (invocation != null) {\r\n      logProducerException(invocation, invocationException);\r\n    }\r\n    return Response.createFail(invocationException);\r\n  }\r\n\r\n  @Override\r\n  public void logProducerException(Invocation invocation, InvocationException exception) {\r\n    if (isIgnoreLog(invocation, exception)) {\r\n      return;\r\n    }\r\n\r\n    if (isPrintStackTrace()) {\r\n      invocation.getTraceIdLogger().error(\"{} Failed to process {} invocation, operation={}.\",\r\n          TraceIdLogger.constructSource(DefaultExceptionProcessor.class.getSimpleName()),\r\n          invocation.getInvocationType(), invocation.getMicroserviceQualifiedName(), exception);\r\n      return;\r\n    }\r\n\r\n    invocation.getTraceIdLogger().error(\"{} Failed to process {} invocation, operation={}, message={}.\",\r\n        TraceIdLogger.constructSource(DefaultExceptionProcessor.class.getSimpleName()),\r\n        invocation.getInvocationType(), invocation.getMicroserviceQualifiedName(),\r\n        ExceptionUtils.getExceptionMessageWithoutTrace(exception));\r\n  }\r\n}\r\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/ExceptionCodes.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception;\n\npublic interface ExceptionCodes {\n  String GENERIC_CLIENT = \"SCB.00000000\";\n  String LB_ADDRESS_NOT_FOUND = \"SCB.00000001\";\n  String NOT_DEFINED_ANY_SCHEMA = \"SCB.00000002\";\n  String DEFAULT_VALIDATE = \"SCB.00000003\";\n  String INVOCATION_TIMEOUT = \"SCB.00000004\";\n\n  String GENERIC_SERVER = \"SCB.50000000\";\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/ExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception;\n\nimport static jakarta.ws.rs.core.Response.Status.Family.CLIENT_ERROR;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.GENERIC_CLIENT;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.GENERIC_SERVER;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic interface ExceptionConverter<T extends Throwable> extends SPIOrder {\n  static boolean isClient(StatusType status) {\n    return CLIENT_ERROR.equals(status.getFamily());\n  }\n\n  static String getGenericCode(StatusType status) {\n    return isClient(status) ? GENERIC_CLIENT : GENERIC_SERVER;\n  }\n\n  /**\n   *\n   * @param throwable exception will be converted\n   * @return can convert the exception\n   */\n  boolean canConvert(Throwable throwable);\n\n  /**\n   *\n   * @param invocation related invocation, will be null only when failed to prepare invocation\n   * @param throwable exception will be converted\n   * @param genericStatus if can not determine the status type, then use this input value\n   * @return converted invocation exception\n   */\n  InvocationException convert(Invocation invocation, T throwable, StatusType genericStatus);\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/ExceptionProcessor.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.exception;\r\n\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.swagger.invocation.Response;\r\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\r\nimport org.springframework.core.Ordered;\r\n\r\nimport jakarta.ws.rs.core.Response.StatusType;\r\n\r\n/**\r\n * will select the min order instance\r\n */\r\npublic interface ExceptionProcessor extends Ordered {\r\n  @Override\r\n  default int getOrder() {\r\n    return 0;\r\n  }\r\n\r\n  boolean isPrintStackTrace();\r\n\r\n  InvocationException convert(Invocation invocation, Throwable throwable);\r\n\r\n  InvocationException convert(Invocation invocation, Throwable throwable, StatusType genericStatus);\r\n\r\n  boolean isIgnoreLog(Invocation invocation, InvocationException exception);\r\n\r\n  Response toConsumerResponse(Invocation invocation, Throwable throwable);\r\n\r\n  void logConsumerException(Invocation invocation, InvocationException exception);\r\n\r\n  Response toProducerResponse(Invocation invocation, Throwable exception);\r\n\r\n  void logProducerException(Invocation invocation, InvocationException exception);\r\n}\r\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/ExceptionUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.exception;\n\nimport org.apache.servicecomb.foundation.common.RegisterManager;\nimport org.apache.servicecomb.foundation.common.utils.FortifyUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class ExceptionUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionUtils.class);\n\n  // 异常码\n  private static final String ERROR_DESC_MGR_MSG = \"error desc mgr\";\n\n  protected static final RegisterManager<String, String> ERROR_DESC_MGR = new RegisterManager<>(ERROR_DESC_MGR_MSG);\n\n  private static final String SERVICECOMB_HANDLER_REF_NOT_EXIST = \"servicecomb.handler.ref.not.exist\";\n\n  private static final String SERVICECOMB_PRODUCER_OPERATION_NOT_EXIST = \"servicecomb.producer.operation.not.exist\";\n\n  private static final String SERVICECOMB_LB_NO_AVAILABLE_ADDRESS = \"servicecomb.lb.no.available.address\";\n\n  static {\n    ERROR_DESC_MGR.register(SERVICECOMB_HANDLER_REF_NOT_EXIST, \"Handler not exist, id=%s\");\n    ERROR_DESC_MGR.register(SERVICECOMB_PRODUCER_OPERATION_NOT_EXIST,\n        \"Producer operation not exist, schemaId=%s, operationName=%s\");\n    ERROR_DESC_MGR.register(SERVICECOMB_LB_NO_AVAILABLE_ADDRESS,\n        \"No available address found. microserviceName=%s, version=%s, discoveryGroupName=%s\");\n  }\n\n  protected ExceptionUtils() {\n  }\n\n  // TODO：应该改为protected，不允许随便调，所有异常，都必须是强类型的\n  public static CseException createCseException(String code, Object... args) {\n    String msg = String.format(ERROR_DESC_MGR.ensureFindValue(code), args);\n\n    CseException exception = new CseException(code, msg);\n    LOGGER.error(FortifyUtils.getErrorInfo(exception));\n    return exception;\n  }\n\n  public static CseException createCseException(String code, Throwable cause, Object... args) {\n    String msg = String.format(ERROR_DESC_MGR.ensureFindValue(code), args);\n\n    CseException exception = new CseException(code, msg, cause);\n    LOGGER.error(FortifyUtils.getErrorInfo(exception));\n    return exception;\n  }\n\n  public static CseException producerOperationNotExist(String schemaId, String operationName) {\n    return createCseException(SERVICECOMB_PRODUCER_OPERATION_NOT_EXIST,\n        schemaId,\n        operationName);\n  }\n\n  public static CseException handlerRefNotExist(String id) {\n    return createCseException(SERVICECOMB_HANDLER_REF_NOT_EXIST, id);\n  }\n\n  public static CseException lbAddressNotFound(String microserviceName, String microserviceVersionRule,\n      String discoveryGroupName) {\n    return createCseException(SERVICECOMB_LB_NO_AVAILABLE_ADDRESS,\n        microserviceName,\n        microserviceVersionRule,\n        discoveryGroupName);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/Exceptions.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.exception;\n\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.GENERIC_CLIENT;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.GENERIC_SERVER;\nimport static org.apache.servicecomb.swagger.invocation.InvocationType.CONSUMER;\n\nimport java.util.Comparator;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class Exceptions {\n  private static ExceptionProcessor processor = new DefaultExceptionProcessor();\n\n  @Autowired(required = false)\n  public void setProcessor(List<ExceptionProcessor> processors) {\n    // never be null, \"orElse\" just to avoid compile warning\n    processor = processors.stream()\n        .min(Comparator.comparingInt(ExceptionProcessor::getOrder))\n        .orElse(new DefaultExceptionProcessor());\n  }\n\n  public static Throwable unwrapIncludeInvocationException(Throwable throwable) {\n    return ExceptionFactory.unwrapIncludeInvocationException(throwable);\n  }\n\n  public static <T extends Throwable> T unwrap(Throwable throwable) {\n    return ExceptionFactory.unwrap(throwable);\n  }\n\n  public static InvocationException create(StatusType status, Object errorData) {\n    return new InvocationException(status, errorData);\n  }\n\n  public static InvocationException create(StatusType status, String code, String msg) {\n    return new InvocationException(status, code, msg);\n  }\n\n  private static InvocationException create(StatusType status, String code, String msg, Throwable cause) {\n    return new InvocationException(status, code, msg, cause);\n  }\n\n  public static InvocationException consumer(String code, String msg) {\n    return create(BAD_REQUEST, code, msg);\n  }\n\n  public static InvocationException consumer(String code, String msg, Throwable cause) {\n    if (cause instanceof InvocationException) {\n      return (InvocationException) cause;\n    }\n    return create(BAD_REQUEST, code, msg, cause);\n  }\n\n  public static InvocationException genericConsumer(String msg) {\n    return consumer(GENERIC_CLIENT, msg);\n  }\n\n  public static InvocationException genericConsumer(String msg, Throwable cause) {\n    return consumer(GENERIC_CLIENT, msg, cause);\n  }\n\n  public static InvocationException producer(String code, String msg) {\n    return create(INTERNAL_SERVER_ERROR, code, msg);\n  }\n\n  public static InvocationException producer(String code, String msg, Throwable cause) {\n    return create(INTERNAL_SERVER_ERROR, code, msg, cause);\n  }\n\n  public static InvocationException genericProducer(String msg) {\n    return producer(GENERIC_SERVER, msg);\n  }\n\n  public static InvocationException genericProducer(String msg, Throwable cause) {\n    return producer(GENERIC_SERVER, msg, cause);\n  }\n\n  public static StatusType getGenericStatus(Invocation invocation) {\n    return CONSUMER.equals(invocation.getInvocationType()) ? BAD_REQUEST : INTERNAL_SERVER_ERROR;\n  }\n\n  public static Response toConsumerResponse(Invocation invocation, Throwable throwable) {\n    return processor.toConsumerResponse(invocation, throwable);\n  }\n\n  public static Response toProducerResponse(Invocation invocation, Throwable exception) {\n    return processor.toProducerResponse(invocation, exception);\n  }\n\n  public static InvocationException convert(Invocation invocation, Throwable throwable) {\n    return processor.convert(invocation, throwable);\n  }\n\n  public static InvocationException convert(Invocation invocation, Throwable throwable,\n      StatusType genericStatus) {\n    return processor.convert(invocation, throwable, genericStatus);\n  }\n\n  public static boolean isPrintInvocationStackTrace() {\n    return processor.isPrintStackTrace();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/ConnectTimeoutExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.netty.channel.ConnectTimeoutException;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class ConnectTimeoutExceptionConverter implements ExceptionConverter<ConnectTimeoutException> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConnectTimeoutExceptionConverter.class);\n\n  public static final int ORDER = Short.MAX_VALUE;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof ConnectTimeoutException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, ConnectTimeoutException throwable,\n      StatusType genericStatus) {\n    // throwable.getMessage:\n    //   connection timed out: /1.1.1.1:8080\n    // should not copy the message to invocationException to avoid leak server ip address\n    LOGGER.info(\"connection timed out, Details: {}.\", throwable.getMessage());\n\n    return new InvocationException(INTERNAL_SERVER_ERROR,\n        ExceptionConverter.getGenericCode(genericStatus), \"connection timed out.\",\n        throwable);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/ConstraintViolationExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.DEFAULT_VALIDATE;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.validation.ConstraintViolationException;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class ConstraintViolationExceptionConverter implements ExceptionConverter<ConstraintViolationException> {\n  public static final int ORDER = Short.MAX_VALUE;\n\n  public static final String KEY_CODE = \"servicecomb.filters.validate.code\";\n\n  public ConstraintViolationExceptionConverter() {\n  }\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof ConstraintViolationException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, ConstraintViolationException throwable,\n      StatusType genericStatus) {\n    List<ValidateDetail> details = throwable.getConstraintViolations().stream()\n        .map(violation -> new ValidateDetail(violation.getPropertyPath().toString(), violation.getMessage()))\n        .collect(Collectors.toList());\n\n    CommonExceptionData exceptionData = new CommonExceptionData(SCBEngine.getInstance().getEnvironment().\n        getProperty(KEY_CODE, String.class, DEFAULT_VALIDATE), \"invalid parameters.\");\n    exceptionData.putDynamic(\"validateDetail\", details);\n    return new InvocationException(BAD_REQUEST, exceptionData);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/DefaultExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\n/**\n * <pre>\n *   Only very few exceptions carry sensitive data\n *   If discard all exception messages for these very few exceptions, it will cause difficult to locate problems\n *\n *   so default to remain the messages, and log the exception\n *\n *   if want to change these:\n *   1. customize a new converter\n *   2. disabled log for this class by log configuration\n * </pre>\n */\npublic class DefaultExceptionConverter implements ExceptionConverter<Throwable> {\n  public static final int ORDER = Integer.MAX_VALUE;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return true;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, Throwable throwable, StatusType genericStatus) {\n    String msg = String.format(\"Unexpected exception when processing %s. %s\",\n        invocation == null ? \"none\" : invocation.getMicroserviceQualifiedName(), throwable.getMessage());\n    return new InvocationException(genericStatus, ExceptionConverter.getGenericCode(genericStatus),\n        msg, throwable);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/IllegalArgumentExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class IllegalArgumentExceptionConverter implements ExceptionConverter<IllegalArgumentException> {\n  public static final int ORDER = Short.MAX_VALUE;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof IllegalArgumentException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, IllegalArgumentException throwable,\n      StatusType genericStatus) {\n    return new InvocationException(genericStatus, ExceptionConverter.getGenericCode(genericStatus),\n        \"Parameters not valid or types not match.\", throwable);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/InvocationExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class InvocationExceptionConverter implements ExceptionConverter<InvocationException> {\n  public static final int ORDER = Byte.MAX_VALUE;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof InvocationException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, InvocationException throwable,\n      StatusType genericStatus) {\n    return throwable;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/ServiceCombExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.exception.converter;\n\nimport java.util.concurrent.TimeoutException;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class ServiceCombExceptionConverter implements ExceptionConverter<ServiceCombException> {\n  public static final int ORDER = Byte.MAX_VALUE;\n\n  private TimeoutExceptionConverter timeoutExceptionConverter = new TimeoutExceptionConverter();\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof ServiceCombException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, ServiceCombException throwable,\n      StatusType genericStatus) {\n    if (throwable.getCause() instanceof TimeoutException) {\n      return timeoutExceptionConverter.convert(invocation, (TimeoutException) throwable.getCause(), genericStatus);\n    }\n\n    return new InvocationException(Status.INTERNAL_SERVER_ERROR,\n        ExceptionConverter.getGenericCode(genericStatus), throwable.getMessage(),\n        throwable);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/TimeoutExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\nimport static jakarta.ws.rs.core.Response.Status.REQUEST_TIMEOUT;\n\nimport java.util.concurrent.TimeoutException;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class TimeoutExceptionConverter implements ExceptionConverter<TimeoutException> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TimeoutExceptionConverter.class);\n\n  public static final int ORDER = Short.MAX_VALUE;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof TimeoutException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, TimeoutException throwable,\n      StatusType genericStatus) {\n    // throwable.getMessage:\n    //   The timeout period of 30000ms has been exceeded while executing GET /xxx for server 1.1.1.1:8080\n    // should not copy the message to invocationException to avoid leak server ip address\n    LOGGER.info(\"Request timeout, Details: {}.\", throwable.getMessage());\n\n    return new InvocationException(REQUEST_TIMEOUT,\n        ExceptionConverter.getGenericCode(genericStatus), \"Request Timeout.\",\n        throwable);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/exception/converter/ValidateDetail.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.exception.converter;\n\npublic class ValidateDetail {\n  private String propertyPath;\n\n  private String message;\n\n  public ValidateDetail() {\n  }\n\n  public ValidateDetail(String propertyPath, String message) {\n    this.propertyPath = propertyPath;\n    this.message = message;\n  }\n\n  public String getPropertyPath() {\n    return propertyPath;\n  }\n\n  public ValidateDetail setPropertyPath(String propertyPath) {\n    this.propertyPath = propertyPath;\n    return this;\n  }\n\n  public String getMessage() {\n    return message;\n  }\n\n  public ValidateDetail setMessage(String message) {\n    this.message = message;\n    return this;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/executor/ExecutorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.executor;\n\nimport java.util.Map;\nimport java.util.concurrent.Executor;\n\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic final class ExecutorManager {\n  public static final String KEY_EXECUTORS_PREFIX = \"servicecomb.executors.Provider.\";\n\n  public static final String KEY_EXECUTORS_DEFAULT = \"servicecomb.executors.default\";\n\n  public static final String EXECUTOR_GROUP_THREAD_POOL = \"servicecomb.executor.groupThreadPool\";\n\n  public static final String EXECUTOR_REACTIVE = \"servicecomb.executor.reactive\";\n\n  private final Map<String, Executor> executors = new ConcurrentHashMapEx<>();\n\n  static String EXECUTOR_DEFAULT = EXECUTOR_GROUP_THREAD_POOL;\n\n  public static void setExecutorDefault(String executorDefault) {\n    EXECUTOR_DEFAULT = executorDefault;\n  }\n\n  private Environment environment;\n\n  public ExecutorManager() {\n    registerExecutor(EXECUTOR_REACTIVE, new ReactiveExecutor());\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  public void registerExecutor(String id, Executor executor) {\n    Executor existing = executors.putIfAbsent(id, executor);\n    if (existing != null) {\n      throw new IllegalStateException(String.format(\n          \"duplicated executor, id=%s, old executor=%s, new executor=%s\",\n          id, existing.getClass().getName(), executor.getClass().getName()));\n    }\n  }\n\n  // 只会在初始化时执行，一点点重复的查找，没必要做缓存\n  public Executor findExecutor(OperationMeta operationMeta) {\n    return findExecutor(operationMeta, null);\n  }\n\n  public Executor findExecutor(OperationMeta operationMeta, Executor defaultOperationExecutor) {\n    // operation级别\n    Executor executor = findByKey(KEY_EXECUTORS_PREFIX + operationMeta.getMicroserviceQualifiedName());\n    if (executor != null) {\n      return executor;\n    }\n\n    executor = findByKey(KEY_EXECUTORS_PREFIX + operationMeta.getSchemaQualifiedName());\n    if (executor != null) {\n      return executor;\n    }\n\n    if (defaultOperationExecutor != null) {\n      return defaultOperationExecutor;\n    }\n\n    // schema级别\n    executor = findByKey(\n        KEY_EXECUTORS_PREFIX + operationMeta.getMicroserviceName() + '.' + operationMeta.getSchemaId());\n    if (executor != null) {\n      return executor;\n    }\n\n    executor = findByKey(KEY_EXECUTORS_PREFIX + operationMeta.getSchemaId());\n    if (executor != null) {\n      return executor;\n    }\n\n    // microservice级别\n    executor = findByKey(KEY_EXECUTORS_PREFIX + operationMeta.getMicroserviceName());\n    if (executor != null) {\n      return executor;\n    }\n\n    // 寻找config-key指定的default\n    executor = findByKey(KEY_EXECUTORS_DEFAULT);\n    if (executor != null) {\n      return executor;\n    }\n\n    return findExecutorById(EXECUTOR_DEFAULT);\n  }\n\n  private Executor findByKey(String configKey) {\n    String id = environment.getProperty(configKey);\n    if (id == null) {\n      return null;\n    }\n\n    return findExecutorById(id);\n  }\n\n  public Executor findExecutorById(String id) {\n    Executor executor = executors.get(id);\n    if (executor != null) {\n      return executor;\n    }\n\n    return BeanUtils.getBean(id);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/executor/GroupExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.executor;\n\nimport java.io.Closeable;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\npublic class GroupExecutor implements Executor, Closeable {\n  private static final Logger LOGGER = LoggerFactory.getLogger(GroupExecutor.class);\n\n  public static final String KEY_GROUP = \"servicecomb.executor.default.group\";\n\n  // Deprecated\n  public static final String KEY_OLD_MAX_THREAD = \"servicecomb.executor.default.thread-per-group\";\n\n  public static final String KEY_CORE_THREADS = \"servicecomb.executor.default.coreThreads-per-group\";\n\n  public static final String KEY_MAX_THREADS = \"servicecomb.executor.default.maxThreads-per-group\";\n\n  public static final String KEY_MAX_IDLE_SECOND = \"servicecomb.executor.default.maxIdleSecond-per-group\";\n\n  public static final String KEY_MAX_QUEUE_SIZE = \"servicecomb.executor.default.maxQueueSize-per-group\";\n\n  private static final AtomicBoolean LOG_PRINTED = new AtomicBoolean();\n\n  private final Environment environment;\n\n  protected String groupName;\n\n  protected int groupCount;\n\n  protected int coreThreads;\n\n  protected int maxThreads;\n\n  protected int maxIdleInSecond;\n\n  protected int maxQueueSize;\n\n  // to avoid multiple network thread conflicted when put tasks to executor queue\n  private final List<ExecutorService> executorList = new ArrayList<>();\n\n  // for bind network thread to one executor\n  // it's impossible that has too many network thread, so index will not too big that less than 0\n  private final AtomicInteger index = new AtomicInteger();\n\n  private final Map<Long, Executor> threadExecutorMap = new ConcurrentHashMapEx<>();\n\n  public GroupExecutor(Environment environment) {\n    this.environment = environment;\n  }\n\n  public GroupExecutor init() {\n    return init(\"group\");\n  }\n\n  public GroupExecutor init(String groupName) {\n    this.groupName = groupName;\n    initConfig();\n\n    for (int groupIdx = 0; groupIdx < groupCount; groupIdx++) {\n      GroupThreadFactory factory = new GroupThreadFactory(groupName + groupIdx);\n\n      ThreadPoolExecutorEx executor = new ThreadPoolExecutorEx(coreThreads,\n          maxThreads,\n          maxIdleInSecond,\n          TimeUnit.SECONDS,\n          new LinkedBlockingQueueEx(maxQueueSize),\n          factory);\n      executorList.add(executor);\n    }\n\n    return this;\n  }\n\n  public synchronized void initConfig() {\n    if (LOG_PRINTED.compareAndSet(false, true)) {\n      LOGGER.info(\"thread pool rules:\\n\"\n          + \"1.use core threads.\\n\"\n          + \"2.if all core threads are busy, then create new thread.\\n\"\n          + \"3.if thread count reach the max limitation, then queue the request.\\n\"\n          + \"4.if queue is full, and threads count is max, then reject the request.\");\n    }\n\n    groupCount = environment.getProperty(KEY_GROUP, int.class, 2);\n    coreThreads = environment.getProperty(KEY_CORE_THREADS, int.class, 25);\n\n    maxThreads = environment.getProperty(KEY_MAX_THREADS, int.class, -1);\n    if (maxThreads <= 0) {\n      maxThreads = environment.getProperty(KEY_OLD_MAX_THREAD, int.class, -1);\n      if (maxThreads > 0) {\n        LOGGER.warn(\"{} is deprecated, recommended to use {}.\", KEY_OLD_MAX_THREAD, KEY_MAX_THREADS);\n      } else {\n        maxThreads = 100;\n      }\n    }\n    if (coreThreads > maxThreads) {\n      LOGGER.warn(\"coreThreads is bigger than maxThreads, change from {} to {}.\", coreThreads, maxThreads);\n      coreThreads = maxThreads;\n    }\n\n    maxIdleInSecond = environment.getProperty(KEY_MAX_IDLE_SECOND, int.class, 60);\n    maxQueueSize = environment.getProperty(KEY_MAX_QUEUE_SIZE, int.class, Integer.MAX_VALUE);\n\n    LOGGER.info(\n        \"executor name={}, group={}. per group settings, coreThreads={}, maxThreads={}, maxIdleInSecond={}, maxQueueSize={}.\",\n        groupName, groupCount, coreThreads, maxThreads, maxIdleInSecond, maxQueueSize);\n  }\n\n  public List<ExecutorService> getExecutorList() {\n    return executorList;\n  }\n\n  @Override\n  public void execute(Runnable command) {\n    long threadId = Thread.currentThread().getId();\n    Executor executor = threadExecutorMap.computeIfAbsent(threadId, this::chooseExecutor);\n\n    executor.execute(command);\n  }\n\n  private Executor chooseExecutor(long threadId) {\n    int idx = index.getAndIncrement() % executorList.size();\n    return executorList.get(idx);\n  }\n\n  @Override\n  public void close() {\n    for (ExecutorService executorService : executorList) {\n      executorService.shutdown();\n    }\n    executorList.clear();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/executor/GroupThreadFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.executor;\n\nimport java.util.Objects;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class GroupThreadFactory implements ThreadFactory {\n  private static final AtomicInteger poolNumber = new AtomicInteger(1);\n\n  private final ThreadGroup group;\n\n  private final AtomicInteger threadNumber = new AtomicInteger(1);\n\n  private final String namePrefix;\n\n  public GroupThreadFactory(String prefix) {\n    Objects.requireNonNull(prefix);\n\n    group = Thread.currentThread().getThreadGroup();\n\n    namePrefix = prefix + \"-\" + poolNumber.getAndIncrement() + \"-thread-\";\n  }\n\n  public Thread newThread(Runnable r) {\n    Thread t = new Thread(group, r,\n        namePrefix + threadNumber.getAndIncrement(),\n        0);\n    if (t.isDaemon()) {\n      t.setDaemon(false);\n    }\n    if (t.getPriority() != Thread.NORM_PRIORITY) {\n      t.setPriority(Thread.NORM_PRIORITY);\n    }\n    return t;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/executor/LinkedBlockingQueueEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.executor;\n\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.RejectedExecutionException;\n\npublic class LinkedBlockingQueueEx extends LinkedBlockingQueue<Runnable> {\n  private static final long serialVersionUID = -1L;\n\n  private transient volatile ThreadPoolExecutorEx owner = null;\n\n  public LinkedBlockingQueueEx(int capacity) {\n    super(capacity);\n  }\n\n  public void setOwner(ThreadPoolExecutorEx owner) {\n    this.owner = owner;\n  }\n\n  @Override\n  public boolean offer(Runnable runnable) {\n    // task can come before owner available\n    if (owner == null) {\n      return super.offer(runnable);\n    }\n    // can not create more thread, just queue the task\n    if (owner.getPoolSize() == owner.getMaximumPoolSize()) {\n      return super.offer(runnable);\n    }\n    // no need to create more thread, just queue the task\n    if (owner.getNotFinished() <= owner.getPoolSize()) {\n      return super.offer(runnable);\n    }\n    // all threads are busy, and can create new thread, not queue the task\n    if (owner.getPoolSize() < owner.getMaximumPoolSize()) {\n      return false;\n    }\n    return super.offer(runnable);\n  }\n\n  /*\n   * when task is rejected (thread pool if full), force the item onto queue.\n   */\n  public boolean force(Runnable runnable) {\n    if (owner == null || owner.isShutdown()) {\n      throw new RejectedExecutionException(\"queue is not running.\");\n    }\n    return super.offer(runnable);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/executor/ReactiveExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.executor;\n\nimport java.io.Closeable;\nimport java.util.concurrent.Executor;\n\n/**\n * 用于在verticle中就地执行，不做多余的调度，这是性能最高的一种模型\n */\npublic class ReactiveExecutor implements Executor, Closeable {\n\n  @Override\n  public void execute(Runnable command) {\n    command.run();\n  }\n\n  @Override\n  public void close() {\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/executor/ThreadPoolExecutorEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.executor;\n\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.RejectedExecutionException;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class ThreadPoolExecutorEx extends ThreadPoolExecutor {\n  private final AtomicInteger submittedCount = new AtomicInteger();\n\n  private final AtomicInteger finishedCount = new AtomicInteger();\n\n  private final AtomicInteger rejectedCount = new AtomicInteger();\n\n  public ThreadPoolExecutorEx(int coreThreads, int maxThreads, int maxIdleInSecond, TimeUnit timeUnit,\n      BlockingQueue<Runnable> queue, ThreadFactory threadFactory) {\n    super(coreThreads, maxThreads, maxIdleInSecond, timeUnit, queue, threadFactory);\n    if (queue instanceof LinkedBlockingQueueEx) {\n      ((LinkedBlockingQueueEx) queue).setOwner(this);\n    }\n    setRejectedExecutionHandler(this::rejectedExecution);\n  }\n\n  @Override\n  public void execute(Runnable command) {\n    submittedCount.incrementAndGet();\n    try {\n      super.execute(command);\n    } catch (RejectedExecutionException e) {\n      if (getQueue() instanceof LinkedBlockingQueueEx) {\n        final LinkedBlockingQueueEx queue = (LinkedBlockingQueueEx) getQueue();\n        if (!queue.force(command)) {\n          throw new RejectedExecutionException(\"thread pool queue is full\");\n        }\n      } else {\n        throw e;\n      }\n    }\n  }\n\n  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {\n    rejectedCount.incrementAndGet();\n    finishedCount.incrementAndGet();\n\n    throw new RejectedExecutionException(\"Task \" + r.toString() +\n        \" rejected from \" +\n        e.toString());\n  }\n\n  @Override\n  protected void afterExecute(Runnable r, Throwable t) {\n    super.afterExecute(r, t);\n    finishedCount.incrementAndGet();\n  }\n\n  public int getNotFinished() {\n    return submittedCount.get() - finishedCount.get();\n  }\n\n  public int getRejectedCount() {\n    return rejectedCount.get();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/AbstractFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\nimport org.springframework.context.EnvironmentAware;\nimport org.springframework.core.env.Environment;\n\npublic abstract class AbstractFilter implements Filter, EnvironmentAware {\n  private static final String ORDER_KEY = \"servicecomb.filter.%s.%s.%s.order\";\n\n  private static final String ENABLE_KEY = \"servicecomb.filter.%s.%s.%s.enabled\";\n\n  protected Environment environment;\n\n  private String nameWithOrder;\n\n  @Override\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public int getOrder(String application, String serviceName) {\n    Integer custom = environment.getProperty(String.format(ORDER_KEY, getName(), application, serviceName),\n        Integer.class);\n    if (custom != null) {\n      return custom;\n    }\n    return getOrder();\n  }\n\n  @Override\n  public boolean enabledForMicroservice(String application, String serviceName) {\n    Boolean custom = environment.getProperty(String.format(ENABLE_KEY, getName(), application, serviceName),\n        Boolean.class);\n    if (custom != null) {\n      return custom;\n    }\n    return true;\n  }\n\n  @Override\n  public String getNameWithOrder() {\n    if (nameWithOrder == null) {\n      nameWithOrder = String.format(\"F(%1$06d)-%2$s\", getOrder(), getName());\n    }\n    return nameWithOrder;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/ConsumerFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\npublic interface ConsumerFilter extends Filter {\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/CoreFilterConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\nimport org.apache.servicecomb.core.filter.impl.ContextMapperFilter;\nimport org.apache.servicecomb.core.filter.impl.ParameterValidatorFilter;\nimport org.apache.servicecomb.core.filter.impl.ProviderOperationFilter;\nimport org.apache.servicecomb.core.filter.impl.RetryFilter;\nimport org.apache.servicecomb.core.filter.impl.ScheduleFilter;\nimport org.apache.servicecomb.governance.handler.MapperHandler;\nimport org.apache.servicecomb.governance.handler.RetryHandler;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class CoreFilterConfiguration {\n  @Bean\n  public ProviderOperationFilter scbProducerOperationFilter() {\n    return new ProviderOperationFilter();\n  }\n\n  @Bean\n  public ScheduleFilter scbScheduleFilter() {\n    return new ScheduleFilter();\n  }\n\n  @Bean\n  public RetryFilter scbRetryFilter(RetryHandler retryHandler) {\n    return new RetryFilter(retryHandler);\n  }\n\n  @Bean\n  public ContextMapperFilter scbContextMapperFilter(MapperHandler mapperHandler) {\n    return new ContextMapperFilter(mapperHandler);\n  }\n\n  @Bean\n  public FilterChainsManager scbFilterChainsManager() {\n    return new FilterChainsManager();\n  }\n\n  @Bean\n  public ParameterValidatorFilter scbParameterValidatorFilter() {\n    return new ParameterValidatorFilter();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/EdgeFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\npublic interface EdgeFilter extends Filter {\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/Filter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.core.Ordered;\n\n/**\n * <pre>\n *  Filters are the basics of how an invocation is executed.\n *\n * thread rule:\n *   assume a provider filter chains is: f1, f2, schedule, f3, f4\n *\n *   schedule is a builtIn filter, which will dispatch invocations to operation related threadPool\n *\n *   f1 and f2 are before \"schedule\" filter, default to run in eventLoop\n *   if developers customize filters and switch to other threads\n *   it's better to switch back to eventLoop, unless you know what you are doing\n *\n *   f3 and f4 are after \"schedule\" filter, default thread depend on controller's method signature\n *     1. if controller method not return CompletableFuture\n *        then will run in a real threadPool\n *     2. if controller method return CompletableFuture\n *        then will still run in eventLoop\n *   so filters after \"schedule\" filter, are more complex than filters before \"schedule\"\n *   if developers need to do some BLOCK logic, MUST use different Strategy when running in different thread:\n *     1. threadPool: run do BLOCK logic directly\n *     2. eventLoop: MUST submit to a threadPool, and then switch back\n *        (<a href=\"https://vertx.io/docs/vertx-core/java/#golden_rule\">reactive golden rule</a>)\n * </pre>\n */\npublic interface Filter extends Ordered {\n  int PROVIDER_SCHEDULE_FILTER_ORDER = 0;\n\n  int CONSUMER_LOAD_BALANCE_ORDER = 0;\n\n  default boolean enabledForTransport(String transport) {\n    return true;\n  }\n\n  default boolean enabledForMicroservice(String application, String serviceName) {\n    return true;\n  }\n\n  default int getOrder(String application, String serviceName) {\n    return 0;\n  }\n\n  default int getOrder() {\n    return 0;\n  }\n\n  default String getName() {\n    throw new IllegalStateException(\"must provide unique filter name.\");\n  }\n\n  String getNameWithOrder();\n\n  /**\n   *\n   * @param invocation invocation\n   * @param nextNode node filter node\n   * @return response future<br>\n   *         even Response can express fail data<br>\n   *         but Response only express success data in filter chain<br>\n   *         all fail data can only express by exception<br>\n   *         <br>\n   *         special for producer:<br>\n   *           if response is failure, then after encode response, response.result will\n   *           be exception.errorData, not a exception\n   */\n  CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode);\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/FilterChainsManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.deleteLast;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class FilterChainsManager {\n  private InvocationFilterChains consumerChains;\n\n  private InvocationFilterChains providerChains;\n\n  private InvocationFilterChains edgeChains;\n\n  @Autowired\n  public FilterChainsManager setEdgeFilters(List<EdgeFilter> filters) {\n    edgeChains = new InvocationFilterChains(filters);\n    return this;\n  }\n\n  @Autowired\n  public FilterChainsManager setConsumerFilters(List<ConsumerFilter> filters) {\n    consumerChains = new InvocationFilterChains(filters);\n    return this;\n  }\n\n  @Autowired\n  public FilterChainsManager setProviderFilters(List<ProviderFilter> filters) {\n    providerChains = new InvocationFilterChains(filters);\n    return this;\n  }\n\n  public FilterChainsManager init() {\n    return this;\n  }\n\n  public FilterNode findConsumerChain(String application, String serviceName) {\n    return consumerChains.findChain(application, serviceName);\n  }\n\n  public FilterNode findProducerChain(String application, String serviceName) {\n    return providerChains.findChain(application, serviceName);\n  }\n\n  public FilterNode findEdgeChain(String application, String serviceName) {\n    return edgeChains.findChain(application, serviceName);\n  }\n\n  public String collectResolvedChains() {\n    StringBuilder sb = new StringBuilder();\n\n    appendLine(sb, \"consumer: \");\n    appendLine(sb, \"  filters: %s\", collectFilterNames(consumerChains));\n\n    appendLine(sb, \"producer: \");\n    appendLine(sb, \"  filters: %s\", collectFilterNames(providerChains));\n\n    appendLine(sb, \"edge: \");\n    appendLine(sb, \"  filters: %s\", collectFilterNames(edgeChains));\n\n    return deleteLast(sb, 1).toString();\n  }\n\n  private List<String> collectFilterNames(InvocationFilterChains chains) {\n    return chains.getFilters().stream()\n        .map(filter -> filter.getName() + \"(\" + filter.getOrder() + \")\")\n        .collect(Collectors.toList());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class FilterNode {\n  public static final FilterNode EMPTY = new FilterNode(null) {\n    @Override\n    public CompletableFuture<Response> onFilter(Invocation invocation) {\n      return CompletableFuture.completedFuture(Response.ok(null));\n    }\n  };\n\n  public static FilterNode buildChain(Filter... filters) {\n    return buildChain(Arrays.asList(filters));\n  }\n\n  public static FilterNode buildChain(List<Filter> filters) {\n    List<FilterNode> filterNodes = filters.stream()\n        .map(FilterNode::new).toList();\n\n    for (int idx = 0; idx < filterNodes.size() - 1; idx++) {\n      FilterNode currentNode = filterNodes.get(idx);\n      FilterNode nextNode = filterNodes.get(idx + 1);\n      currentNode.setNextNode(nextNode);\n    }\n\n    return filterNodes.get(0);\n  }\n\n  private final Filter filter;\n\n  private FilterNode nextNode;\n\n  public FilterNode(Filter filter) {\n    this.filter = filter;\n  }\n\n  private void setNextNode(FilterNode nextNode) {\n    this.nextNode = nextNode;\n  }\n\n  public CompletableFuture<Response> onFilter(Invocation invocation) {\n    // When transport name is empty, maybe edge transport filters need to be executed.\n    // Can't set Endpoint before load balance in edge.\n    if (invocation.getTransportName() != null && !filter.enabledForTransport(invocation.getTransportName())) {\n      return nextNode.onFilter(invocation);\n    }\n\n    String stage = invocation.getInvocationStageTrace().recordStageBegin(this.filter.getNameWithOrder());\n    return AsyncUtils.tryCatchSupplierFuture(() -> filter.onFilter(invocation, nextNode)\n        .whenComplete((r, e) -> invocation.getInvocationStageTrace().recordStageEnd(stage)));\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/InvocationFilterChains.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.filter;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\npublic class InvocationFilterChains {\n\n  private final List<? extends Filter> filters;\n\n  private final Map<String, Map<String, FilterNode>> microserviceChains = new ConcurrentHashMapEx<>();\n\n  public InvocationFilterChains(List<? extends Filter> filters) {\n    this.filters = filters;\n  }\n\n  public List<? extends Filter> getFilters() {\n    return filters;\n  }\n\n  public FilterNode findChain(String application, String serviceName) {\n    return microserviceChains.computeIfAbsent(application, key -> new ConcurrentHashMapEx<>())\n        .computeIfAbsent(serviceName, (serviceNameInner) -> {\n          List<Filter> serviceFilters = filters.stream()\n              .filter(e -> e.enabledForMicroservice(application, serviceName))\n              .sorted(Comparator.comparingInt(a -> a.getOrder(application, serviceName)))\n              .collect(Collectors.toList());\n          return FilterNode.buildChain(serviceFilters);\n        });\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/ProviderFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter;\n\npublic interface ProviderFilter extends Filter {\n\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/ContextMapperFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter.impl;\n\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.governance.handler.MapperHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.processor.mapping.Mapper;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.util.CollectionUtils;\n\npublic class ContextMapperFilter extends AbstractFilter implements ProviderFilter, EdgeFilter {\n  private final MapperHandler mapperHandler;\n\n  public ContextMapperFilter(MapperHandler mapperHandler) {\n    this.mapperHandler = mapperHandler;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.RESTFUL.equals(transport);\n  }\n\n  @Override\n  public int getOrder() {\n    return -1995;\n  }\n\n  @Override\n  public String getName() {\n    return \"context-mapper\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n    Mapper mapper = mapperHandler.getActuator(request);\n    if (mapper == null || CollectionUtils.isEmpty(mapper.target())) {\n      return nextNode.onFilter(invocation);\n    }\n    Map<String, String> properties = mapper.target();\n    properties.forEach((k, v) -> {\n      if (StringUtils.isEmpty(v)) {\n        return;\n      }\n      if (\"$U\".equals(v)) {\n        invocation.addContext(k, request.apiPath());\n      } else if (\"$M\".equals(v)) {\n        invocation.addContext(k, request.method());\n      } else if (v.startsWith(\"$H{\") && v.endsWith(\"}\")) {\n        invocation.addContext(k, request.header(v.substring(3, v.length() - 1)));\n      } else if (v.startsWith(\"$Q{\") && v.endsWith(\"}\")) {\n        invocation.addContext(k, request.query(v.substring(3, v.length() - 1)));\n      } else {\n        invocation.addContext(k, v);\n      }\n    });\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/EmptyFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter.impl;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\n// just for test\npublic class EmptyFilter extends AbstractFilter implements ProviderFilter, ConsumerFilter, EdgeFilter {\n  @Override\n  public String getName() {\n    return \"empty\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    return CompletableFuture.completedFuture(Response.ok(null));\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/JacksonPropertyNodeNameProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.filter.impl;\n\nimport org.hibernate.validator.spi.nodenameprovider.JavaBeanProperty;\nimport org.hibernate.validator.spi.nodenameprovider.Property;\nimport org.hibernate.validator.spi.nodenameprovider.PropertyNodeNameProvider;\n\nimport com.fasterxml.jackson.databind.BeanDescription;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\n\nimport io.vertx.core.json.jackson.DatabindCodec;\n\n/**\n * hibernate validator will cache the resolved data<br>\n *   no need to worry about performance problem\n */\npublic class JacksonPropertyNodeNameProvider implements PropertyNodeNameProvider {\n  @Override\n  public String getName(Property property) {\n    if (property instanceof JavaBeanProperty) {\n      return getJavaBeanPropertyName((JavaBeanProperty) property);\n    }\n\n    return property.getName();\n  }\n\n  private String getJavaBeanPropertyName(JavaBeanProperty property) {\n    ObjectMapper objectMapper = DatabindCodec.mapper();\n    JavaType type = objectMapper.constructType(property.getDeclaringClass());\n    BeanDescription desc = objectMapper.getSerializationConfig().introspect(type);\n\n    return desc.findProperties()\n        .stream()\n        .filter(prop -> prop.getInternalName().equals(property.getName()))\n        .map(BeanPropertyDefinition::getName)\n        .findFirst()\n        .orElse(property.getName());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter.impl;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.hibernate.validator.HibernateValidator;\nimport org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator;\nimport org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;\nimport org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.InitializingBean;\n\nimport jakarta.validation.Configuration;\nimport jakarta.validation.ConstraintViolation;\nimport jakarta.validation.ConstraintViolationException;\nimport jakarta.validation.Valid;\nimport jakarta.validation.Validation;\nimport jakarta.validation.ValidatorFactory;\nimport jakarta.validation.constraints.Min;\nimport jakarta.validation.constraints.NotNull;\nimport jakarta.validation.executable.ExecutableValidator;\nimport jakarta.validation.groups.Default;\n\npublic class ParameterValidatorFilter extends AbstractFilter implements ProviderFilter, InitializingBean {\n  private static class Service {\n    @SuppressWarnings(\"unused\")\n    public void service(@Valid Model model) {\n\n    }\n  }\n\n  private static class Model {\n    @NotNull\n    String name;\n\n    @Min(10)\n    int age;\n\n    Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ParameterValidatorFilter.class);\n\n  public static final String NAME = \"validator\";\n\n  public static final String HIBERNATE_VALIDATE_PREFIX = \"hibernate.validator\";\n\n  public static final String ENABLE_EL = \"servicecomb.filters.validation.useResourceBundleMessageInterpolator\";\n\n  protected ExecutableValidator validator;\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER + 1000;\n  }\n\n  @Override\n  public void afterPropertiesSet() {\n    validator = createValidatorFactory()\n        .getValidator().forExecutables();\n    initValidate();\n  }\n\n  private void initValidate() {\n    // This method is intended to make first rpc call faster\n    // Because validation cache bean class, this way only make first rpc call a little faster.\n    try {\n      Model model = new Model(\"foo\", 23);\n      Service instance = new Service();\n      Method method = Service.class.getMethod(\"service\", Model.class);\n      Object[] args = new Object[] {model};\n      validator.validateParameters(instance, method, args, Default.class);\n    } catch (Throwable e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  protected ValidatorFactory createValidatorFactory() {\n    Configuration<?> validatorConfiguration = Validation.byProvider(HibernateValidator.class)\n        .configure()\n        .propertyNodeNameProvider(new JacksonPropertyNodeNameProvider())\n        .messageInterpolator(messageInterpolator());\n    Map<String, String> properties = ConfigUtil.stringPropertiesWithPrefix(environment, HIBERNATE_VALIDATE_PREFIX);\n    if (!properties.isEmpty()) {\n      for (Map.Entry<String, String> entry : properties.entrySet()) {\n        validatorConfiguration.addProperty(entry.getKey(), entry.getValue());\n      }\n    }\n    return validatorConfiguration.buildValidatorFactory();\n  }\n\n  protected AbstractMessageInterpolator messageInterpolator() {\n    if (useResourceBundleMessageInterpolator()) {\n      return new ResourceBundleMessageInterpolator();\n    }\n    return new ParameterMessageInterpolator();\n  }\n\n  private boolean useResourceBundleMessageInterpolator() {\n    return environment.getProperty(ENABLE_EL, boolean.class, false);\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    Set<ConstraintViolation<Object>> violations = doValidate(invocation);\n    if (violations.size() > 0) {\n      LOGGER.error(\"Parameter validation failed : \" + violations);\n      return AsyncUtils.completeExceptionally(new ConstraintViolationException(violations));\n    }\n\n    return nextNode.onFilter(invocation);\n  }\n\n  protected Set<ConstraintViolation<Object>> doValidate(Invocation invocation) {\n    SwaggerProducerOperation producerOperation = invocation.getOperationMeta().getSwaggerProducerOperation();\n    return validator.validateParameters(producerOperation.getProducerInstance(), producerOperation.getProducerMethod(),\n        invocation.toProducerArguments(), Default.class);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/ProviderOperationFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter.impl;\n\nimport java.lang.reflect.Method;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ProviderOperationFilter extends AbstractFilter implements ProviderFilter {\n  public static final String NAME = \"producer-operation\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    // almost time, should be the last filter.\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER + 2000;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (!transportAccessAllowed(invocation)) {\n      return CompletableFuture.failedFuture(new InvocationException(Status.UNAUTHORIZED,\n          new CommonExceptionData(\"transport access not allowed.\")));\n    }\n    invocation.onBusinessMethodStart();\n\n    SwaggerProducerOperation producerOperation = invocation.getOperationMeta().getSwaggerProducerOperation();\n    Object instance = producerOperation.getProducerInstance();\n    Method method = producerOperation.getProducerMethod();\n    Object[] args = invocation.toProducerArguments();\n    return invoke(invocation, instance, method, args)\n        .thenApply(result -> convertResultToResponse(invocation, producerOperation, result))\n        .whenComplete((response, throwable) -> processMetrics(invocation));\n  }\n\n  private boolean transportAccessAllowed(Invocation invocation) {\n    if (invocation.getProviderTransportName() == null) {\n      return true;\n    }\n    return invocation.getProviderTransportName().equals(invocation.getTransportName());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  protected CompletableFuture<Object> invoke(Invocation invocation, Object instance, Method method, Object[] args) {\n    ContextUtils.setInvocationContext(invocation);\n\n    try {\n      Object result = method.invoke(instance, args);\n      if (result instanceof CompletableFuture) {\n        return (CompletableFuture<Object>) result;\n      }\n\n      return CompletableFuture.completedFuture(result);\n    } catch (Throwable e) {\n      return AsyncUtils.completeExceptionally(Exceptions.unwrap(e));\n    } finally {\n      ContextUtils.removeInvocationContext();\n    }\n  }\n\n  protected Response convertResultToResponse(Invocation invocation, SwaggerProducerOperation producerOperation,\n      Object result) {\n    return producerOperation.getResponseMapper().mapResponse(invocation.getStatus(), result);\n  }\n\n  protected void processMetrics(Invocation invocation) {\n    invocation.onBusinessFinish();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/RetryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter.impl;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.governance.GovernanceConfiguration;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.core.governance.RetryContext;\nimport org.apache.servicecomb.governance.handler.RetryHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCompletionStage;\nimport io.github.resilience4j.retry.Retry;\n\npublic class RetryFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Object LOCK = new Object();\n\n  private static volatile ScheduledExecutorService reactiveRetryPool;\n\n  private static ScheduledExecutorService getOrCreateRetryPool() {\n    if (reactiveRetryPool == null) {\n      synchronized (LOCK) {\n        if (reactiveRetryPool == null) {\n          reactiveRetryPool = Executors.newScheduledThreadPool(2, new ThreadFactory() {\n            private final AtomicInteger count = new AtomicInteger(0);\n\n            @Override\n            public Thread newThread(Runnable r) {\n              Thread thread = new Thread(r, \"reactive-retry-pool-thread-\" + count.getAndIncrement());\n              // avoid block shutdown\n              thread.setDaemon(true);\n              return thread;\n            }\n          });\n        }\n      }\n    }\n    return reactiveRetryPool;\n  }\n\n  private final RetryHandler retryHandler;\n\n  @Autowired\n  public RetryFilter(RetryHandler retryHandler) {\n    this.retryHandler = retryHandler;\n  }\n\n  @Override\n  public String getName() {\n    return \"retry\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n    Retry retry = retryHandler.getActuator(request);\n    if (retry == null) {\n      return nextNode.onFilter(invocation);\n    }\n\n    Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation, nextNode);\n    DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);\n    dcs.withRetry(retry, getOrCreateRetryPool());\n    CompletableFuture<Response> future = new CompletableFuture<>();\n    dcs.get().whenComplete((r, e) -> {\n      if (e == null) {\n        future.complete(r);\n        return;\n      }\n\n      future.completeExceptionally(e);\n    });\n\n    return future;\n  }\n\n  private Supplier<CompletionStage<Response>> createBusinessCompletionStageSupplier(Invocation invocation,\n      FilterNode nextNode) {\n    return () -> {\n      updateRetryStatus(invocation);\n      return nextNode.onFilter(invocation);\n    };\n  }\n\n  private static void updateRetryStatus(Invocation invocation) {\n    if (invocation.getLocalContext(RetryContext.RETRY_CONTEXT) != null) {\n      if (invocation.getLocalContext(RetryContext.RETRY_LOAD_BALANCE) != null\n          && (boolean) invocation.getLocalContext(RetryContext.RETRY_LOAD_BALANCE)) {\n        // clear last server to avoid using user defined endpoint\n        invocation.setEndpoint(null);\n      }\n      RetryContext retryContext = invocation.getLocalContext(RetryContext.RETRY_CONTEXT);\n      retryContext.incrementRetry();\n      return;\n    }\n\n    invocation.addLocalContext(RetryContext.RETRY_CONTEXT,\n        new RetryContext(GovernanceConfiguration.getRetrySameServer(invocation.getMicroserviceName())));\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER - 1990;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/filter/impl/ScheduleFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.filter.impl;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.Executor;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.core.tracing.TraceIdLogger;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.MDC;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ScheduleFilter extends AbstractFilter implements ProviderFilter {\n  public static final String NAME = \"schedule\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode next) {\n    invocation.getInvocationStageTrace().startProviderQueue();\n    Executor executor = invocation.getOperationMeta().getExecutor();\n    return CompletableFuture.completedFuture(null)\n        .thenComposeAsync(response -> runInExecutor(invocation, next), executor);\n  }\n\n  protected CompletableFuture<Response> runInExecutor(Invocation invocation, FilterNode next) {\n    invocation.getInvocationStageTrace().finishProviderQueue();\n    MDC.put(TraceIdLogger.KEY_TRACE_ID, invocation.getTraceId());\n    checkInQueueTimeout(invocation);\n    return next.onFilter(invocation);\n  }\n\n  private void checkInQueueTimeout(Invocation invocation) {\n    long nanoTimeout = invocation.getOperationMeta().getConfig()\n        .getNanoRequestWaitInPoolTimeout(invocation.getTransport().getName());\n\n    if (invocation.getInvocationStageTrace().calcQueue() > nanoTimeout) {\n      throw new InvocationException(Status.REQUEST_TIMEOUT, \"Request in the queue timed out.\");\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/CoreGovernanceConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.governance;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class CoreGovernanceConfiguration {\n  @Bean\n  public ServiceCombCircuitBreakerExtension serviceCombCircuitBreakerExtension() {\n    return new ServiceCombCircuitBreakerExtension();\n  }\n\n  @Bean\n  public ServiceCombInstanceIsolationExtension serviceCombInstanceIsolationExtension() {\n    return new ServiceCombInstanceIsolationExtension();\n  }\n\n  @Bean\n  public ServiceCombMicroserviceMeta serviceCombMicroserviceMeta(SCBEngine scbEngine) {\n    return new ServiceCombMicroserviceMeta(scbEngine);\n  }\n\n  @Bean\n  public ServiceCombRetryExtension serviceCombRetryExtension() {\n    return new ServiceCombRetryExtension();\n  }\n\n  @Bean\n  public ServiceCombConfigurationEventAdapter serviceCombConfigurationEventAdapter() {\n    return new ServiceCombConfigurationEventAdapter();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/GovernanceConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.governance;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\n\npublic class GovernanceConfiguration {\n  public static final String ROOT = \"servicecomb.loadbalance.\";\n\n  // retry configurations\n  public static final String RETRY_ENABLED = \"retryEnabled\";\n\n  public static final String RETRY_ON_NEXT = \"retryOnNext\";\n\n  public static final String RETRY_ON_SAME = \"retryOnSame\";\n\n  public static boolean isRetryEnabled(String microservice) {\n    String p = getStringProperty(\"false\",\n        ROOT + microservice + \".\" + RETRY_ENABLED,\n        ROOT + RETRY_ENABLED);\n    return Boolean.parseBoolean(p);\n  }\n\n  public static int getRetryNextServer(String microservice) {\n    return getRetryServer(microservice, RETRY_ON_NEXT);\n  }\n\n  public static int getRetrySameServer(String microservice) {\n    return getRetryServer(microservice, RETRY_ON_SAME);\n  }\n\n  private static int getRetryServer(String microservice, String retryType) {\n    final int defaultValue = 0;\n    String p = getStringProperty(\"0\",\n        ROOT + microservice + \".\" + retryType,\n        ROOT + retryType);\n    try {\n      int result = Integer.parseInt(p);\n      if (result > 0) {\n        return result;\n      }\n      return defaultValue;\n    } catch (NumberFormatException e) {\n      return defaultValue;\n    }\n  }\n\n  public static String getStringProperty(String defaultValue, String... keys) {\n    String property;\n    for (String key : keys) {\n      property = LegacyPropertyFactory.getStringProperty(key);\n      if (property != null) {\n        return property;\n      }\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.governance;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\n\npublic final class MatchType {\n  private static class GovernanceRequestExtractorImpl implements GovernanceRequestExtractor {\n    private final Invocation invocation;\n\n    private GovernanceRequestExtractorImpl(Invocation invocation) {\n      this.invocation = invocation;\n    }\n\n    @Override\n    public String apiPath() {\n      if (MatchType.REST.equalsIgnoreCase(invocation.getOperationMeta().getConfig().getGovernanceMatchType())) {\n        if (!invocation.isProducer()) {\n          return SwaggerUtils.concatAbsolutePath(invocation.getSchemaMeta().getSwagger(),\n              invocation.getOperationMeta().getOperationPath());\n        }\n        // not highway\n        if (invocation.getRequestEx() != null) {\n          return invocation.getRequestEx().getRequestURI();\n        }\n      }\n\n      if (!invocation.isProducer()) {\n        return invocation.getOperationMeta().getMicroserviceQualifiedName();\n      }\n      return invocation.getOperationMeta().getSchemaQualifiedName();\n    }\n\n    @Override\n    public String method() {\n      return invocation.getOperationMeta().getHttpMethod();\n    }\n\n    @Override\n    public String header(String key) {\n      Map<String, Object> arguments = invocation.getSwaggerArguments();\n      if (arguments != null && arguments.get(key) != null) {\n        return arguments.get(key).toString();\n      }\n\n      if (invocation.getContext(key) != null) {\n        return invocation.getContext(key);\n      }\n\n      if (invocation.getRequestEx() != null) {\n        return invocation.getRequestEx().getHeader(key);\n      }\n\n      return null;\n    }\n\n    @Override\n    public String query(String key) {\n      HttpServletRequestEx requestEx = invocation.getRequestEx();\n      if (requestEx == null) {\n        return null;\n      }\n      return requestEx.getParameter(key);\n    }\n\n    @Override\n    public String instanceId() {\n      if (!invocation.isProducer()) {\n        if (invocation.getEndpoint() != null && invocation.getEndpoint().getMicroserviceInstance() != null) {\n          return invocation.getEndpoint().getMicroserviceInstance().getInstanceId();\n        }\n      }\n      return null;\n    }\n\n    @Override\n    public String serviceName() {\n      if (!invocation.isProducer()) {\n        return invocation.getMicroserviceName();\n      }\n      return null;\n    }\n\n    @Override\n    public Object sourceRequest() {\n      return invocation;\n    }\n  }\n\n  public static final String REST = \"rest\";\n\n  public static final String RPC = \"rpc\";\n\n  public static GovernanceRequestExtractor createGovHttpRequest(Invocation invocation) {\n    return new GovernanceRequestExtractorImpl(invocation);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/RetryContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.governance;\n\npublic class RetryContext {\n  public static final String RETRY_CONTEXT = \"x-context-retry\";\n\n  // weather need reset Endpoint in retry\n  public static final String RETRY_LOAD_BALANCE = \"x-context-retry-loadbalance\";\n\n  private boolean retry;\n\n  private int triedCount;\n\n  private final int retryOnSame;\n\n  public RetryContext(int retryOnSame) {\n    this.retryOnSame = retryOnSame;\n    this.retry = false;\n    this.triedCount = 0;\n  }\n\n  public boolean isRetry() {\n    return retry;\n  }\n\n  public void incrementRetry() {\n    this.retry = true;\n    this.triedCount++;\n  }\n\n  public boolean trySameServer() {\n    return triedCount <= retryOnSame;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/ServiceCombCircuitBreakerExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.governance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractCircuitBreakerExtension;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\npublic class ServiceCombCircuitBreakerExtension extends AbstractCircuitBreakerExtension {\n  @Override\n  protected String extractStatusCode(Object result) {\n    if (!(result instanceof Response)) {\n      return null;\n    }\n    Response resp = (Response) result;\n    if (resp.isFailed()) {\n      if (resp.getResult() instanceof InvocationException) {\n        InvocationException e = resp.getResult();\n        return String.valueOf(e.getStatusCode());\n      }\n    }\n    return String.valueOf(resp.getStatusCode());\n  }\n\n  @Override\n  public boolean isFailedResult(List<String> statusList, Throwable e) {\n    if (e instanceof InvocationException) {\n      InvocationException invocationException = (InvocationException) e;\n      return statusList.contains(String.valueOf(invocationException.getStatusCode()));\n    }\n    return super.isFailedResult(statusList, e);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/ServiceCombConfigurationEventAdapter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.governance;\n\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic class ServiceCombConfigurationEventAdapter {\n  public ServiceCombConfigurationEventAdapter() {\n    EventManager.register(this);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    GovernanceConfigurationChangedEvent newEvent = new GovernanceConfigurationChangedEvent(event.getChanged());\n    GovernanceEventManager.post(newEvent);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/ServiceCombInstanceIsolationExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.governance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractInstanceIsolationExtension;\n\npublic class ServiceCombInstanceIsolationExtension extends AbstractInstanceIsolationExtension {\n  private final ServiceCombRetryExtension retryExtension = new ServiceCombRetryExtension();\n\n  @Override\n  protected String extractStatusCode(Object result) {\n    return retryExtension.extractStatusCode(result);\n  }\n\n  @Override\n  public boolean isFailedResult(List<String> statusList, Throwable e) {\n    return retryExtension.isFailedResult(statusList, e);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/ServiceCombMicroserviceMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.governance;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.governance.MicroserviceMeta;\n\npublic class ServiceCombMicroserviceMeta implements MicroserviceMeta {\n  private SCBEngine scbEngine;\n\n  public ServiceCombMicroserviceMeta(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  @Override\n  public String getName() {\n    return BootStrapProperties.readServiceName(scbEngine.getEnvironment());\n  }\n\n  @Override\n  public String getVersion() {\n    return BootStrapProperties.readServiceVersion(scbEngine.getEnvironment());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/governance/ServiceCombRetryExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.governance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractRetryExtension;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\npublic class ServiceCombRetryExtension extends AbstractRetryExtension {\n  @Override\n  protected String extractStatusCode(Object result) {\n    if (!(result instanceof Response)) {\n      return null;\n    }\n    Response resp = (Response) result;\n    if (resp.isFailed()) {\n      if (resp.getResult() instanceof InvocationException) {\n        InvocationException e = resp.getResult();\n        return String.valueOf(e.getStatusCode());\n      }\n    }\n    return String.valueOf(resp.getStatusCode());\n  }\n\n  @Override\n  public boolean isFailedResult(List<String> statusList, Throwable e) {\n    if (e instanceof InvocationException) {\n      InvocationException invocationException = (InvocationException) e;\n      return statusList.contains(String.valueOf(invocationException.getStatusCode()));\n    }\n    return super.isFailedResult(statusList, e);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/CoreInvocationConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.invocation.timeout.PassingTimeStrategy;\nimport org.apache.servicecomb.core.invocation.timeout.ProcessingTimeStrategy;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\n@Configuration\npublic class CoreInvocationConfiguration {\n  @Bean\n  public InvocationTimeoutBootListener scbInvocationTimeoutBootListener(EventBus eventBus,\n      List<InvocationTimeoutStrategy> strategies,\n      Environment environment) {\n    return new InvocationTimeoutBootListener(eventBus, strategies, environment);\n  }\n\n  @Bean\n  public PassingTimeStrategy scbPassingTimeStrategy() {\n    return new PassingTimeStrategy();\n  }\n\n  @Bean\n  public ProcessingTimeStrategy scbProcessingTimeStrategy() {\n    return new ProcessingTimeStrategy();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/InvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic interface InvocationCreator {\n  CompletableFuture<Invocation> createAsync();\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/InvocationFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\n\npublic final class InvocationFactory {\n  private InvocationFactory() {\n  }\n\n  public static Invocation forConsumer(ReferenceConfig referenceConfig, OperationMeta operationMeta,\n      InvocationRuntimeType invocationRuntimeType, Map<String, Object> swaggerArguments) {\n    Invocation invocation = new Invocation(referenceConfig,\n        operationMeta,\n        invocationRuntimeType,\n        swaggerArguments);\n    return setSrcMicroservice(invocation);\n  }\n\n  public static Invocation setSrcMicroservice(Invocation invocation) {\n    invocation.addContext(CoreConst.SRC_MICROSERVICE,\n        BootStrapProperties.readServiceName(SCBEngine.getInstance().getEnvironment()));\n    // TODO: hard code registry name here. This is an old feature not for all registry implementations.\n    if (addSourceServiceId()) {\n      invocation.addContext(CoreConst.SRC_SERVICE_ID,\n          SCBEngine.getInstance().getRegistrationManager().getServiceId(\"sc-registration\"));\n    }\n    if (addSourceInstanceId()) {\n      invocation.addContext(CoreConst.SRC_INSTANCE_ID,\n          SCBEngine.getInstance().getRegistrationManager().getInstanceId(\"sc-registration\"));\n    }\n    return invocation;\n  }\n\n  public static boolean addSourceServiceId() {\n    return SCBEngine.getInstance().getEnvironment().\n        getProperty(\"servicecomb.context.source.serviceId\", boolean.class, true);\n  }\n\n  public static boolean addSourceInstanceId() {\n    return SCBEngine.getInstance().getEnvironment().\n        getProperty(\"servicecomb.context.source.instanceId\", boolean.class, true);\n  }\n\n  /*\n   * transport server收到请求时，创建invocation\n   */\n  public static Invocation forProvider(Endpoint endpoint,\n      OperationMeta operationMeta,\n      Map<String, Object> swaggerArguments) {\n    SCBEngine.getInstance().ensureStatusUp();\n    return new Invocation(endpoint,\n        operationMeta,\n        swaggerArguments);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n * <pre>\n * for consumer:\n *\n *  1. total: start create invocation -> all filters finished\n *  2. prepare: start create invocation -> finish create invocation\n *  3. filters-(filter-name): start call on filter -> on complete\n *  4. connection: start get connection -> finish get connection\n *  5. consumer-encode: start encode request -> finish encode request\n *  6. consumer-decode: start decode response -> finish decode response\n *  7. consumer-send: start send request -> finish send request\n *  8. wait: finish send request -> start decode response\n *\n * for provider:\n *  1. total: start create invocation -> all filters finished\n *  2. prepare: start create invocation -> finish create invocation\n *  3. filters-(filter-name): start call on filter -> on complete\n *  4. queue: add in queue -> execute in thread\n *  5. provider-decode: start decode request -> finish decode request\n *  6. provider-encode: start encode response -> finish encode response\n *  7. provider-send: start send response -> finish send response\n *  8. execute: start business execute -> finish business execute\n *\n * for edge:\n *\n *  *  1. total: start create invocation -> all filters finished\n *  *  2. prepare: start create invocation -> finish create invocation\n *  *  3. filters-(filter-name): start call on filter -> on complete\n *  *  4. connection: start get connection -> finish get connection\n *  *  5. provider-decode: start decode request -> finish decode request\n *  *  6. provider-encode: start encode response -> finish encode response\n *  *  7. consumer-encode: start encode request -> finish encode request\n *  *  8. consumer-decode: start decode response -> finish decode response\n *  *  9. consumer-send: start send request -> finish send request\n *  *  10. provider-send: start send response -> finish send response\n *  *  11. wait: finish send request -> start decode response\n *\n * </pre>\n */\npublic class InvocationStageTrace {\n  public static class Stage {\n    private long beginTime;\n\n    private long endTime;\n\n    public long getBeginTime() {\n      return beginTime;\n    }\n\n    public long getEndTime() {\n      return endTime;\n    }\n  }\n\n  public static final String STAGE_TOTAL = \"total\";\n\n  public static final String STAGE_PREPARE = \"prepare\";\n\n  public static final String STAGE_PROVIDER_QUEUE = \"queue\";\n\n  public static final String STAGE_PROVIDER_DECODE_REQUEST = \"provider-decode\";\n\n  public static final String STAGE_PROVIDER_ENCODE_RESPONSE = \"provider-encode\";\n\n  public static final String STAGE_PROVIDER_SEND = \"provider-send\";\n\n  public static final String STAGE_PROVIDER_BUSINESS = \"execute\";\n\n  public static final String STAGE_CONSUMER_CONNECTION = \"connection\";\n\n  public static final String STAGE_CONSUMER_ENCODE_REQUEST = \"consumer-encode\";\n\n  public static final String STAGE_CONSUMER_DECODE_RESPONSE = \"consumer-decode\";\n\n  public static final String STAGE_CONSUMER_SEND = \"consumer-send\";\n\n  public static final String STAGE_CONSUMER_WAIT = \"wait\";\n\n  private final Invocation invocation;\n\n  // invocation start time in millis, for passing strategy use only\n  private long startInMillis;\n\n  // invocation start time in nanos, for passing strategy use only\n  private long start;\n\n  private long finish;\n\n  private long startCreateInvocation;\n\n  private long finishCreateInvocation;\n\n  private long startProviderQueue;\n\n  private long finishProviderQueue;\n\n  private long startConsumerConnection;\n\n  private long finishConsumerConnection;\n\n  private long startProviderDecodeRequest;\n\n  private long finishProviderDecodeRequest;\n\n  private long startProviderEncodeResponse;\n\n  private long finishProviderEncodeResponse;\n\n  private long startConsumerEncodeRequest;\n\n  private long finishConsumerEncodeRequest;\n\n  private long startConsumerDecodeResponse;\n\n  private long finishConsumerDecodeResponse;\n\n  private long startProviderSendResponse;\n\n  private long finishProviderSendResponse;\n\n  private long startConsumerSendRequest;\n\n  private long finishConsumerSendRequest;\n\n  private long startBusinessExecute;\n\n  private long finishBusinessExecute;\n\n  private long startWaitResponse;\n\n  private long finishWaitResponse;\n\n  // invocation stage can not be used in concurrent access\n  private final Map<String, Stage> stages = new HashMap<>();\n\n  public InvocationStageTrace(Invocation invocation) {\n    this.invocation = invocation;\n  }\n\n  public String recordStageBegin(String stageName) {\n    String realStageName = stageName;\n    while (stages.get(realStageName) != null) {\n      realStageName = realStageName + \"@\";\n    }\n    Stage stage = new Stage();\n    stage.beginTime = System.nanoTime();\n    stages.put(realStageName, stage);\n    return realStageName;\n  }\n\n  public void recordStageEnd(String realStageName) {\n    Stage stage = stages.get(realStageName);\n    stage.endTime = nanoTime();\n  }\n\n  public Map<String, Stage> getStages() {\n    return stages;\n  }\n\n  public void finish() {\n    this.finish = nanoTime();\n  }\n\n  public void startCreateInvocation(long nano) {\n    this.startCreateInvocation = nano;\n    this.startInMillis = millisTime();\n    this.start = nanoTime();\n  }\n\n  public void finishCreateInvocation() {\n    this.finishCreateInvocation = nanoTime();\n  }\n\n  public long calcPrepare() {\n    return calc(finishCreateInvocation, startCreateInvocation);\n  }\n\n  public void startProviderQueue() {\n    this.startProviderQueue = nanoTime();\n  }\n\n  public void finishProviderQueue() {\n    this.finishProviderQueue = nanoTime();\n  }\n\n  public long calcQueue() {\n    return calc(finishProviderQueue, startProviderQueue);\n  }\n\n  public void startProviderDecodeRequest() {\n    this.startProviderDecodeRequest = nanoTime();\n  }\n\n  public void finishProviderDecodeRequest() {\n    this.finishProviderDecodeRequest = nanoTime();\n  }\n\n  public long calcProviderDecodeRequest() {\n    return calc(finishProviderDecodeRequest, startProviderDecodeRequest);\n  }\n\n  public void startProviderEncodeResponse() {\n    this.startProviderEncodeResponse = nanoTime();\n  }\n\n  public void finishProviderEncodeResponse() {\n    this.finishProviderEncodeResponse = nanoTime();\n  }\n\n  public long calcProviderEncodeResponse() {\n    return calc(finishProviderEncodeResponse, startProviderEncodeResponse);\n  }\n\n  public void startConsumerEncodeRequest() {\n    this.startConsumerEncodeRequest = nanoTime();\n  }\n\n  public void finishConsumerEncodeRequest() {\n    this.finishConsumerEncodeRequest = nanoTime();\n  }\n\n  public long calcConsumerEncodeRequest() {\n    return calc(finishConsumerEncodeRequest, startConsumerEncodeRequest);\n  }\n\n  public void startConsumerDecodeResponse() {\n    this.startConsumerDecodeResponse = nanoTime();\n  }\n\n  public void finishConsumerDecodeResponse() {\n    this.finishConsumerDecodeResponse = nanoTime();\n  }\n\n  public long calcConsumerDecodeResponse() {\n    return calc(finishConsumerDecodeResponse, startConsumerDecodeResponse);\n  }\n\n  public void startProviderSendResponse() {\n    this.startProviderSendResponse = nanoTime();\n  }\n\n  public void finishProviderSendResponse() {\n    this.finishProviderSendResponse = nanoTime();\n  }\n\n  public long calcProviderSendResponse() {\n    return calc(finishProviderSendResponse, startProviderSendResponse);\n  }\n\n  public void startBusinessExecute() {\n    this.startBusinessExecute = nanoTime();\n  }\n\n  public void finishBusinessExecute() {\n    this.finishBusinessExecute = nanoTime();\n  }\n\n  public long calcBusinessExecute() {\n    return calc(finishBusinessExecute, startBusinessExecute);\n  }\n\n  public void startConsumerConnection() {\n    this.startConsumerConnection = nanoTime();\n  }\n\n  public void finishConsumerConnection() {\n    this.finishConsumerConnection = nanoTime();\n  }\n\n  public long calcConnection() {\n    return calc(finishConsumerConnection, startConsumerConnection);\n  }\n\n  public void startConsumerSendRequest() {\n    this.startConsumerSendRequest = nanoTime();\n  }\n\n  public void finishConsumerSendRequest() {\n    this.finishConsumerSendRequest = nanoTime();\n  }\n\n  public long calcConsumerSendRequest() {\n    return calc(finishConsumerSendRequest, startConsumerSendRequest);\n  }\n\n  public void startWaitResponse() {\n    this.startWaitResponse = nanoTime();\n  }\n\n  public void finishWaitResponse() {\n    this.finishWaitResponse = nanoTime();\n  }\n\n  public long calcWait() {\n    return calc(finishWaitResponse, startWaitResponse);\n  }\n\n  public long calcTotal() {\n    return calc(finish, this.startCreateInvocation);\n  }\n\n  public long getStartInMillis() {\n    return this.startInMillis;\n  }\n\n  public long getStart() {\n    return this.start;\n  }\n\n  public static long calc(long finish, long start) {\n    if (finish == 0 || start == 0) {\n      return 0;\n    }\n\n    return finish - start;\n  }\n\n  /*\n   * Holder for testing purpose\n   */\n  protected long nanoTime() {\n    return System.nanoTime();\n  }\n\n  protected long millisTime() {\n    return System.currentTimeMillis();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/InvocationTimeoutBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.event.InvocationBusinessFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationBusinessMethodStartEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.core.event.InvocationStartSendRequestEvent;\nimport org.apache.servicecomb.core.event.InvocationTimeoutCheckEvent;\nimport org.apache.servicecomb.core.invocation.timeout.PassingTimeStrategy;\nimport org.apache.servicecomb.foundation.common.event.EnableExceptionPropagation;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\n@SuppressWarnings({\"unused\"})\npublic final class InvocationTimeoutBootListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(InvocationTimeoutBootListener.class);\n\n  public static final String PREFIX = \"servicecomb.invocation.timeout.check\";\n\n  public static final String STRATEGY = PREFIX + \".strategy\";\n\n  public static final String ENABLED = PREFIX + \".enabled\";\n\n  private final InvocationTimeoutStrategy strategy;\n\n  public InvocationTimeoutBootListener(EventBus eventBus, List<InvocationTimeoutStrategy> strategies,\n      Environment environment) {\n    if (!environment.getProperty(ENABLED, boolean.class, false)) {\n      strategy = null;\n      return;\n    }\n\n    String strategyName = environment.getProperty(STRATEGY, PassingTimeStrategy.NAME);\n    // if strategyName is wrong, then just throw exception\n    strategy = strategies.stream()\n        .filter(invocationTimeoutStrategy -> strategyName.equals(invocationTimeoutStrategy.name()))\n        .findFirst()\n        .orElseThrow(() -> new IllegalStateException(\"can not find InvocationTimeoutStrategy, name=\" + strategyName));\n    eventBus.register(this);\n  }\n\n  @Subscribe\n  @EnableExceptionPropagation\n  public void onInvocationTimeoutCheckEvent(InvocationTimeoutCheckEvent event) {\n    strategy.checkTimeout(event.getInvocation());\n  }\n\n  @Subscribe\n  public void onInvocationStartEvent(InvocationStartEvent event) {\n    strategy.start(event.getInvocation());\n  }\n\n  @Subscribe\n  @EnableExceptionPropagation\n  public void onInvocationBusinessMethodStartEvent(InvocationBusinessMethodStartEvent event) {\n    strategy.startBusinessMethod(event.getInvocation());\n  }\n\n  @Subscribe\n  @EnableExceptionPropagation\n  public void onInvocationBusinessFinishEvent(InvocationBusinessFinishEvent event) {\n    strategy.finishBusinessMethod(event.getInvocation());\n  }\n\n  @Subscribe\n  @EnableExceptionPropagation\n  public void onInvocationStartSendRequestEvent(InvocationStartSendRequestEvent event) {\n    strategy.beforeSendRequest(event.getInvocation());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/InvocationTimeoutStrategy.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.invocation;\r\n\r\nimport static jakarta.ws.rs.core.Response.Status.REQUEST_TIMEOUT;\r\n\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.core.exception.ExceptionCodes;\r\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\r\n\r\npublic interface InvocationTimeoutStrategy {\r\n  // indicate whether invocation already timeout inside a process\r\n  // null is not timeout\r\n  // other value is timeout\r\n  String CHAIN_ALREADY_TIMED_OUT = \"x-scb-chain-timed-out\";\r\n\r\n  String name();\r\n\r\n  void start(Invocation invocation);\r\n\r\n  default void startRunInExecutor(Invocation invocation) {\r\n    checkTimeout(invocation);\r\n  }\r\n\r\n  default void startBusinessMethod(Invocation invocation) {\r\n    checkTimeout(invocation);\r\n  }\r\n\r\n  default void finishBusinessMethod(Invocation invocation) {\r\n    checkTimeout(invocation);\r\n  }\r\n\r\n  default void beforeSendRequest(Invocation invocation) {\r\n    checkTimeout(invocation);\r\n  }\r\n\r\n  default void checkTimeout(Invocation invocation) {\r\n    long nanoInvocationTimeout = invocation.getOperationMeta().getConfig().getNanoInvocationTimeout();\r\n    if (nanoInvocationTimeout <= 0 || alreadyTimeout(invocation)) {\r\n      return;\r\n    }\r\n\r\n    long nanoTime = calculateElapsedNanoTime(invocation);\r\n    if (nanoTime <= nanoInvocationTimeout) {\r\n      return;\r\n    }\r\n\r\n    invocation.addLocalContext(CHAIN_ALREADY_TIMED_OUT, true);\r\n    throw new InvocationException(REQUEST_TIMEOUT, ExceptionCodes.INVOCATION_TIMEOUT, \"Invocation Timeout.\");\r\n  }\r\n\r\n  default boolean alreadyTimeout(Invocation invocation) {\r\n    return invocation.getLocalContext(CHAIN_ALREADY_TIMED_OUT) != null;\r\n  }\r\n\r\n  long calculateElapsedNanoTime(Invocation invocation);\r\n}\r\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/ProducerInvocationFlow.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic abstract class ProducerInvocationFlow {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProducerInvocationFlow.class);\n\n  private final long startTime = System.nanoTime();\n\n  private final InvocationCreator invocationCreator;\n\n  protected final HttpServletRequestEx requestEx;\n\n  protected final HttpServletResponseEx responseEx;\n\n  public ProducerInvocationFlow(InvocationCreator invocationCreator) {\n    this(invocationCreator, null, null);\n  }\n\n  public ProducerInvocationFlow(InvocationCreator invocationCreator,\n      HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {\n    this.invocationCreator = invocationCreator;\n    this.requestEx = requestEx;\n    this.responseEx = responseEx;\n  }\n\n  public void run() {\n    CompletableFuture.completedFuture(null)\n        .thenCompose(v -> invocationCreator.createAsync())\n        .exceptionally(this::sendCreateInvocationException)\n        .thenAccept(this::tryRunInvocation);\n  }\n\n  private void tryRunInvocation(Invocation invocation) {\n    if (invocation == null) {\n      return;\n    }\n    invocation.getInvocationStageTrace().startCreateInvocation(this.startTime);\n    invocation.getInvocationStageTrace().finishCreateInvocation();\n    invocation.onStart(requestEx);\n    if (invocation.isEdge()) {\n      invocation.getMicroserviceMeta().getEdgeFilterChain()\n          .onFilter(invocation)\n          .whenComplete((response, throwable) -> {\n            if (throwable != null) {\n              // Server codec operates on Response. So the filter chain result should be Response and\n              // will never throw exception.\n              // Sometimes Server Codec will throw exception, e.g. Connection Closed.\n              LOGGER.error(\"Maybe a fatal bug that should be addressed or codec exception for {}.\",\n                  invocation.getInvocationQualifiedName(), throwable);\n              response = Response.createFail(new InvocationException(Status.INTERNAL_SERVER_ERROR,\n                  new CommonExceptionData(\"Internal error, check logs for details.\")));\n            }\n            endResponse(invocation, response);\n            finishInvocation(invocation, response);\n          });\n      return;\n    }\n    invocation.getMicroserviceMeta().getProviderFilterChain()\n        .onFilter(invocation)\n        .whenComplete((response, throwable) -> {\n          if (throwable != null) {\n            // Server codec operates on Response. So the filter chain result should be Response and\n            // will never throw exception.\n            // Sometimes Server Codec will throw exception, e.g. Connection Closed.\n            LOGGER.error(\"Maybe a fatal bug that should be addressed or codec exception for {}.\",\n                invocation.getInvocationQualifiedName(), throwable);\n            response = Response.createFail(new InvocationException(Status.INTERNAL_SERVER_ERROR,\n                new CommonExceptionData(\"Internal error, check logs for details.\")));\n          }\n          endResponse(invocation, response);\n          finishInvocation(invocation, response);\n        });\n  }\n\n  private void finishInvocation(Invocation invocation, Response response) {\n    invocation.onFinish(response);\n  }\n\n  protected abstract Invocation sendCreateInvocationException(Throwable throwable);\n\n  protected abstract void endResponse(Invocation invocation, Response response);\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointCacheUtils.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.invocation.endpoint;\r\n\r\nimport org.apache.servicecomb.core.Endpoint;\r\n\r\nimport com.google.common.cache.CacheBuilder;\r\nimport com.google.common.cache.CacheLoader;\r\nimport com.google.common.cache.LoadingCache;\r\n\r\npublic final class EndpointCacheUtils {\r\n  private static final LoadingCache<String, Endpoint> CACHE = CacheBuilder.newBuilder()\r\n      .maximumSize(10000)\r\n      .build(new CacheLoader<String, Endpoint>() {\r\n        @Override\r\n        public Endpoint load(String uri) {\r\n          return EndpointCacheUtils.create(uri);\r\n        }\r\n      });\r\n\r\n  /**\r\n   * @param uri https://www.abc.com:12345\r\n   * @return endpoint\r\n   */\r\n  public static Endpoint getOrCreate(String uri) {\r\n    return CACHE.getUnchecked(uri);\r\n  }\r\n\r\n  public static Endpoint create(String uri) {\r\n    return EndpointUtils.parse(EndpointUtils.formatFromUri(uri));\r\n  }\r\n}\r\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointContextRegister.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation.endpoint;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.swagger.generator.SwaggerContextRegister;\n\npublic class EndpointContextRegister implements SwaggerContextRegister {\n  @Override\n  public Type getContextType() {\n    return Endpoint.class;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation.endpoint;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgumentMapper;\n\npublic class EndpointMapper extends ConsumerArgumentMapper {\n  private final String invocationArgumentName;\n\n  public EndpointMapper(String invocationArgumentName) {\n    this.invocationArgumentName = invocationArgumentName;\n  }\n\n  @Override\n  public void invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> swaggerArguments, Map<String, Object> invocationArguments) {\n    Invocation invocation = (Invocation) swaggerInvocation;\n    invocation.setEndpoint((Endpoint) invocationArguments.get(invocationArgumentName));\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation.endpoint;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerContextArgumentMapperFactory;\n\npublic class EndpointMapperFactory implements ConsumerContextArgumentMapperFactory {\n  @Override\n  public Class<?> getContextClass() {\n    return Endpoint.class;\n  }\n\n  @Override\n  public ArgumentMapper create(String invocationArgumentName, String swaggerArgumentName) {\n    return new EndpointMapper(invocationArgumentName);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation.endpoint;\n\nimport static com.google.common.collect.ImmutableMap.of;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.Map;\n\nimport org.apache.http.client.utils.URIBuilder;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class EndpointUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EndpointUtils.class);\n\n  private static final String HTTP = \"http\";\n\n  private static final String HTTPS = \"https\";\n\n  private static final String H2C = \"h2c\";\n\n  private static final String H2 = \"h2\";\n\n  private static final String HTTP2 = \"http2\";\n\n  private static final int DEFAULT_HTTP_PORT = 80;\n\n  private static final int DEFAULT_HTTPS_PORT = 443;\n\n  private static class SchemeMeta {\n    String protocol;\n\n    boolean ssl;\n\n    int defaultPort;\n\n    public SchemeMeta(String protocol, boolean ssl, int defaultPort) {\n      this.protocol = protocol;\n      this.ssl = ssl;\n      this.defaultPort = defaultPort;\n    }\n  }\n\n  private static final Map<String, SchemeMeta> SCHEME_META_MAP = of(\n      HTTP, new SchemeMeta(null, false, DEFAULT_HTTP_PORT),\n      HTTPS, new SchemeMeta(null, true, DEFAULT_HTTPS_PORT),\n      H2C, new SchemeMeta(HTTP2, false, DEFAULT_HTTP_PORT),\n      H2, new SchemeMeta(HTTP2, true, DEFAULT_HTTPS_PORT)\n  );\n\n  private EndpointUtils() {\n  }\n\n  /**\n   *\n   * @param uriEndpoint eg: rest://xxx?sslEnabled=true\n   * @return Endpoint object\n   */\n  public static Endpoint parse(String uriEndpoint) {\n    URI uri = URI.create(uriEndpoint);\n    Transport transport = SCBEngine.getInstance().getTransportManager().findTransport(uri.getScheme());\n    if (transport == null) {\n      LOGGER.error(\"not deployed transport, uri={}.\", uriEndpoint);\n      throw Exceptions.genericConsumer(\"the endpoint's transport is not found.\");\n    }\n\n    return new Endpoint(transport, uriEndpoint);\n  }\n\n  /**\n   * {@code\n   *   http://xxx  -> rest://xxx\n   *   https://xxx -> rest://xxx?sslEnabled=true\n   *\n   *   h2c://xxx   -> rest://xxx?protocol=http2\n   *   h2://xxx    -> rest://xxx?sslEnabled=true&protocol=http2\n   *\n   *   xxx         -> rest://xxx:port?protocol=http2\n   *   xxx?a=a1    -> rest://xxx:port?a=a1&protocol=http2\n   *   other://xxx -> other://xxx\n   * }\n   *\n   *  This method provided for convenience of handling user input endpoints, and do not have a strict meaning. Make sure all unit test cases\n   *  work before change.\n   **/\n  public static String formatFromUri(String inputUri) {\n    try {\n      return doFormatFromUri(inputUri);\n    } catch (URISyntaxException e) {\n      throw new IllegalStateException(\"failed to convert uri to endpoint.\", e);\n    }\n  }\n\n  private static String doFormatFromUri(String inputUri) throws URISyntaxException {\n    URIBuilder builder = new URIBuilder(inputUri);\n    if (builder.getScheme() == null) {\n      builder.setScheme(H2C);\n      builder.setHost(extractHostFromPath(builder));\n      builder.setPath(null);\n    }\n\n    SchemeMeta schemeMeta = SCHEME_META_MAP.get(builder.getScheme());\n    if (schemeMeta == null) {\n      return inputUri;\n    }\n\n    return format(builder, schemeMeta);\n  }\n\n  private static String extractHostFromPath(URIBuilder builder) {\n    String path = builder.getPath();\n    if (path == null) {\n      return null;\n    }\n    if (path.startsWith(\"/\")) {\n      path = path.substring(1);\n    }\n    if (path.contains(\"/\")) {\n      path = path.substring(0, path.indexOf(\"/\"));\n    }\n    return path;\n  }\n\n  private static String format(URIBuilder builder, SchemeMeta schemeMeta) throws URISyntaxException {\n    if (schemeMeta.ssl) {\n      builder.addParameter(\"sslEnabled\", \"true\");\n    }\n    if (schemeMeta.protocol != null) {\n      builder.addParameter(\"protocol\", schemeMeta.protocol);\n    }\n    if (builder.getPort() == -1) {\n      builder.setPort(schemeMeta.defaultPort);\n    }\n\n    return builder.setScheme(\"rest\").build().toString();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/timeout/PassingTimeStrategy.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.invocation.timeout;\r\n\r\nimport java.time.Clock;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\nimport org.apache.commons.lang3.StringUtils;\r\nimport org.apache.commons.lang3.math.NumberUtils;\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.core.invocation.InvocationTimeoutStrategy;\r\n\r\n/**\r\n * <pre>\r\n * based on time synchronization\r\n * any time to calculate timeout: now - start time of invocation chain\r\n *\r\n * consumer: c\r\n * producer: p\r\n * ---------------------------------------------------------------\r\n * | process 2                                                   |\r\n * |                 c-send(T5)                       c-send(T8) |\r\n * |                    ↑                               ↑      |\r\n * | p-start(T3) → c-start(T4) → p-operation(T6) → c-start(T7)|\r\n * -----↑--------------------------------------------------------\r\n *      ↑\r\n * -----↑-----------------\r\n * |    ↑     process 1  |\r\n * |  c-send(T2)          |\r\n * |    ↑                |\r\n * |  c-start(T1)         |\r\n * ------------------------\r\n *\r\n * T2 timeout: T2 - T1\r\n * T3 timeout: T3 - T1\r\n * T4 timeout: T4 - T1\r\n * ......\r\n * </pre>\r\n */\r\npublic class PassingTimeStrategy implements InvocationTimeoutStrategy {\r\n  public static final String NAME = \"passing-time\";\r\n\r\n  // milliseconds\r\n  // depend on time synchronization\r\n  // transfer between processes\r\n  public static final String CHAIN_START_TIME = \"x-scb-chain-start\";\r\n\r\n  private Clock clock = Clock.systemDefaultZone();\r\n\r\n  public PassingTimeStrategy setClock(Clock clock) {\r\n    this.clock = clock;\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public String name() {\r\n    return NAME;\r\n  }\r\n\r\n  @Override\r\n  public void start(Invocation invocation) {\r\n    if (invocation.getLocalContext(CHAIN_START_TIME) != null) {\r\n      return;\r\n    }\r\n\r\n    long startTimeMillis = invocation.getInvocationStageTrace().getStartInMillis();\r\n    String contextChainStartTime = invocation.getContext(CHAIN_START_TIME);\r\n    if (StringUtils.isEmpty(contextChainStartTime)) {\r\n      invocation.addContext(CHAIN_START_TIME, String.valueOf(startTimeMillis));\r\n      invocation.addLocalContext(CHAIN_START_TIME, startTimeMillis);\r\n      return;\r\n    }\r\n\r\n    long chainStartTime = NumberUtils.toLong(contextChainStartTime, startTimeMillis);\r\n    invocation.addLocalContext(CHAIN_START_TIME, chainStartTime);\r\n  }\r\n\r\n  @Override\r\n  public long calculateElapsedNanoTime(Invocation invocation) {\r\n    long passingTimeMillis = clock.millis() - invocation.<Long>getLocalContext(CHAIN_START_TIME);\r\n    return TimeUnit.MILLISECONDS.toNanos(passingTimeMillis);\r\n  }\r\n}\r\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/invocation/timeout/ProcessingTimeStrategy.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.invocation.timeout;\r\n\r\nimport org.apache.commons.lang3.math.NumberUtils;\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.core.invocation.InvocationTimeoutStrategy;\r\n\r\nimport com.google.common.base.Ticker;\r\n\r\n/**\r\n * <pre>\r\n * Cumulative Processing Time\r\n * not depend on time synchronization\r\n * but lost network and framework outside of servicecomb processing time\r\n *\r\n * consumer: c\r\n * producer: p\r\n * ---------------------------------------------------------------\r\n * | process 2                                                   |\r\n * |                 c-send(T5)                       c-send(T8) |\r\n * |                    ↑                               ↑      |\r\n * | p-start(T3) → c-start(T4) → p-operation(T6) → c-start(T7)|\r\n * -----↑--------------------------------------------------------\r\n *      ↑\r\n * -----↑-----------------\r\n * |    ↑     process 1  |\r\n * |  c-send(T2)          |\r\n * |    ↑                |\r\n * |  c-start(T1)         |\r\n * ------------------------\r\n *\r\n * T2 timeout: T2 - T1\r\n * T3 timeout: (T2 - T1) + (T3 - T3)\r\n * T4 timeout: (T2 - T1) + (T4 - T3)\r\n * T5 timeout: (T2 - T1) + (T5 - T3)\r\n * T6 timeout: (T2 - T1) + (T6 - T3)\r\n * T7 timeout: (T2 - T1) + (T7 - T3)\r\n * T8 timeout: (T2 - T1) + (T8 - T3)\r\n * ......\r\n * </pre>\r\n */\r\npublic class ProcessingTimeStrategy implements InvocationTimeoutStrategy {\r\n  public static final String NAME = \"processing-time\";\r\n\r\n  // nanoseconds\r\n  // used inside one process\r\n  // not depend on time synchronization\r\n  public static final String CHAIN_START_TIME = \"x-scb-process-chain-start\";\r\n\r\n  // nanoseconds\r\n  // processing time of all previous process\r\n  // transfer between processes\r\n  public static final String CHAIN_PROCESSING = \"x-scb-processing-time\";\r\n\r\n  private Ticker ticker = Ticker.systemTicker();\r\n\r\n  public ProcessingTimeStrategy setTicker(Ticker ticker) {\r\n    this.ticker = ticker;\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public String name() {\r\n    return NAME;\r\n  }\r\n\r\n  @Override\r\n  public void start(Invocation invocation) {\r\n    initProcessChainStart(invocation);\r\n    initChainProcessing(invocation);\r\n  }\r\n\r\n  private void initProcessChainStart(Invocation invocation) {\r\n    if (invocation.getLocalContext(CHAIN_START_TIME) != null) {\r\n      return;\r\n    }\r\n\r\n    invocation.addLocalContext(CHAIN_START_TIME, invocation.getInvocationStageTrace().getStart());\r\n  }\r\n\r\n  private void initChainProcessing(Invocation invocation) {\r\n    if (invocation.getLocalContext(CHAIN_PROCESSING) != null) {\r\n      return;\r\n    }\r\n\r\n    String contextChainProcessing = invocation.getContext(CHAIN_PROCESSING);\r\n    long chainProcessingTime = NumberUtils.toLong(contextChainProcessing, 0L);\r\n    invocation.addLocalContext(CHAIN_PROCESSING, chainProcessingTime);\r\n  }\r\n\r\n  @Override\r\n  public void beforeSendRequest(Invocation invocation) {\r\n    InvocationTimeoutStrategy.super.beforeSendRequest(invocation);\r\n\r\n    long processingTime = calculateElapsedNanoTime(invocation);\r\n    invocation.addContext(CHAIN_PROCESSING, Long.toString(processingTime));\r\n  }\r\n\r\n  @Override\r\n  public long calculateElapsedNanoTime(Invocation invocation) {\r\n    long chainStartTime = invocation.getLocalContext(CHAIN_START_TIME);\r\n    long previousProcessingTime = invocation.getLocalContext(CHAIN_PROCESSING);\r\n    return ticker.read() - chainStartTime + previousProcessingTime;\r\n  }\r\n}\r\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/LocalOpenAPIRegistry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider;\n\nimport java.util.Collections;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager.OpenAPIChangeListener;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n/**\n * register and load OpenAPI from local file store or memory\n */\npublic class LocalOpenAPIRegistry implements OpenAPIRegistry {\n  private static final Logger LOGGER = LoggerFactory.getLogger(LocalOpenAPIRegistry.class);\n\n  // first key : appId\n  // second key: microservice short name\n  // third key : schemaId\n  private final Map<String, Map<String, Map<String, OpenAPI>>> apps = new ConcurrentHashMapEx<>();\n\n  private final Environment environment;\n\n  private OpenAPIChangeListener openAPIChangeListener;\n\n  public LocalOpenAPIRegistry(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public boolean enabled() {\n    return true;\n  }\n\n  @Override\n  public void registerOpenAPI(String application, String serviceName, String schemaId, OpenAPI api) {\n    apps.computeIfAbsent(application, k -> new ConcurrentHashMapEx<>())\n        .computeIfAbsent(serviceName, k -> new ConcurrentHashMapEx<>())\n        .put(schemaId, api);\n    openAPIChangeListener.onOpenAPIChanged(application, serviceName);\n    LOGGER.info(\"register swagger appId={}, name={}, schemaId={}.\",\n        application, serviceName, schemaId);\n  }\n\n  /**\n   * Method for retrieve myself schema contents.\n   */\n  public Map<String, OpenAPI> loadOpenAPI() {\n    return loadOpenAPI(BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment));\n  }\n\n  @Override\n  public Map<String, OpenAPI> loadOpenAPI(String application, String serviceName) {\n    if (apps.get(application) != null && apps.get(application).get(serviceName) != null) {\n      return apps.get(application).get(serviceName);\n    }\n    return Collections.emptyMap();\n  }\n\n  @Override\n  public void setOpenAPIChangeListener(OpenAPIChangeListener listener) {\n    this.openAPIChangeListener = listener;\n  }\n\n  @Override\n  public int getOrder() {\n    return -10000;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/OpenAPIRegistry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager.OpenAPIChangeListener;\nimport org.springframework.core.Ordered;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n/**\n * Register and load OpenAPI extensions.\n */\npublic interface OpenAPIRegistry extends Ordered {\n  String CONFIG_PREFIX = \"servicecomb.openAPI.registry\";\n\n  boolean enabled();\n\n  void registerOpenAPI(String application, String serviceName, String schemaId, OpenAPI api);\n\n  Map<String, OpenAPI> loadOpenAPI(String application, String serviceName);\n\n  void setOpenAPIChangeListener(OpenAPIChangeListener listener);\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/OpenAPIRegistryManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider;\n\nimport java.net.URI;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.io.FilenameUtils;\nimport org.apache.servicecomb.foundation.common.utils.ResourceUtil;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.util.CollectionUtils;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n/**\n * Register and load OpenAPI from various OpenAPIRegistry\n */\npublic class OpenAPIRegistryManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(OpenAPIRegistryManager.class);\n\n  public interface OpenAPIChangeListener {\n    void onOpenAPIChanged(String application, String serviceName);\n  }\n\n  private List<OpenAPIRegistry> openAPIRegistries;\n\n  private final List<OpenAPIChangeListener> changeListeners = new ArrayList<>();\n\n  @Autowired\n  public void setOpenAPIRegistries(List<OpenAPIRegistry> openAPIRegistries) {\n    List<OpenAPIRegistry> target = new ArrayList<>(openAPIRegistries.size());\n    for (OpenAPIRegistry registry : openAPIRegistries) {\n      if (registry.enabled()) {\n        registry.setOpenAPIChangeListener(this::onOpenAPIChanged);\n        target.add(registry);\n      }\n    }\n    this.openAPIRegistries = target;\n  }\n\n  public void addOpenAPIChangeListener(OpenAPIChangeListener changeListener) {\n    this.changeListeners.add(changeListener);\n  }\n\n  public void onOpenAPIChanged(String application, String serviceName) {\n    for (OpenAPIChangeListener listener : this.changeListeners) {\n      try {\n        listener.onOpenAPIChanged(application, serviceName);\n      } catch (Exception e) {\n        LOGGER.warn(\"event process error {}/{}, {}\", application, serviceName, e.getMessage());\n      }\n    }\n  }\n\n  public void registerOpenAPI(String application, String serviceName, String schemaId, OpenAPI api) {\n    for (OpenAPIRegistry registry : this.openAPIRegistries) {\n      registry.registerOpenAPI(application, serviceName, schemaId, api);\n    }\n  }\n\n  public void registerOpenAPI(String application, String serviceName, String schemaId, Class<?> cls) {\n    OpenAPI api = SwaggerGenerator.generate(cls);\n    registerOpenAPI(application, serviceName, schemaId, api);\n  }\n\n  public void registerOpenAPIInLocation(String application, String serviceName, String swaggersLocation) {\n    try {\n      List<URI> resourceUris = ResourceUtil.findResourcesBySuffix(swaggersLocation, \".yaml\");\n      if (resourceUris.isEmpty()) {\n        return;\n      }\n      for (URI uri : resourceUris) {\n        URL url = uri.toURL();\n        OpenAPI swagger = SwaggerUtils.parseAndValidateSwagger(url);\n        String schemaId = FilenameUtils.getBaseName(url.getPath());\n        registerOpenAPI(application, serviceName, schemaId, swagger);\n      }\n    } catch (Throwable e) {\n      throw new IllegalStateException(String.format(\n          \"failed to register swaggers, microserviceName=%s, location=%s.\",\n          serviceName, swaggersLocation), e);\n    }\n  }\n\n  public Map<String, OpenAPI> loadOpenAPI(String appId, String microserviceName) {\n    for (OpenAPIRegistry registry : this.openAPIRegistries) {\n      Map<String, OpenAPI> result = registry.loadOpenAPI(appId, microserviceName);\n      if (!CollectionUtils.isEmpty(result)) {\n        return result;\n      }\n    }\n    return Collections.emptyMap();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/RegistryOpenAPIRegistry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager.OpenAPIChangeListener;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.router.util.VersionCompareUtil;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport jakarta.ws.rs.core.Response.Status;\n\n/**\n * register and load OpenAPI from registration and discovery registry.\n */\npublic class RegistryOpenAPIRegistry implements OpenAPIRegistry {\n  private DiscoveryManager discoveryManager;\n\n  private Environment environment;\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n\n  @Override\n  public boolean enabled() {\n    return environment.getProperty(OpenAPIRegistry.CONFIG_PREFIX + \".registry.enabled\", boolean.class, false);\n  }\n\n  @Override\n  public void registerOpenAPI(String application, String serviceName, String schemaId, OpenAPI api) {\n    // do noting\n  }\n\n  @Override\n  public Map<String, OpenAPI> loadOpenAPI(String application, String serviceName) {\n    List<? extends DiscoveryInstance> discoveryInstances =\n        discoveryManager.findServiceInstances(application, serviceName);\n    if (discoveryInstances.isEmpty()) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR, \"no instances\");\n    }\n    discoveryInstances.sort((a, b) -> VersionCompareUtil.compareVersion(b.getVersion(), a.getVersion()));\n\n    Map<String, OpenAPI> result = new HashMap<>();\n    String version = null;\n    for (DiscoveryInstance instance : discoveryInstances) {\n      if (version != null && !version.equals(instance.getVersion())) {\n        break;\n      }\n      version = instance.getVersion();\n      instance.getSchemas().forEach((k, v) -> result.computeIfAbsent(k, (key) -> SwaggerUtils.parseSwagger(v)));\n    }\n    return result;\n  }\n\n  @Override\n  public void setOpenAPIChangeListener(OpenAPIChangeListener listener) {\n    this.discoveryManager.addInstanceChangeListener(\n        (registryName, application, serviceName, instances) -> {\n          if (CollectionUtils.isEmpty(instances)) {\n            return;\n          }\n          listener.onOpenAPIChanged(application, serviceName);\n        });\n  }\n\n  @Override\n  public int getOrder() {\n    return -8000;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/ConsumerProviderManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager;\nimport org.apache.servicecomb.foundation.common.utils.ResourceUtil;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\npublic class ConsumerProviderManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerProviderManager.class);\n\n  private final OpenAPIRegistryManager openAPIRegistryManager;\n\n  private final Environment environment;\n\n  public ConsumerProviderManager(Environment environment, OpenAPIRegistryManager openAPIRegistryManager) {\n    this.environment = environment;\n    this.openAPIRegistryManager = openAPIRegistryManager;\n  }\n\n  public void init() throws Exception {\n    registerSwaggerFromApplications();\n    registerSwaggerFromMicroservices();\n  }\n\n  private void registerSwaggerFromApplications() {\n    try {\n      List<URI> resourceUris = ResourceUtil.findResourcesBySuffix(\"applications\", \".yaml\");\n      for (URI uri : resourceUris) {\n        String path = uri.toURL().getPath();\n        String[] segments = path.split(\"/\");\n        if (segments.length < 4 || !\"applications\".equals(segments[segments.length - 4])) {\n          continue;\n        }\n        openAPIRegistryManager.registerOpenAPI(segments[segments.length - 3], segments[segments.length - 2],\n            segments[segments.length - 1].substring(0, segments[segments.length - 1].indexOf(\".yaml\")),\n            SwaggerUtils.parseAndValidateSwagger(uri.toURL()));\n      }\n    } catch (IOException | URISyntaxException e) {\n      LOGGER.error(\"Load schema ids failed from applications. {}.\", e.getMessage());\n    }\n  }\n\n  private void registerSwaggerFromMicroservices() {\n    try {\n      List<URI> resourceUris = ResourceUtil.findResourcesBySuffix(\"microservices\", \".yaml\");\n      for (URI uri : resourceUris) {\n        String path = uri.toURL().getPath();\n        String[] segments = path.split(\"/\");\n        if (segments.length < 3 || !\"microservices\".equals(segments[segments.length - 3])) {\n          continue;\n        }\n        openAPIRegistryManager.registerOpenAPI(BootStrapProperties.readApplication(environment),\n            segments[segments.length - 2],\n            segments[segments.length - 1].substring(0, segments[segments.length - 1].indexOf(\".yaml\")),\n            SwaggerUtils.parseAndValidateSwagger(uri.toURL()));\n      }\n    } catch (IOException | URISyntaxException e) {\n      LOGGER.error(\"Load schema ids failed from microservices. {}.\", e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport static org.apache.servicecomb.core.exception.Exceptions.toConsumerResponse;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.swagger.invocation.AsyncResponse;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport io.vertx.core.Context;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic final class InvokerUtils {\n  @SuppressWarnings({\"unchecked\"})\n  public static <T> T syncInvoke(String microserviceName, String transport,\n      String schemaId, String operationId, Map<String, Object> swaggerArguments, Type responseType) {\n    Invocation invocation = createInvocation(microserviceName, transport, schemaId, operationId,\n        swaggerArguments, responseType);\n    return (T) syncInvoke(invocation);\n  }\n\n  public static void reactiveInvoke(String microserviceName, String transport,\n      String schemaId, String operationId, Map<String, Object> swaggerArguments, Type responseType,\n      AsyncResponse asyncResp) {\n    Invocation invocation = createInvocation(microserviceName, transport, schemaId, operationId,\n        swaggerArguments, responseType);\n    reactiveInvoke(invocation, asyncResp);\n  }\n\n  public static <T> T syncInvoke(String microserviceName, String schemaId, String operationId,\n      Map<String, Object> swaggerArguments, Type responseType) {\n    return syncInvoke(microserviceName, null,\n        schemaId, operationId, swaggerArguments, responseType);\n  }\n\n  public static void reactiveInvoke(String microserviceName, String schemaId, String operationId,\n      Map<String, Object> swaggerArguments, Type responseType,\n      AsyncResponse asyncResp) {\n    reactiveInvoke(microserviceName, null,\n        schemaId, operationId, swaggerArguments, responseType, asyncResp);\n  }\n\n  public static Invocation createInvocation(String microserviceName, String transport,\n      String schemaId, String operationId, Map<String, Object> swaggerArguments, Type responseType) {\n    long startCreateInvocation = System.nanoTime();\n    MicroserviceReferenceConfig microserviceReferenceConfig = SCBEngine.getInstance()\n        .getOrCreateReferenceConfig(microserviceName);\n    if (microserviceReferenceConfig == null) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          new CommonExceptionData(String.format(\"Failed to invoke service %s. Maybe service\"\n              + \" not registered or no active instance.\", microserviceName)));\n    }\n    MicroserviceMeta microserviceMeta = microserviceReferenceConfig.getMicroserviceMeta();\n    SchemaMeta schemaMeta = microserviceMeta.ensureFindSchemaMeta(schemaId);\n    OperationMeta operationMeta = schemaMeta.ensureFindOperation(operationId);\n\n    ReferenceConfig referenceConfig = microserviceReferenceConfig.createReferenceConfig(transport, operationMeta);\n    InvocationRuntimeType invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();\n    invocationRuntimeType.setSuccessResponseType(responseType);\n    Invocation result = InvocationFactory\n        .forConsumer(referenceConfig, operationMeta, invocationRuntimeType, swaggerArguments);\n    result.getInvocationStageTrace().startCreateInvocation(startCreateInvocation);\n    result.getInvocationStageTrace().finishCreateInvocation();\n    return result;\n  }\n\n  /**\n   *\n   * use of this method , the response type can not be determined.\n   * use {@link #syncInvoke(String, String, String, String, Map, Type)} instead.\n   *\n   */\n  @Deprecated\n  public static Object syncInvoke(String microserviceName, String transport,\n      String schemaId, String operationId, Map<String, Object> swaggerArguments) {\n    return syncInvoke(microserviceName, transport, schemaId, operationId, swaggerArguments,\n        null);\n  }\n\n  /**\n   * This is an internal API, caller make sure already invoked SCBEngine.ensureStatusUp\n   */\n  public static Object syncInvoke(Invocation invocation) throws InvocationException {\n    Response response = innerSyncInvoke(invocation);\n    if (response.isSucceed()) {\n      return response.getResult();\n    }\n    throw ExceptionFactory.convertConsumerException(response.getResult());\n  }\n\n  public static boolean isInEventLoop() {\n    return Context.isOnEventLoopThread();\n  }\n\n  /**\n   * This is an internal API, caller make sure already invoked SCBEngine.ensureStatusUp\n   */\n  public static Response innerSyncInvoke(Invocation invocation) {\n    if (isInEventLoop() &&\n        SCBEngine.getInstance()\n            .getEnvironment()\n            .getProperty(\"servicecomb.invocation.enableEventLoopBlockingCallCheck\", boolean.class, true)) {\n      throw new IllegalStateException(\"Can not execute sync logic in event loop.\");\n    }\n    return toSync(invoke(invocation), invocation.getWaitTime());\n  }\n\n  /**\n   * This is an internal API, caller make sure already invoked SCBEngine.ensureStatusUp\n   */\n  public static void reactiveInvoke(Invocation invocation, AsyncResponse asyncResp) {\n    invoke(invocation).whenComplete((r, e) -> {\n      if (e == null) {\n        asyncResp.complete(r);\n      } else {\n        asyncResp.consumerFail(e);\n      }\n    });\n  }\n\n  public static boolean isSyncMethod(Method method) {\n    return !isAsyncMethod(method);\n  }\n\n  public static boolean isAsyncMethod(Method method) {\n    // currently only support CompletableFuture for async method definition\n    return method.getReturnType().equals(CompletableFuture.class);\n  }\n\n  public static <T> T toSync(CompletableFuture<T> future, long waitInMillis) {\n    try {\n      if (waitInMillis > 0) {\n        return future.get(waitInMillis, TimeUnit.MILLISECONDS);\n      }\n      return future.get();\n    } catch (ExecutionException executionException) {\n      throw AsyncUtils.rethrow(executionException.getCause());\n    } catch (TimeoutException timeoutException) {\n      throw new InvocationException(Status.REQUEST_TIMEOUT,\n          new CommonExceptionData(\"Invocation Timeout.\"), timeoutException);\n    } catch (Throwable e) {\n      throw AsyncUtils.rethrow(e);\n    }\n  }\n\n  /**\n   * This method is used in new Filter implementation to replace Handler\n   * NOTE: this method should never throw exception directly\n   */\n  public static CompletableFuture<Response> invoke(Invocation invocation) {\n    invocation.onStart(null);\n    return invocation.getMicroserviceMeta().getConsumerFilterChain()\n        .onFilter(invocation)\n        .exceptionally(throwable -> toConsumerResponse(invocation, throwable))\n        .whenComplete((response, throwable) -> invocation.onFinish(response));\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/MicroserviceReferenceConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\n\n/**\n * microservice meta data for consumer.\n */\npublic class MicroserviceReferenceConfig {\n  private final String appId;\n\n  private final String microserviceName;\n\n  private final MicroserviceMeta microserviceMeta;\n\n  public MicroserviceReferenceConfig(\n      String appId,\n      String microserviceName,\n      MicroserviceMeta microserviceMeta) {\n    this.appId = appId;\n    this.microserviceName = microserviceName;\n    this.microserviceMeta = microserviceMeta;\n  }\n\n  public MicroserviceMeta getMicroserviceMeta() {\n    if (microserviceMeta == null) {\n      throw new IllegalStateException(\n          String.format(\n              \"Probably invoke a service before it is registered, or no instance found for it, appId=%s, name=%s.\",\n              appId,\n              microserviceName));\n    }\n\n    return microserviceMeta;\n  }\n\n  public ReferenceConfig createReferenceConfig(OperationMeta operationMeta) {\n    return createReferenceConfig(null, operationMeta);\n  }\n\n  public ReferenceConfig createReferenceConfig(String transport, OperationMeta operationMeta) {\n    if (transport == null) {\n      transport = operationMeta.getConfig().getTransport();\n    }\n    final ReferenceConfig referenceConfig = new ReferenceConfig(transport);\n    return referenceConfig;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/ReactiveResponseExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport java.util.concurrent.Executor;\n\n/**\n * reactive场景，就地执行即可\n */\npublic class ReactiveResponseExecutor implements Executor {\n  @Override\n  public void execute(Runnable cmd) {\n    cmd.run();\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/ReferenceConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.consumer;\n\n// operation level, to keep compatible, not change name\npublic class ReferenceConfig {\n  protected String transport;\n\n  public ReferenceConfig(String transport) {\n    this.transport = transport;\n  }\n\n  public String getTransport() {\n    return transport;\n  }\n\n  public void setTransport(String transport) {\n    this.transport = transport;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/ReferenceConfigManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.SCBEngine.CreateMicroserviceMetaEvent;\nimport org.apache.servicecomb.core.definition.ConsumerMicroserviceVersionsMeta;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.vertx.executor.VertxWorkerExecutor;\nimport org.apache.servicecomb.registry.definition.MicroserviceNameParser;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ReferenceConfigManager {\n  // application -> microservice name\n  private final Map<String, Map<String, MicroserviceReferenceConfig>> referenceConfigs = new ConcurrentHashMapEx<>();\n\n  private final Map<String, Map<String, Object>> referenceConfigsLocks = new ConcurrentHashMapEx<>();\n\n  private OpenAPIRegistryManager openAPIRegistryManager;\n\n  @Autowired\n  public void setOpenAPIRegistryManager(OpenAPIRegistryManager openAPIRegistryManager) {\n    this.openAPIRegistryManager = openAPIRegistryManager;\n    this.openAPIRegistryManager.addOpenAPIChangeListener(this::onOpenAPIChanged);\n  }\n\n  private void onOpenAPIChanged(String application, String serviceName) {\n    if (referenceConfigs.get(application) != null && referenceConfigs.get(application).get(serviceName) != null) {\n      MicroserviceReferenceConfig config = buildMicroserviceReferenceConfig(SCBEngine.getInstance(), application,\n          serviceName);\n      referenceConfigs.get(application).put(serviceName, config);\n    }\n  }\n\n  public CompletableFuture<MicroserviceReferenceConfig> getOrCreateReferenceConfigAsync\n      (SCBEngine scbEngine, String qualifiedName) {\n    MicroserviceNameParser parser = parseMicroserviceName(scbEngine, qualifiedName);\n    MicroserviceReferenceConfig config = referenceConfigs.computeIfAbsent(parser.getAppId(),\n            app -> new ConcurrentHashMapEx<>())\n        .get(parser.getMicroserviceName());\n\n    if (config != null) {\n      return CompletableFuture.completedFuture(config);\n    }\n\n    if (InvokerUtils.isInEventLoop()) {\n      CompletableFuture<MicroserviceReferenceConfig> result = new CompletableFuture<>();\n      VertxWorkerExecutor executor = new VertxWorkerExecutor();\n      executor.execute(() -> {\n        synchronized (referenceConfigsLocks.computeIfAbsent(parser.getAppId(), key -> new ConcurrentHashMapEx<>())\n            .computeIfAbsent(parser.getMicroserviceName(), key -> new Object())) {\n          try {\n            MicroserviceReferenceConfig temp = referenceConfigs.get(parser.getAppId())\n                .get(parser.getMicroserviceName());\n            if (temp != null) {\n              result.complete(temp);\n              return;\n            }\n            temp = buildMicroserviceReferenceConfig(scbEngine, parser.getAppId(),\n                parser.getMicroserviceName());\n            referenceConfigs.get(parser.getAppId()).put(parser.getMicroserviceName(), temp);\n            result.complete(temp);\n          } catch (Exception e) {\n            result.completeExceptionally(e);\n          }\n        }\n      });\n      return result;\n    } else {\n      synchronized (referenceConfigsLocks.computeIfAbsent(parser.getAppId(), key -> new ConcurrentHashMapEx<>())\n          .computeIfAbsent(parser.getMicroserviceName(), key -> new Object())) {\n        MicroserviceReferenceConfig temp = referenceConfigs.get(parser.getAppId())\n            .get(parser.getMicroserviceName());\n        if (temp != null) {\n          return CompletableFuture.completedFuture(temp);\n        }\n        temp = buildMicroserviceReferenceConfig(scbEngine, parser.getAppId(),\n            parser.getMicroserviceName());\n        referenceConfigs.get(parser.getAppId()).put(parser.getMicroserviceName(), temp);\n        return CompletableFuture.completedFuture(temp);\n      }\n    }\n  }\n\n  public MicroserviceReferenceConfig getOrCreateReferenceConfig(SCBEngine scbEngine, String qualifiedName) {\n    MicroserviceNameParser parser = parseMicroserviceName(scbEngine, qualifiedName);\n    MicroserviceReferenceConfig config = referenceConfigs.computeIfAbsent(parser.getAppId(),\n            app -> new ConcurrentHashMapEx<>())\n        .get(parser.getMicroserviceName());\n    if (config == null) {\n      synchronized (referenceConfigsLocks.computeIfAbsent(parser.getAppId(), key -> new ConcurrentHashMapEx<>())\n          .computeIfAbsent(parser.getMicroserviceName(), key -> new Object())) {\n        config = referenceConfigs.get(parser.getAppId()).get(parser.getMicroserviceName());\n        if (config != null) {\n          return config;\n        }\n        config = buildMicroserviceReferenceConfig(scbEngine, parser.getAppId(), parser.getMicroserviceName());\n        referenceConfigs.get(parser.getAppId()).put(parser.getMicroserviceName(), config);\n        return config;\n      }\n    }\n    return config;\n  }\n\n  private MicroserviceNameParser parseMicroserviceName(SCBEngine scbEngine, String microserviceName) {\n    return new MicroserviceNameParser(scbEngine.getAppId(), microserviceName);\n  }\n\n  private MicroserviceReferenceConfig buildMicroserviceReferenceConfig(SCBEngine engine,\n      String application, String microserviceName) {\n    ConsumerMicroserviceVersionsMeta microserviceVersionsMeta = new ConsumerMicroserviceVersionsMeta(engine);\n    MicroserviceMeta microserviceMeta = new MicroserviceMeta(engine, application, microserviceName, true);\n    microserviceMeta.setConsumerFilterChain(engine.getFilterChainsManager()\n        .findConsumerChain(application, microserviceName));\n    microserviceMeta.setEdgeFilterChain(engine.getFilterChainsManager()\n        .findEdgeChain(application, microserviceName));\n    microserviceMeta.setMicroserviceVersionsMeta(microserviceVersionsMeta);\n\n    Map<String, OpenAPI> schemas = this.openAPIRegistryManager.loadOpenAPI(application, microserviceName);\n    for (Entry<String, OpenAPI> entry : schemas.entrySet()) {\n      OpenAPI swagger = entry.getValue();\n      if (swagger != null) {\n        microserviceMeta.registerSchemaMeta(entry.getKey(), entry.getValue());\n        continue;\n      }\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          String.format(\"Swagger %s/%s/%s can not be empty or load swagger failed.\",\n              application, microserviceName, entry.getKey()));\n    }\n\n    EventManager.getEventBus().post(new CreateMicroserviceMetaEvent(microserviceMeta));\n    return new MicroserviceReferenceConfig(application,\n        microserviceName, microserviceMeta);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/consumer/SyncResponseExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport static jakarta.ws.rs.core.Response.Status.REQUEST_TIMEOUT;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionCodes;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\n/**\n * 业务线程在阻塞等待着，不必另起线程\n * 将应答流程包装为Runnable，先唤醒业务线程，再在业务线程中执行runnable\n */\npublic class SyncResponseExecutor implements Executor {\n  private final CountDownLatch latch;\n\n  private Runnable cmd;\n\n  private Response response;\n\n  public SyncResponseExecutor() {\n    latch = new CountDownLatch(1);\n  }\n\n  @Override\n  public void execute(Runnable cmd) {\n    this.cmd = cmd;\n\n    // one network thread, many connections, then this notify will be performance bottlenecks\n    // if save to a queue, and other thread(s) to invoke countDown, will get good performance\n    // but if have multiple network thread, this \"optimization\" will reduce performance\n    // now not change this.\n    latch.countDown();\n  }\n\n  public Response waitResponse(Invocation invocation) throws InvocationException {\n    guardedWait(invocation);\n\n    // cmd为null，是没走execute，直接返回的场景\n    if (cmd != null) {\n      cmd.run();\n    }\n\n    return response;\n  }\n\n  public void setResponse(Response response) {\n    this.response = response;\n    if (cmd == null) {\n      // 1. 走到这里，没有cmd，说明没走到网络线程，直接就返回了。\n      // 2. 或者在网络线程中没使用execute的方式返回，这会导致返回流程在网络线程中执行，虽然不合适，但是也不应该导致业务线程无法唤醒\n      latch.countDown();\n    }\n  }\n\n  private void guardedWait(Invocation invocation) throws InvocationException {\n    long wait = getWaitTime(invocation);\n    try {\n      if (wait <= 0) {\n        latch.await();\n        return;\n      }\n      if (latch.await(wait, TimeUnit.MILLISECONDS)) {\n        return;\n      }\n    } catch (InterruptedException e) {\n      //ignore\n    }\n    throw new InvocationException(REQUEST_TIMEOUT, ExceptionCodes.INVOCATION_TIMEOUT, \"Invocation Timeout.\");\n  }\n\n  private long getWaitTime(Invocation invocation) {\n    if (invocation.getOperationMeta().getConfig().getMsInvocationTimeout() > 0) {\n      // if invocation timeout configured, use it.\n      return invocation.getOperationMeta().getConfig().getMsInvocationTimeout();\n    }\n\n    // In invocation handlers, may call other microservices, invocation\n    // timeout may be much longer than request timeout.\n    // For simplicity, default 30000 or two times of request timeout.\n    return Math.max(invocation.getOperationMeta().getConfig().getMsRequestTimeout() * 2, 30000);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/producer/AbstractProducerProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.producer;\n\nimport org.apache.servicecomb.core.ProducerProvider;\n\npublic abstract class AbstractProducerProvider implements ProducerProvider {\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/producer/ProducerBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.producer;\n\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.concurrent.ExecutorService;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.utils.IOUtils;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class ProducerBootListener implements BootListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProducerBootListener.class);\n\n  private static final String PATTERN = File.separator + \"microservices\"\n      + File.separator + \"%s\" + File.separator + \"%s.yaml\";\n\n  private static final String TMP_DIR = System.getProperty(\"java.io.tmpdir\");\n\n  private RegistrationManager registrationManager;\n\n  private Environment environment;\n\n  @Autowired\n  public void setRegistrationManager(RegistrationManager registrationManager) {\n    this.registrationManager = registrationManager;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void onAfterTransport(BootEvent event) {\n    boolean exportToFile = environment.getProperty(CoreConst.SWAGGER_EXPORT_ENABLED, boolean.class, true);\n    String filePath = environment.getProperty(CoreConst.SWAGGER_DIRECTORY, String.class, TMP_DIR) + PATTERN;\n\n    if (exportToFile) {\n      LOGGER.info(\"export microservice swagger file to path {}\", filePath);\n    }\n    // register schema to microservice;\n    MicroserviceMeta microserviceMeta = event.getScbEngine().getProducerMicroserviceMeta();\n    for (SchemaMeta schemaMeta : microserviceMeta.getSchemaMetas().values()) {\n      OpenAPI swagger = schemaMeta.getSwagger();\n      String content = SwaggerUtils.swaggerToString(swagger);\n      if (exportToFile) {\n        exportToFile(String.format(filePath,\n            BootStrapProperties.readServiceName(environment), schemaMeta.getSchemaId()), content);\n      } else {\n        LOGGER.info(\"generate swagger for {}/{}/{}, swagger: {}\",\n            microserviceMeta.getAppId(),\n            microserviceMeta.getMicroserviceName(),\n            schemaMeta.getSchemaId(),\n            content);\n      }\n      this.registrationManager.addSchema(schemaMeta.getSchemaId(), content);\n    }\n  }\n\n\n  // bug: can not close all thread for edge\n  @Override\n  public void onAfterClose(BootEvent event) {\n    MicroserviceMeta microserviceMeta = event.getScbEngine().getProducerMicroserviceMeta();\n    if (microserviceMeta == null) {\n      return;\n    }\n\n    for (OperationMeta operationMeta : microserviceMeta.getOperations()) {\n      if (operationMeta.getExecutor() instanceof ExecutorService) {\n        ((ExecutorService) operationMeta.getExecutor()).shutdown();\n        continue;\n      }\n\n      if (operationMeta.getExecutor() instanceof Closeable) {\n        IOUtils.closeQuietly((Closeable) operationMeta.getExecutor());\n        continue;\n      }\n\n      LOGGER.warn(\"Executor {} do not support close or shutdown, it may block service shutdown.\",\n          operationMeta.getExecutor().getClass().getName());\n    }\n  }\n\n  private void exportToFile(String fileName, String content) {\n    File file = new File(fileName);\n    if (!file.getParentFile().exists()) {\n      if (!file.getParentFile().mkdirs()) {\n        LOGGER.error(\"create file directory failed\");\n        return;\n      }\n    }\n    if (file.exists()) {\n      file.delete();\n    }\n    try {\n      file.createNewFile();\n      FileUtils.writeStringToFile(file, content, StandardCharsets.UTF_8, false);\n      file.setReadOnly();\n    } catch (IOException e) {\n      LOGGER.error(\"export swagger content to file failed, message: {}\", e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/producer/ProducerMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.producer;\n\npublic class ProducerMeta {\n  private String schemaId;\n\n  private Object instance;\n\n  private Class<?> schemaInterface;\n\n  public ProducerMeta() {\n  }\n\n  public ProducerMeta(String schemaId, Object instance) {\n    this.schemaId = schemaId;\n    this.instance = instance;\n  }\n\n  public String getSchemaId() {\n    return schemaId;\n  }\n\n  public void setSchemaId(String schemaId) {\n    this.schemaId = schemaId;\n  }\n\n  public Object getInstance() {\n    return instance;\n  }\n\n  public void setInstance(Object instance) {\n    this.instance = instance;\n  }\n\n  public Class<?> getSchemaInterface() {\n    return schemaInterface;\n  }\n\n  public void setSchemaInterface(Class<?> schemaInterface) {\n    this.schemaInterface = schemaInterface;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/provider/producer/ProducerProviderManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.producer;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.Executor;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.ProducerProvider;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.CoreMetaUtils;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class ProducerProviderManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProducerProviderManager.class);\n\n  private final List<ProducerProvider> producerProviderList = new ArrayList<>(\n      SPIServiceUtils.getOrLoadSortedService(ProducerProvider.class));\n\n  private final SCBEngine scbEngine;\n\n  private final List<ProducerMeta> producerMetas = new ArrayList<>();\n\n  public ProducerProviderManager(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  public List<ProducerProvider> getProducerProviderList() {\n    return producerProviderList;\n  }\n\n  public void init() {\n    registerProducerMetas(producerMetas);\n\n    for (ProducerProvider provider : producerProviderList) {\n      List<ProducerMeta> producerMetas = provider.init();\n      if (producerMetas == null) {\n        LOGGER.warn(\"ProducerProvider {} not provide any producer.\", provider.getClass().getName());\n        continue;\n      }\n\n      registerProducerMetas(producerMetas);\n    }\n  }\n\n  public void addProducerMeta(String schemaId, Object instance) {\n    addProducerMeta(new ProducerMeta(schemaId, instance));\n  }\n\n  public void addProducerMeta(ProducerMeta producerMeta) {\n    producerMetas.add(producerMeta);\n  }\n\n  private void registerProducerMetas(List<ProducerMeta> producerMetas) {\n    for (ProducerMeta producerMeta : producerMetas) {\n      registerSchema(producerMeta.getSchemaId(), producerMeta.getSchemaInterface(), producerMeta.getInstance());\n    }\n  }\n\n  public SchemaMeta registerSchema(String schemaId, Object instance) {\n    return registerSchema(schemaId, null, instance);\n  }\n\n  public SchemaMeta registerSchema(String schemaId, Class<?> schemaInterface, Object instance) {\n    MicroserviceMeta producerMicroserviceMeta = scbEngine.getProducerMicroserviceMeta();\n    SwaggerProducer swaggerProducer = scbEngine.getSwaggerEnvironment()\n        .createProducer(instance, schemaInterface);\n    OpenAPI swagger = swaggerProducer.getSwagger();\n    registerUrlPrefixToSwagger(swagger);\n\n    // register self OpenAPI to registry\n    scbEngine.getOpenAPIRegistryManager()\n        .registerOpenAPI(BootStrapProperties.readApplication(scbEngine.getEnvironment()),\n            BootStrapProperties.readServiceName(scbEngine.getEnvironment()), schemaId, swagger);\n\n    SchemaMeta schemaMeta = producerMicroserviceMeta.registerSchemaMeta(schemaId, swagger);\n    schemaMeta.putExtData(CoreMetaUtils.SWAGGER_PRODUCER, swaggerProducer);\n    Executor reactiveExecutor = scbEngine.getExecutorManager().findExecutorById(ExecutorManager.EXECUTOR_REACTIVE);\n    for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {\n      OperationMeta operationMeta = schemaMeta.ensureFindOperation(producerOperation.getOperationId());\n      operationMeta.setSwaggerProducerOperation(producerOperation);\n\n      if (CompletableFuture.class.equals(producerOperation.getProducerMethod().getReturnType())) {\n        operationMeta.setExecutor(scbEngine.getExecutorManager().findExecutor(operationMeta, reactiveExecutor));\n      }\n    }\n\n    return schemaMeta;\n  }\n\n  // This is special requirement by users: When service deployed in tomcat,user want to use RestTemplate to\n  // call REST service by the full url. e.g. restTemplate.getForObject(\"cse://serviceName/root/prefix/health\")\n  // By default, user's do not need context prefix, e.g. restTemplate.getForObject(\"cse://serviceName/health\")\n  private void registerUrlPrefixToSwagger(OpenAPI swagger) {\n    String urlPrefix = ClassLoaderScopeContext.getClassLoaderScopeProperty(DefinitionConst.URL_PREFIX);\n    if (!StringUtils.isEmpty(urlPrefix) && !SwaggerUtils.getBasePath(swagger).startsWith(urlPrefix)\n        && scbEngine.getEnvironment().getProperty(DefinitionConst.REGISTER_URL_PREFIX, boolean.class, false)) {\n      LOGGER.info(\"Add swagger base path prefix for {} with {}\", SwaggerUtils.getBasePath(swagger), urlPrefix);\n      SwaggerUtils.setBasePath(swagger, urlPrefix + SwaggerUtils.getBasePath(swagger));\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/registry/discovery/EndpointDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.registry.discovery;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.registry.discovery.AbstractEndpointDiscoveryFilter;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class EndpointDiscoveryFilter extends AbstractEndpointDiscoveryFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EndpointDiscoveryFilter.class);\n\n  protected SCBEngine scbEngine;\n\n  public EndpointDiscoveryFilter() {\n  }\n\n  @Autowired\n  public void setScbEngine(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  @Override\n  public int getOrder() {\n    return Short.MAX_VALUE;\n  }\n\n  @Override\n  protected String findTransportName(DiscoveryContext context, DiscoveryTreeNode parent) {\n    Invocation invocation = context.getInputParameters();\n    return invocation.getConfigTransportName();\n  }\n\n  @Override\n  protected Object createEndpoint(DiscoveryContext context, String transportName, String endpoint,\n      StatefulDiscoveryInstance instance) {\n    Transport transport = scbEngine.getTransportManager().findTransport(transportName);\n    if (transport == null) {\n      LOGGER.info(\"not deployed transport {}, ignore {}.\", transportName, endpoint);\n      return null;\n    }\n\n    return new Endpoint(transport, endpoint, instance);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/tracing/BraveTraceIdGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.tracing;\n\nimport org.apache.servicecomb.core.CoreConst;\n\nimport brave.internal.Platform;\n\npublic class BraveTraceIdGenerator implements TraceIdGenerator {\n  @Override\n  public String getTraceIdKeyName() {\n    return CoreConst.TRACE_ID_NAME;\n  }\n\n  @Override\n  public String generate() {\n    return Long.toHexString(Platform.get().nextTraceIdHigh());\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/tracing/ScbMarker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.tracing;\n\nimport org.apache.servicecomb.foundation.common.log.AbstractMarker;\n\npublic class ScbMarker extends AbstractMarker {\n  private static final long serialVersionUID = -1L;\n\n  private static final String MARKER_NAME = \"SERVICECOMB_MARKER\";\n\n  public ScbMarker() {\n\n  }\n\n  @Override\n  public final String getName() {\n    return MARKER_NAME;\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/tracing/TraceIdGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.tracing;\n\npublic interface TraceIdGenerator {\n  default int getOrder() {\n    return 1000;\n  }\n\n  /**\n   * <pre>\n   *   for generators have the same name, will only use the minimum order instance\n   *   not use getTraceIdKeyName to control this logic, because most customers not want to generate multiple traceIds\n   * </pre>\n   * @return generator name\n   */\n  default String getName() {\n    return \"default\";\n  }\n\n  /**\n   *\n   * @return trance id key name\n   * <pre>\n   * default value is X-B3-TraceId to work with zipkin\n   * </pre>\n   */\n  String getTraceIdKeyName();\n\n  String generate();\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/tracing/TraceIdLogger.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.tracing;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.slf4j.MDC;\nimport org.slf4j.Marker;\n\npublic class TraceIdLogger {\n  private static final Logger LOGGER = LoggerFactory.getLogger(\"scb-trace-id\");\n\n  private static final Marker MARKER = new ScbMarker();\n\n  public static final String KEY_TRACE_ID = \"SERVICECOMB_TRACE_ID\";\n\n  private final Invocation invocation;\n\n  public TraceIdLogger(Invocation invocation) {\n    this.invocation = invocation;\n  }\n\n  public Invocation getInvocation() {\n    return invocation;\n  }\n\n  public static String constructSource(String source) {\n    return \"[\" + source + \"(\" +\n        Thread.currentThread().getStackTrace()[2].getLineNumber() + \")]\";\n  }\n\n  public final String getName() {\n    return invocation.getTraceId();\n  }\n\n  public void error(String format, Object... arguments) {\n    MDC.put(KEY_TRACE_ID, getName());\n    LOGGER.error(MARKER, format, arguments);\n    MDC.remove(KEY_TRACE_ID);\n  }\n\n  public void warn(String format, Object... arguments) {\n    MDC.put(KEY_TRACE_ID, getName());\n    LOGGER.warn(MARKER, format, arguments);\n    MDC.remove(KEY_TRACE_ID);\n  }\n\n  public void info(String format, Object... arguments) {\n    MDC.put(KEY_TRACE_ID, getName());\n    LOGGER.info(MARKER, format, arguments);\n    MDC.remove(KEY_TRACE_ID);\n  }\n\n  public void debug(String format, Object... arguments) {\n    MDC.put(KEY_TRACE_ID, getName());\n    LOGGER.debug(MARKER, format, arguments);\n    MDC.remove(KEY_TRACE_ID);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/transport/AbstractTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.transport;\n\nimport java.net.Inet6Address;\nimport java.net.InetSocketAddress;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\nimport org.apache.http.client.utils.URIBuilder;\nimport org.apache.http.client.utils.URLEncodedUtils;\nimport org.apache.http.message.BasicNameValuePair;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.foundation.common.net.IpPort;\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.vertx.SharedVertxFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.Vertx;\n\npublic abstract class AbstractTransport implements Transport {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTransport.class);\n\n  public static final String PUBLISH_ADDRESS = \"servicecomb.service.publishAddress\";\n\n  private static final String PUBLISH_PORT = \"servicecomb.{transport_name}.publishPort\";\n\n  /*\n   * 用于参数传递：比如向RestServerVerticle传递endpoint地址。\n   */\n  public static final String ENDPOINT_KEY = \"servicecomb.endpoint\";\n\n  protected Vertx transportVertx;\n\n  protected Endpoint endpoint;\n\n  protected Endpoint publishEndpoint;\n\n  protected Environment environment;\n\n  @Override\n  public Endpoint getPublishEndpoint() {\n    return publishEndpoint;\n  }\n\n  @Override\n  public Endpoint getEndpoint() {\n    return endpoint;\n  }\n\n  @Override\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n    this.transportVertx = SharedVertxFactory.getSharedVertx(environment);\n  }\n\n  protected void setListenAddressWithoutSchema(String addressWithoutSchema) {\n    setListenAddressWithoutSchema(addressWithoutSchema, null);\n  }\n\n  /*\n   * 将配置的URI转换为endpoint\n   * addressWithoutSchema 配置的URI，没有schema部分\n   */\n  protected void setListenAddressWithoutSchema(String addressWithoutSchema,\n      Map<String, String> pairs) {\n    addressWithoutSchema = genAddressWithoutSchema(addressWithoutSchema, pairs);\n\n    this.endpoint = new Endpoint(this, NetUtils.getRealListenAddress(getName(), addressWithoutSchema));\n    if (this.endpoint.getEndpoint() != null) {\n      this.publishEndpoint = new Endpoint(this, getPublishAddress(getName(),\n          addressWithoutSchema));\n    } else {\n      this.publishEndpoint = null;\n    }\n  }\n\n  private String genAddressWithoutSchema(String addressWithoutSchema, Map<String, String> pairs) {\n    if (addressWithoutSchema == null || pairs == null || pairs.isEmpty()) {\n      return addressWithoutSchema;\n    }\n\n    int idx = addressWithoutSchema.indexOf('?');\n    if (idx == -1) {\n      addressWithoutSchema += \"?\";\n    } else {\n      addressWithoutSchema += \"&\";\n    }\n\n    String encodedQuery = URLEncodedUtils.format(\n        pairs.entrySet().stream().map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))\n            .collect(Collectors.toList()), StandardCharsets.UTF_8.name());\n\n    addressWithoutSchema += encodedQuery;\n\n    return addressWithoutSchema;\n  }\n\n  @Override\n  public Object parseAddress(String address) {\n    if (address == null) {\n      return null;\n    }\n    return new URIEndpointObject(address);\n  }\n\n  /**\n   * In the case that listening address configured as 0.0.0.0, the publish address will be determined\n   * by the query result for the net interfaces.\n   *\n   * @return the publish address, or {@code null} if the param {@code address} is null.\n   */\n  protected String getPublishAddress(String schema, String address) {\n    if (address == null) {\n      return address;\n    }\n\n    try {\n      URI originalURI = new URI(schema + \"://\" + address);\n      IpPort ipPort = NetUtils.parseIpPort(originalURI);\n      if (ipPort == null) {\n        LOGGER.warn(\"address {} not valid.\", address);\n        return null;\n      }\n\n      IpPort publishIpPort = genPublishIpPort(schema, ipPort);\n      URIBuilder builder = new URIBuilder(originalURI);\n      return builder.setHost(publishIpPort.getHostOrIp()).setPort(publishIpPort.getPort()).build().toString();\n    } catch (URISyntaxException e) {\n      LOGGER.warn(\"address {} not valid.\", address);\n      return null;\n    }\n  }\n\n  private IpPort genPublishIpPort(String schema, IpPort ipPort) {\n    String publicAddressSetting = environment.getProperty(PUBLISH_ADDRESS, \"\");\n    publicAddressSetting = publicAddressSetting.trim();\n\n    String publishPortKey = PUBLISH_PORT.replace(\"{transport_name}\", schema);\n    int publishPortSetting = environment.getProperty(publishPortKey, int.class, 0);\n    int publishPort = publishPortSetting == 0 ? ipPort.getPort() : publishPortSetting;\n\n    if (publicAddressSetting.isEmpty()) {\n      InetSocketAddress socketAddress = ipPort.getSocketAddress();\n      if (socketAddress.getAddress().isAnyLocalAddress()) {\n        String host = NetUtils.getHostAddress();\n        if (Inet6Address.class.isInstance(socketAddress.getAddress())) {\n          host = NetUtils.getIpv6HostAddress();\n        }\n        LOGGER.warn(\"address {}, auto select a host address to publish {}:{}, maybe not the correct one\",\n            socketAddress,\n            host,\n            publishPort);\n        return new IpPort(host, publishPort);\n      }\n\n      return ipPort;\n    }\n\n    if (publicAddressSetting.startsWith(\"{\") && publicAddressSetting.endsWith(\"}\")) {\n      publicAddressSetting = NetUtils\n          .ensureGetInterfaceAddress(\n              publicAddressSetting.substring(1, publicAddressSetting.length() - 1))\n          .getHostAddress();\n    }\n\n    return new IpPort(publicAddressSetting, publishPort);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/transport/TransportClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.transport;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class TransportClassAnnotationProcessor implements ClassAnnotationProcessor<Transport> {\n  @Override\n  public Type getProcessType() {\n    return Transport.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, Transport transport) {\n    OpenAPI swagger = swaggerGenerator.getOpenAPI();\n    if (StringUtils.isNotEmpty(transport.name())) {\n      swagger.addExtension(CoreConst.TRANSPORT_NAME, transport.name());\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/transport/TransportManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.transport;\n\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class TransportManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TransportManager.class);\n\n  private final List<Transport> transports = new ArrayList<>(SPIServiceUtils.getOrLoadSortedService(Transport.class));\n\n  private final Map<String, Transport> transportMap = new HashMap<>();\n\n  public Map<String, Transport> getTransportMap() {\n    return transportMap;\n  }\n\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  public void clearTransportBeforeInit() {\n    transports.clear();\n  }\n\n  public void addTransportBeforeInit(Transport transport) {\n    this.transports.add(transport);\n  }\n\n  public void addTransportsBeforeInit(List<Transport> transports) {\n    this.transports.addAll(transports);\n  }\n\n  public void init(SCBEngine scbEngine) throws Exception {\n    initEnvironment();\n    buildTransportMap();\n\n    for (Transport transport : transportMap.values()) {\n      if (transport.init()) {\n        Endpoint endpoint = transport.getPublishEndpoint();\n        if (endpoint != null && endpoint.getEndpoint() != null) {\n          LOGGER.info(\"endpoint to publish: {}\", endpoint.getEndpoint());\n          scbEngine.getRegistrationManager().addEndpoint(endpoint.getEndpoint());\n        }\n        continue;\n      }\n    }\n  }\n\n  private void initEnvironment() {\n    for (Transport transport : transports) {\n      transport.setEnvironment(environment);\n    }\n  }\n\n  protected void buildTransportMap() {\n    Map<String, List<Transport>> groups = groupByName();\n\n    for (Entry<String, List<Transport>> entry : groups.entrySet()) {\n      List<Transport> group = entry.getValue();\n\n      checkTransportGroup(group);\n      Transport transport = chooseOneTransport(group);\n      transportMap.put(transport.getName(), transport);\n    }\n  }\n\n  protected Transport chooseOneTransport(List<Transport> group) {\n    group.sort(Comparator.comparingInt(Transport::getOrder));\n\n    for (Transport transport : group) {\n      if (transport.canInit()) {\n        LOGGER.info(\"choose {} for {}.\", transport.getClass().getName(), transport.getName());\n        return transport;\n      }\n    }\n\n    throw new ServiceCombException(\n        String.format(\"all transport named %s refused to init.\", group.get(0).getName()));\n  }\n\n  protected void checkTransportGroup(List<Transport> group) {\n    // order value must be different, otherwise, maybe will choose a random transport\n    Map<Integer, Transport> orderMap = new HashMap<>();\n    for (Transport transport : group) {\n      Transport existTransport = orderMap.putIfAbsent(transport.getOrder(), transport);\n      if (existTransport != null) {\n        throw new ServiceCombException(String.format(\"%s and %s have the same order %d\",\n            existTransport.getClass().getName(),\n            transport.getClass().getName(),\n            transport.getOrder()));\n      }\n    }\n  }\n\n  protected Map<String, List<Transport>> groupByName() {\n    Map<String, List<Transport>> groups = new HashMap<>();\n    for (Transport transport : transports) {\n      List<Transport> list = groups.computeIfAbsent(transport.getName(), name -> new ArrayList<>());\n      list.add(transport);\n    }\n    return groups;\n  }\n\n  public Transport findTransport(String transportName) {\n    return transportMap.get(transportName);\n  }\n}\n"
  },
  {
    "path": "core/src/main/java/org/apache/servicecomb/core/transport/TransportMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.transport;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.oas.models.Operation;\n\npublic class TransportMethodAnnotationProcessor implements MethodAnnotationProcessor<Transport> {\n  @Override\n  public Type getProcessType() {\n    return Transport.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, Transport transport) {\n    Operation operation = operationGenerator.getOperation();\n    if (StringUtils.isNotEmpty(transport.name())) {\n      operation.addExtension(CoreConst.TRANSPORT_NAME, transport.name());\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.core.exception.ExceptionConverter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.exception.converter.ConstraintViolationExceptionConverter\norg.apache.servicecomb.core.exception.converter.InvocationExceptionConverter\norg.apache.servicecomb.core.exception.converter.IllegalArgumentExceptionConverter\norg.apache.servicecomb.core.exception.converter.TimeoutExceptionConverter\norg.apache.servicecomb.core.exception.converter.ConnectTimeoutExceptionConverter\norg.apache.servicecomb.core.exception.converter.DefaultExceptionConverter\norg.apache.servicecomb.core.exception.converter.ServiceCombExceptionConverter\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.core.filter.FilterProvider",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.filter.impl.DefaultFilterProvider\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.core.tracing.TraceIdGenerator",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.tracing.BraveTraceIdGenerator\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.transport.TransportClassAnnotationProcessor\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.transport.TransportMethodAnnotationProcessor\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerContextRegister",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.invocation.endpoint.EndpointContextRegister\n"
  },
  {
    "path": "core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerContextArgumentMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.core.invocation.endpoint.EndpointMapperFactory\n"
  },
  {
    "path": "core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.core.filter.CoreFilterConfiguration\norg.apache.servicecomb.core.invocation.CoreInvocationConfiguration\norg.apache.servicecomb.core.governance.CoreGovernanceConfiguration\norg.apache.servicecomb.core.exception.CoreExceptionConfiguration\norg.apache.servicecomb.core.ServiceCombCoreConfiguration\n"
  },
  {
    "path": "core/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: -500\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\npublic class Config {\n  private static int clientThread;\n\n  private static String transport;\n\n  private static String mode;\n\n  public static String getTransport() {\n    return transport;\n  }\n\n  public static void setTransport(String transport) {\n    Config.transport = transport;\n  }\n\n  public static int getClientThread() {\n    return clientThread;\n  }\n\n  public static void setClientThread(int clientThread) {\n    Config.clientThread = clientThread;\n  }\n\n  public static String getMode() {\n    return mode;\n  }\n\n  public static void setMode(String mode) {\n    Config.mode = mode;\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestConfig {\n  @Test\n  public void testConstants() {\n    Assertions.assertEquals(\"x-cse-context\", CoreConst.CSE_CONTEXT);\n    Assertions.assertEquals(\"rest\", CoreConst.RESTFUL);\n    Assertions.assertEquals(\"\", CoreConst.ANY_TRANSPORT);\n    Assertions.assertEquals(\"latest\", CoreConst.VERSION_RULE_LATEST);\n    Assertions.assertEquals(\"0.0.0.0+\", CoreConst.DEFAULT_VERSION_RULE);\n  }\n\n  @Test\n  public void testHttpResponse() {\n    String objectString = new String(\"Unit Testing\");\n    Response oResponse = Response.success(objectString, Status.OK);\n\n    Assertions.assertTrue(oResponse.isSucceed());\n\n    oResponse = Response.succResp(objectString);\n    Assertions.assertTrue(oResponse.isSucceed());\n    Assertions.assertEquals(200, oResponse.getStatusCode());\n\n    Throwable oThrowable = new Throwable(\"Error\");\n\n    oResponse = Response.consumerFailResp(oThrowable);\n    Assertions.assertTrue(oResponse.isFailed());\n\n    oResponse = Response.providerFailResp(oThrowable);\n    Assertions.assertTrue(oResponse.isFailed());\n  }\n\n  @Test\n  public void testHttpStatus() {\n    StatusType oStatus = new HttpStatus(204, \"InternalServerError\");\n    Assertions.assertEquals(\"InternalServerError\", oStatus.getReasonPhrase());\n  }\n\n  @Test\n  public void testContextUtils() {\n    ThreadLocal<InvocationContext> contextMgr = new ThreadLocal<>();\n    Assertions.assertEquals(contextMgr.get(), ContextUtils.getInvocationContext());\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    invocation.addContext(\"test1\", \"testObject\");\n\n    Assertions.assertEquals(\"testObject\", invocation.getContext(\"test1\"));\n\n    Map<String, String> context = new HashMap<>();\n    context.put(\"test2\", new String(\"testObject\"));\n    invocation.setContext(context);\n    Assertions.assertEquals(context, invocation.getContext());\n\n    invocation.setStatus(Status.OK);\n    Assertions.assertEquals(200, invocation.getStatus().getStatusCode());\n\n    invocation.setStatus(204);\n    Assertions.assertEquals(204, invocation.getStatus().getStatusCode());\n\n    invocation.setStatus(Status.OK);\n    Assertions.assertEquals((Status.OK).getStatusCode(), invocation.getStatus().getStatusCode());\n\n    invocation.setStatus(203, \"Done\");\n    Assertions.assertEquals(203, invocation.getStatus().getStatusCode());\n\n    ContextUtils.setInvocationContext(invocation);\n    Assertions.assertEquals(invocation, ContextUtils.getInvocationContext());\n\n    ContextUtils.removeInvocationContext();\n    Assertions.assertNull(ContextUtils.getInvocationContext());\n  }\n\n  @Test\n  public void testResponse() {\n    Response response = Response.create(400, \"test\", null);\n    InvocationException exception = response.getResult();\n    Assertions.assertNull(exception.getErrorData());\n\n    response = Response.create(400, \"test\", \"errorData\");\n    exception = response.getResult();\n    Assertions.assertEquals(\"errorData\", exception.getErrorData());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestConfigurationSpringInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.logging.log4j.Level;\nimport org.apache.logging.log4j.core.config.Configurator;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.ArgumentMatchers;\nimport org.mockito.Mockito;\nimport org.mockito.stubbing.Answer;\nimport org.springframework.core.env.CompositePropertySource;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.MutablePropertySources;\nimport org.springframework.jndi.JndiPropertySource;\n\npublic class TestConfigurationSpringInitializer {\n  @BeforeEach\n  public void beforeTest() {\n    Configurator.setRootLevel(Level.OFF);\n\n    Configurator.setRootLevel(Level.INFO);\n  }\n\n  @AfterEach\n  public void afterTest() {\n\n  }\n\n  @Test\n  public void testSetEnvironment() {\n    ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\n    MutablePropertySources propertySources = new MutablePropertySources();\n    Map<String, String> propertyMap = new HashMap<>();\n    final String map0Key0 = \"map0-Key0\";\n    final String map1Key0 = \"map1-Key0\";\n    final String map2Key0 = \"map2-Key0\";\n    final String map3Key0 = \"map3-Key0\";\n    propertyMap.put(map0Key0, \"map0-Value0\");\n    propertyMap.put(map1Key0, \"map1-Value0\");\n    propertyMap.put(map2Key0, \"map2-Value0\");\n    propertyMap.put(map3Key0, \"map3-Value0\");\n\n    /*\n    propertySources\n    |- compositePropertySource0\n    |  |- mapPropertySource0\n    |  |  |- map0-Key0 = map0-Value0\n    |  |- compositePropertySource1\n    |     |- mapPropertySource1\n    |     |  |- map1-Key0 = map1-Value0\n    |     |- mapPropertySource2\n    |        |- map2-Key0 = map2-Value0\n    |     |- JndiPropertySource(mocked)\n    |- mapPropertySource3\n      |- map3-Key0 = map3-Value0\n     */\n    CompositePropertySource compositePropertySource0 = new CompositePropertySource(\"compositePropertySource0\");\n    propertySources.addFirst(compositePropertySource0);\n\n    HashMap<String, Object> map0 = new HashMap<>();\n    map0.put(map0Key0, propertyMap.get(map0Key0));\n    MapPropertySource mapPropertySource0 = new MapPropertySource(\"mapPropertySource0\", map0);\n    compositePropertySource0.addFirstPropertySource(mapPropertySource0);\n\n    CompositePropertySource compositePropertySource1 = new CompositePropertySource(\"compositePropertySource1\");\n    compositePropertySource0.addPropertySource(compositePropertySource1);\n    HashMap<String, Object> map1 = new HashMap<>();\n    map1.put(map1Key0, propertyMap.get(map1Key0));\n    MapPropertySource mapPropertySource1 = new MapPropertySource(\"mapPropertySource1\", map1);\n    compositePropertySource1.addPropertySource(mapPropertySource1);\n    HashMap<String, Object> map2 = new HashMap<>();\n    map2.put(map2Key0, propertyMap.get(map2Key0));\n    MapPropertySource mapPropertySource2 = new MapPropertySource(\"mapPropertySource2\", map2);\n    compositePropertySource1.addPropertySource(mapPropertySource2);\n    compositePropertySource1.addPropertySource(Mockito.mock(JndiPropertySource.class));\n\n    HashMap<String, Object> map3 = new HashMap<>();\n    map3.put(map3Key0, propertyMap.get(map3Key0));\n    MapPropertySource mapPropertySource3 = new MapPropertySource(\"mapPropertySource3\", map3);\n    compositePropertySource0.addPropertySource(mapPropertySource3);\n\n    Mockito.when(environment.getPropertySources()).thenReturn(propertySources);\n    Mockito.doAnswer((Answer<String>) invocation -> {\n      Object[] args = invocation.getArguments();\n      String propertyName = (String) args[0];\n\n      if (\"spring.config.name\".equals(propertyName) || \"spring.application.name\".equals(propertyName)) {\n        return null;\n      }\n\n      String value = propertyMap.get(propertyName);\n      if (null == value) {\n        Assertions.fail(\"get unexpected property name: \" + propertyName);\n      }\n      return value;\n    }).when(environment).getProperty(ArgumentMatchers.anyString(), ArgumentMatchers.eq(Object.class));\n  }\n\n  @Test\n  public void testSetEnvironmentOnEnvironmentName() {\n    // get environment name from spring.config.name\n    ConfigurableEnvironment environment0 = Mockito.mock(ConfigurableEnvironment.class);\n    MutablePropertySources propertySources0 = new MutablePropertySources();\n    Mockito.when(environment0.getPropertySources()).thenReturn(propertySources0);\n    Map<String, Object> map0 = new HashMap<>(1);\n    map0.put(\"spring.config.name\", \"application\");\n    propertySources0.addFirst(new MapPropertySource(\"mapPropertySource0\", map0));\n    Mockito.when(environment0.getProperty(\"spring.config.name\", Object.class)).thenReturn(\"application\");\n    Mockito.when(environment0.getProperty(\"spring.config.name\")).thenReturn(\"application\");\n\n    // get environment name from spring.application.name\n    ConfigurableEnvironment environment1 = Mockito.mock(ConfigurableEnvironment.class);\n    MutablePropertySources propertySources1 = new MutablePropertySources();\n    Mockito.when(environment1.getPropertySources()).thenReturn(propertySources1);\n    Map<String, Object> map1 = new HashMap<>(1);\n    map1.put(\"spring.application.name\", \"bootstrap\");\n    propertySources1.addFirst(new MapPropertySource(\"mapPropertySource1\", map1));\n    Mockito.when(environment1.getProperty(\"spring.application.name\", Object.class)).thenReturn(\"bootstrap\");\n    Mockito.when(environment1.getProperty(\"spring.application.name\")).thenReturn(\"bootstrap\");\n\n    // get environment name from className+hashcode\n    ConfigurableEnvironment environment2 = Mockito.mock(ConfigurableEnvironment.class);\n    MutablePropertySources propertySources2 = new MutablePropertySources();\n    Mockito.when(environment2.getPropertySources()).thenReturn(propertySources2);\n    Map<String, Object> map2 = new HashMap<>(1);\n    map2.put(\"key2\", \"value2\");\n    propertySources2.addFirst(new MapPropertySource(\"mapPropertySource2\", map2));\n    Mockito.when(environment2.getProperty(\"key2\", Object.class)).thenReturn(\"value2\");\n    Mockito.when(environment2.getProperty(\"key2\")).thenReturn(\"value2\");\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestEndpoint {\n  @Test\n  public void testEndpoint() {\n    Transport transport = Mockito.mock(Transport.class);\n    Mockito.when(transport.parseAddress(\"rest://123.6.6.6:8080\")).thenReturn(\"rest://123.6.6.6:8080\");\n\n    Endpoint endpoint = new Endpoint(transport, \"rest://123.6.6.6:8080\");\n    Assertions.assertEquals(endpoint.getAddress(), \"rest://123.6.6.6:8080\");\n    Assertions.assertEquals(endpoint.getEndpoint(), \"rest://123.6.6.6:8080\");\n    Assertions.assertEquals(endpoint.getTransport(), transport);\n    Assertions.assertEquals(endpoint.toString(), \"rest://123.6.6.6:8080\");\n  }\n\n  @Test\n  public void testEndpointAddressConstructor() {\n    Transport transport = Mockito.mock(Transport.class);\n    StatefulDiscoveryInstance instance = Mockito.mock(StatefulDiscoveryInstance.class);\n    Endpoint endpoint = new Endpoint(transport, \"rest://123.6.6.6:8080\", instance, \"iot://123.6.6.6:8080\");\n    Assertions.assertEquals(endpoint.getAddress(), \"iot://123.6.6.6:8080\");\n    Assertions.assertEquals(endpoint.getEndpoint(), \"rest://123.6.6.6:8080\");\n    Assertions.assertEquals(endpoint.getTransport(), transport);\n    Assertions.assertEquals(endpoint.toString(), \"rest://123.6.6.6:8080\");\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.apache.servicecomb.core.exception.CseException;\nimport org.apache.servicecomb.core.exception.ExceptionUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestException {\n  @Test\n  public void testCseException() {\n    CseException oException = new CseException(\"500\", \"InternalServerError\");\n    Assertions.assertEquals(\"500\", oException.getCode());\n    Assertions.assertEquals(\"ServiceDefinitionException Code:500, Message:InternalServerError\",\n        oException.toString());\n\n    oException = new CseException(\"503\", \"OwnException\", new Throwable());\n    Assertions.assertEquals(\"503\", oException.getCode());\n  }\n\n  @Test\n  public void testExceptionUtils() {\n    CseException oException = ExceptionUtils\n        .createCseException(\"servicecomb.handler.ref.not.exist\", new String(\"test\"));\n    Assertions.assertEquals(\"servicecomb.handler.ref.not.exist\", oException.getCode());\n\n    oException =\n        ExceptionUtils.createCseException(\"servicecomb.handler.ref.not.exist\", new Throwable(), new String(\"test\"));\n    Assertions.assertEquals(\"servicecomb.handler.ref.not.exist\", oException.getCode());\n\n    oException = ExceptionUtils.producerOperationNotExist(\"servicecomb.error\", \"unit-testing\");\n    Assertions.assertEquals(\"servicecomb.producer.operation.not.exist\", oException.getCode());\n\n    oException = ExceptionUtils.handlerRefNotExist(\"servicecomb.double.error\");\n    Assertions.assertEquals(\"servicecomb.handler.ref.not.exist\", oException.getCode());\n\n    oException = ExceptionUtils.lbAddressNotFound(\"microServiceName\", \"my rule my world\", \"transportChannel\");\n    Assertions.assertEquals(\"servicecomb.lb.no.available.address\", oException.getCode());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestInvocation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.event.InvocationBaseEvent;\nimport org.apache.servicecomb.core.event.InvocationBusinessMethodStartEvent;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.core.tracing.BraveTraceIdGenerator;\nimport org.apache.servicecomb.core.tracing.TraceIdGenerator;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestInvocation {\n\n  @Mocked\n  Endpoint endpoint;\n\n  @Mocked\n  OperationMeta operationMeta;\n\n  @Mocked\n  InvocationRuntimeType invocationRuntimeType;\n\n  static long nanoTime = 123;\n\n  @BeforeClass\n  public static void classSetup() {\n    EventManager.eventBus = new EventBus();\n  }\n\n  protected static void mockNonaTime() {\n    new MockUp<System>() {\n      @Mock\n      long nanoTime() {\n        return nanoTime;\n      }\n    };\n  }\n\n  @AfterClass\n  public static void classTeardown() {\n    EventManager.eventBus = new EventBus();\n  }\n\n  @Test\n  public void onStart() {\n    Holder<Invocation> result = new Holder<>();\n    Object subscriber = new Object() {\n      @Subscribe\n      public void onStart(InvocationStartEvent event) {\n        result.value = event.getInvocation();\n      }\n    };\n    EventManager.register(subscriber);\n\n    Invocation invocation = new Invocation(endpoint, operationMeta, null);\n    invocation.onStart();\n\n    Assertions.assertSame(invocation, result.value);\n    EventManager.unregister(subscriber);\n  }\n\n  @Test\n  public void onFinish() {\n    mockNonaTime();\n\n    Holder<InvocationFinishEvent> result = new Holder<>();\n    Object subscriber = new Object() {\n      @Subscribe\n      public void onStart(InvocationFinishEvent event) {\n        result.value = event;\n      }\n    };\n    EventManager.register(subscriber);\n\n    Invocation invocation = new Invocation(endpoint, operationMeta, null);\n    Assertions.assertFalse(invocation.isFinished());\n    Response response = Response.succResp(null);\n    invocation.onFinish(response);\n\n    Assertions.assertSame(invocation, result.value.getInvocation());\n    Assertions.assertSame(response, result.value.getResponse());\n    Assertions.assertTrue(invocation.isFinished());\n\n    // should not post event again\n    InvocationFinishEvent oldEvent = result.value;\n    invocation.onFinish(null);\n    Assertions.assertSame(oldEvent, result.value);\n\n    EventManager.unregister(subscriber);\n  }\n\n  @Test\n  public void isConsumer_yes() {\n    Invocation invocation = new Invocation(endpoint, operationMeta, null);\n    Assertions.assertFalse(invocation.isConsumer());\n  }\n\n  @Test\n  public void isConsumer_no(@Mocked ReferenceConfig referenceConfig) {\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null);\n    Assertions.assertTrue(invocation.isConsumer());\n  }\n\n  @Test\n  public void localContext(@Mocked ReferenceConfig referenceConfig) {\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null);\n\n    invocation.addLocalContext(\"k\", 1);\n    Assertions.assertSame(invocation.getHandlerContext(), invocation.getLocalContext());\n    Assertions.assertEquals(1, (int) invocation.getLocalContext(\"k\"));\n  }\n\n  @Test\n  public void traceId_fromContext(@Mocked ReferenceConfig referenceConfig) {\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null);\n    invocation.addContext(CoreConst.TRACE_ID_NAME, \"abc\");\n\n    invocation.onStart();\n\n    Assertions.assertEquals(\"abc\", invocation.getTraceId());\n    Assertions.assertEquals(\"abc\", invocation.getTraceId(CoreConst.TRACE_ID_NAME));\n  }\n\n  @Test\n  public void traceId_consumerCreateTraceId(@Mocked ReferenceConfig referenceConfig) {\n    TraceIdGenerator generator = SPIServiceUtils.getTargetService(TraceIdGenerator.class, BraveTraceIdGenerator.class);\n    new Expectations(generator) {\n      {\n        generator.generate();\n        result = \"abc\";\n      }\n    };\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null);\n\n    invocation.onStart();\n\n    Assertions.assertEquals(\"abc\", invocation.getTraceId());\n    Assertions.assertEquals(\"abc\", invocation.getTraceId(CoreConst.TRACE_ID_NAME));\n  }\n\n  @Test\n  public void traceId_fromRequest(@Mocked Endpoint endpoint, @Mocked HttpServletRequestEx requestEx) {\n    new Expectations() {\n      {\n        requestEx.getHeader(CoreConst.TRACE_ID_NAME);\n        result = \"abc\";\n      }\n    };\n    Invocation invocation = new Invocation(endpoint, operationMeta, null);\n\n    invocation.onStart(requestEx);\n\n    Assertions.assertEquals(\"abc\", invocation.getTraceId());\n    Assertions.assertEquals(\"abc\", invocation.getTraceId(CoreConst.TRACE_ID_NAME));\n  }\n\n  @Test\n  public void traceId_producerCreateTraceId(@Mocked Endpoint endpoint, @Mocked HttpServletRequestEx requestEx) {\n\n    TraceIdGenerator generator = SPIServiceUtils.getTargetService(TraceIdGenerator.class, BraveTraceIdGenerator.class);\n    new Expectations(generator) {\n      {\n        generator.generate();\n        result = \"abc\";\n      }\n    };\n    Invocation invocation = new Invocation(endpoint, operationMeta, null);\n\n    invocation.onStart(requestEx);\n\n    Assertions.assertEquals(\"abc\", invocation.getTraceId());\n    Assertions.assertEquals(\"abc\", invocation.getTraceId(CoreConst.TRACE_ID_NAME));\n  }\n\n  @Test\n  public void traceIdGeneratorInit(@Mocked TraceIdGenerator gen1, @Mocked TraceIdGenerator gen2,\n      @Mocked TraceIdGenerator gen3, @Mocked TraceIdGenerator gen4) {\n    new Expectations(SPIServiceUtils.class) {\n      {\n        gen1.getName();\n        result = \"zipkin\";\n\n        gen3.getName();\n        result = \"apm\";\n\n        gen2.getName();\n        result = \"zipkin\";\n\n        gen4.getName();\n        result = \"apm\";\n\n        SPIServiceUtils.getOrLoadSortedService(TraceIdGenerator.class);\n        result = Arrays.asList(gen1, gen3, gen2, gen4);\n      }\n    };\n\n    MatcherAssert.assertThat(Invocation.loadTraceIdGenerators(), Matchers.containsInAnyOrder(gen1, gen3));\n  }\n\n  InvocationBaseEvent invocationBaseEvent;\n\n  @Test\n  public void test_business_execute_time_correct() {\n    Object listener = new Object() {\n      @Subscribe\n      public void onBusinessMethodStart(InvocationBusinessMethodStartEvent event) {\n        invocationBaseEvent = event;\n      }\n    };\n    EventManager.getEventBus().register(listener);\n    Invocation invocation = new Invocation(endpoint, operationMeta, null);\n    mockNonaTime();\n    invocation.onBusinessMethodStart();\n    EventManager.getEventBus().unregister(listener);\n\n    Assertions.assertSame(invocation, invocationBaseEvent.getInvocation());\n    nanoTime++;\n    invocation.onBusinessFinish();\n    Assertions.assertEquals(1, invocation.getInvocationStageTrace().calcBusinessExecute());\n  }\n\n  @Test\n  public void marker(@Mocked ReferenceConfig referenceConfig) {\n    Invocation.INVOCATION_ID.set(0);\n\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null);\n    invocation.addContext(CoreConst.TRACE_ID_NAME, \"abc\");\n    invocation.onStart();\n    Assertions.assertEquals(\"abc\", invocation.getTraceIdLogger().getName());\n\n    invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null);\n    invocation.addContext(CoreConst.TRACE_ID_NAME, \"abc\");\n    invocation.onStart();\n    Assertions.assertEquals(\"abc\", invocation.getTraceIdLogger().getName());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestSCBApplicationListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.context.event.ContextClosedEvent;\nimport org.springframework.core.env.Environment;\n\npublic class TestSCBApplicationListener {\n  @BeforeEach\n  public void before() {\n  }\n\n  @AfterAll\n  public static void classTeardown() {\n  }\n\n  @Test\n  public void onApplicationEvent_close() {\n    ContextClosedEvent contextClosedEvent = Mockito.mock(ContextClosedEvent.class);\n    Environment environment = Mockito.mock(Environment.class);\n    SCBEngine scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n    scbEngine.setEnvironment(environment);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    scbEngine.setStatus(SCBStatus.UP);\n\n    SCBApplicationListener listener = new SCBApplicationListener(scbEngine);\n    listener.onApplicationEvent(contextClosedEvent);\n\n    Assertions.assertEquals(SCBStatus.DOWN, scbEngine.getStatus());\n\n    scbEngine.destroy();\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/TestTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core;\n\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.core.env.Environment;\n\npublic class TestTransport {\n  @BeforeAll\n  public static void classSetup() {\n\n  }\n\n  @AfterAll\n  public static void classTeardown() {\n  }\n\n  @Test\n  public void testEndpoint() throws Exception {\n    Endpoint oEndpoint = new Endpoint(new Transport() {\n      @Override\n      public Object parseAddress(String address) {\n        return \"127.0.0.1\";\n      }\n\n      @Override\n      public void setEnvironment(Environment environment) {\n\n      }\n      @Override\n      public boolean init() {\n        return true;\n      }\n\n      @Override\n      public String getName() {\n        return \"test\";\n      }\n\n      @Override\n      public Endpoint getEndpoint() {\n        return (new Endpoint(this, \"testEndpoint\"));\n      }\n\n      @Override\n      public Endpoint getPublishEndpoint() {\n        return (new Endpoint(this, \"testEndpoint\"));\n      }\n    }, \"rest://127.0.0.1:8080\");\n    oEndpoint.getTransport().init();\n    Assertions.assertEquals(\"rest://127.0.0.1:8080\", oEndpoint.getEndpoint());\n    Assertions.assertEquals(\"127.0.0.1\", oEndpoint.getAddress());\n    Assertions.assertEquals(\"test\", oEndpoint.getTransport().getName());\n    Assertions.assertEquals(\"rest://127.0.0.1:8080\", oEndpoint.getEndpoint());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/consumer/TestReactiveResponseExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.consumer;\n\nimport org.apache.servicecomb.core.provider.consumer.ReactiveResponseExecutor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestReactiveResponseExecutor {\n  @Test\n  public void testReactiveResponseExecutor() {\n    ReactiveResponseExecutor executor = new ReactiveResponseExecutor();\n    Runnable cmd = Mockito.mock(Runnable.class);\n    boolean validAssert = true;\n    try {\n      executor.execute(cmd);\n    } catch (Exception e) {\n      validAssert = false;\n    }\n    Assertions.assertTrue(validAssert);\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/consumer/TestSyncResponseExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.consumer;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.provider.consumer.SyncResponseExecutor;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestSyncResponseExecutor {\n  @Test\n  public void testSyncResponseExecutor() {\n    SyncResponseExecutor executor = new SyncResponseExecutor();\n    Runnable cmd = Mockito.mock(Runnable.class);\n    Response response = Mockito.mock(Response.class);\n    Invocation invocation = Mockito.mock(Invocation.class);\n    executor.execute(cmd);\n    executor.setResponse(response);\n\n    try {\n      Response responseValue = executor.waitResponse(invocation);\n      Assertions.assertNotNull(responseValue);\n    } catch (Exception e) {\n      Assertions.assertNotNull(e);\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/definition/MicroServicePropertyExtendedStub.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.definition;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.PropertyExtended;\n\npublic class MicroServicePropertyExtendedStub implements PropertyExtended {\n  @Override\n  public Map<String, String> getExtendedProperties() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/definition/OperationConfigTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.definition;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\n\nclass OperationConfigTest {\n  OperationConfig config = new OperationConfig();\n\n  @Nested\n  class InPoolTimeout {\n    @Test\n    void should_get_rest_value() {\n      config.setMsDefaultRequestWaitInPoolTimeout(1);\n      config.setMsRestRequestWaitInPoolTimeout(2);\n\n      long nano = TimeUnit.MILLISECONDS.toNanos(2);\n      assertThat(config.getNanoRestRequestWaitInPoolTimeout()).isEqualTo(nano);\n      assertThat(config.getNanoRequestWaitInPoolTimeout(CoreConst.RESTFUL)).isEqualTo(nano);\n    }\n\n    @Test\n    void should_get_highway_value() {\n      config.setMsDefaultRequestWaitInPoolTimeout(1);\n      config.setMsHighwayRequestWaitInPoolTimeout(2);\n\n      long nano = TimeUnit.MILLISECONDS.toNanos(2);\n      assertThat(config.getNanoHighwayRequestWaitInPoolTimeout()).isEqualTo(nano);\n      assertThat(config.getNanoRequestWaitInPoolTimeout(CoreConst.HIGHWAY)).isEqualTo(nano);\n    }\n\n    @Test\n    void should_support_register_customize_transport() {\n      config.setMsDefaultRequestWaitInPoolTimeout(1);\n      config.registerRequestWaitInPoolTimeout(\"abc\", 2);\n\n      long nano = TimeUnit.MILLISECONDS.toNanos(2);\n      assertThat(config.getNanoRequestWaitInPoolTimeout(\"abc\")).isEqualTo(nano);\n    }\n\n    @Test\n    void should_get_invocation_timeout_value() {\n      config.setMsInvocationTimeout(1);\n\n      long nano = TimeUnit.MILLISECONDS.toNanos(1);\n      assertThat(config.getNanoInvocationTimeout()).isEqualTo(nano);\n      assertThat(config.getMsInvocationTimeout()).isEqualTo(1);\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/definition/TestMicroserviceMetaManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.definition;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestMicroserviceMetaManager {\n\n  @Test\n  public void testEnsureFindSchemaMeta() {\n    SchemaMeta meta = Mockito.mock(SchemaMeta.class);\n    MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    Mockito.when(microserviceMeta.ensureFindSchemaMeta(\"yhfghj\")).thenReturn(meta);\n    Assertions.assertEquals(meta, microserviceMeta.ensureFindSchemaMeta(\"yhfghj\"));\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/event/TestInvocationStartEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.event;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestInvocationStartEvent {\n  InvocationStartEvent event;\n\n  @Test\n  public void construct() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    event = new InvocationStartEvent(invocation);\n\n    Assertions.assertSame(invocation, event.getInvocation());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/exception/ExceptionsTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.exception;\n\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\nimport static org.assertj.core.api.Assertions.assertThat;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\nimport java.util.Collections;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.Test;\n\nimport io.vertx.core.json.Json;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nclass ExceptionsTest {\n\n  private static final ObjectMapper objectMapper = new ObjectMapper();\n\n  @Test\n  void should_not_convert_invocation_exception() {\n    InvocationException exception = Exceptions.genericConsumer(\"msg\");\n\n    assertThat(Exceptions.convert(null, exception, BAD_REQUEST))\n        .isSameAs(exception);\n  }\n\n  @Test\n  void should_convert_unknown_client_exception_to_invocation_exception() {\n    IllegalStateException exception = new IllegalStateException(\"msg\");\n\n    InvocationException invocationException = Exceptions.convert(null, exception, BAD_REQUEST);\n\n    assertThat(invocationException).hasCause(exception);\n    assertThat(invocationException.getStatus()).isEqualTo(BAD_REQUEST);\n    assertThat(invocationException.getErrorData()).isInstanceOf(CommonExceptionData.class);\n\n    try {\n      assertThat(objectMapper.readTree(Json.encode(invocationException.getErrorData())))\n          .isEqualTo(objectMapper.readTree(\"{\\\"code\\\":\\\"SCB.00000000\\\",\\\"message\\\":\\\"Unexpected exception when processing none. msg\\\"}\"));\n    } catch (Exception e) {\n      throw new AssertionError(\"Error during JSON comparison: \" + e.getMessage(), e);\n    }\n  }\n\n  @Test\n  void should_convert_unknown_server_exception_to_invocation_exception() {\n    IllegalStateException exception = new IllegalStateException(\"msg\");\n\n    InvocationException invocationException = Exceptions.convert(null, exception, INTERNAL_SERVER_ERROR);\n\n    assertThat(invocationException).hasCause(exception);\n    assertThat(invocationException.getStatus()).isEqualTo(INTERNAL_SERVER_ERROR);\n    assertThat(invocationException.getErrorData()).isInstanceOf(CommonExceptionData.class);\n\n    try {\n      assertThat(objectMapper.readTree(Json.encode(invocationException.getErrorData())))\n          .isEqualTo(objectMapper.readTree(\"{\\\"code\\\":\\\"SCB.50000000\\\",\\\"message\\\":\\\"Unexpected exception when processing none. msg\\\"}\"));\n    } catch (Exception e) {\n      throw new AssertionError(\"Error during JSON comparison: \" + e.getMessage(), e);\n    }\n  }\n\n  static class ThrowExceptionWhenConvert implements ExceptionConverter<Throwable> {\n    @Override\n    public int getOrder() {\n      return Integer.MIN_VALUE;\n    }\n\n    @Override\n    public boolean canConvert(Throwable throwable) {\n      return true;\n    }\n\n    @Override\n    public InvocationException convert(Invocation invocation, Throwable throwable, StatusType genericStatus) {\n      throw new RuntimeExceptionWithoutStackTrace(\"mock exception when convert\");\n    }\n  }\n\n  @Test\n  void should_protect_when_converter_throw_exception() {\n    DefaultExceptionProcessor processor = new DefaultExceptionProcessor()\n        .setConverters(Collections.singletonList(new ThrowExceptionWhenConvert()));\n\n    try (LogCollector logCollector = new LogCollector()) {\n      InvocationException exception = processor\n          .convert(null, new RuntimeExceptionWithoutStackTrace(\"exception need convert\"), BAD_REQUEST);\n\n      assertThat(exception.getStatus())\n          .isSameAs(INTERNAL_SERVER_ERROR);\n      assertThat(exception.getErrorData().toString())\n          .isEqualTo(\"CommonExceptionData{code='SCB.50000000', message='Internal Server Error', dynamic={}}\");\n      assertThat(logCollector.getLastEvents().getMessage().getFormattedMessage().replace(\"\\r\\n\", \"\\n\"))\n          .isEqualTo(\"BUG: ExceptionConverter.convert MUST not throw exception, please fix it.\\n\"\n              + \"original exception :org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace: exception need convert\\n\"\n              + \"converter exception:org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace: mock exception when convert\\n\");\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/exception/converter/TimeoutExceptionConverterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.exception.converter;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.concurrent.TimeoutException;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.Test;\n\nclass TimeoutExceptionConverterTest {\n  private InvocationException convert() {\n    TimeoutException timeoutException = new TimeoutException(\n        \"The timeout period of 30000ms has been exceeded while executing GET /xxx for server 1.1.1.1:8080\");\n\n    return Exceptions.convert(null, timeoutException, Status.BAD_REQUEST);\n  }\n\n  @Test\n  void should_not_leak_server_ip() {\n    InvocationException exception = convert();\n\n    assertThat(exception)\n        .hasMessage(\n            \"InvocationException: code=408;msg=CommonExceptionData{code='SCB.00000000', message='Request Timeout.', dynamic={}}\");\n  }\n\n  @Test\n  void should_log_detail() {\n    try (LogCollector logCollector = new LogCollector()) {\n      convert();\n\n      assertThat(logCollector.getLastEvents().getMessage().getFormattedMessage())\n          .isEqualTo(\n              \"Request timeout, Details: The timeout period of 30000ms has been exceeded while executing GET /xxx for server 1.1.1.1:8080.\");\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/executor/TestExecutorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.executor;\n\nimport java.util.concurrent.Executor;\n\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport mockit.Expectations;\nimport mockit.Mocked;\n\npublic class TestExecutorManager {\n  @Mocked\n  Executor defaultExecutor;\n\n  ExecutorManager executorManager = new ExecutorManager();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setup() {\n    executorManager.setEnvironment(environment);\n  }\n\n  @After\n  public void teardown() {\n  }\n\n  @Test\n  public void findExecutor_oneParam(@Mocked Executor executor, @Mocked OperationMeta operationMeta) {\n    new Expectations(BeanUtils.class) {\n      {\n        BeanUtils.getBean(ExecutorManager.EXECUTOR_DEFAULT);\n        result = executor;\n      }\n    };\n\n    Assertions.assertSame(executor, executorManager.findExecutor(operationMeta));\n  }\n\n  @Test\n  public void findExecutor_twoParam_opCfg_withoutOpDef(@Mocked Executor executor,\n      @Mocked OperationMeta operationMeta) {\n    // String schemaQualifiedName = \"schemaId.opId\";\n    String microserviceQualifiedName = \"microserviceName.schemaId.opId\";\n    String opBeanId = \"opBeanId\";\n    Mockito.when(environment.getProperty(\n        ExecutorManager.KEY_EXECUTORS_PREFIX + microserviceQualifiedName)).thenReturn(opBeanId);\n    new Expectations(BeanUtils.class) {\n      {\n        operationMeta.getMicroserviceQualifiedName();\n        result = microserviceQualifiedName;\n        BeanUtils.getBean(opBeanId);\n        result = executor;\n      }\n    };\n\n    Assertions.assertSame(executor, executorManager.findExecutor(operationMeta, null));\n  }\n\n  @Test\n  public void findExecutor_twoParam_opCfg_withOpDef(@Mocked Executor executor,\n      @Mocked Executor defExecutor,\n      @Mocked OperationMeta operationMeta) {\n    String microserviceQualifiedName = \"microserviceName.schemaId.opId\";\n    String opBeanId = \"opBeanId\";\n    Mockito.when(environment.getProperty(\n        ExecutorManager.KEY_EXECUTORS_PREFIX + microserviceQualifiedName)).thenReturn(opBeanId);\n    new Expectations(BeanUtils.class) {\n      {\n        operationMeta.getMicroserviceQualifiedName();\n        result = microserviceQualifiedName;\n        BeanUtils.getBean(opBeanId);\n        result = executor;\n      }\n    };\n\n    Assertions.assertSame(executor, executorManager.findExecutor(operationMeta, defExecutor));\n  }\n\n  @Test\n  public void findExecutor_twoParam_schemaCfg_withOpDef(@Mocked OperationMeta operationMeta,\n      @Mocked Executor defExecutor) {\n    Assertions.assertSame(defExecutor, executorManager.findExecutor(operationMeta, defExecutor));\n  }\n\n  @Test\n  public void findExecutor_twoParam_schemaCfg_withoutOpDef(@Mocked Executor executor,\n      @Mocked OperationMeta operationMeta) {\n    String microserviceName = \"serviceName\";\n    String schemaName = \"schemaId\";\n    String opBeanId = \"opBeanId\";\n    Mockito.when(environment.getProperty(ExecutorManager.KEY_EXECUTORS_PREFIX + microserviceName + \".\" + schemaName))\n        .thenReturn(opBeanId);\n    new Expectations(BeanUtils.class) {\n      {\n        operationMeta.getSchemaId();\n        result = schemaName;\n        operationMeta.getMicroserviceName();\n        result = microserviceName;\n        BeanUtils.getBean(opBeanId);\n        result = executor;\n      }\n    };\n    Assertions.assertSame(executor, executorManager.findExecutor(operationMeta, null));\n  }\n\n  @Test\n  public void findExecutor_twoParam_defaultCfg(@Mocked Executor executor,\n      @Mocked SchemaMeta schemaMeta,\n      @Mocked OperationMeta operationMeta) {\n    String beanId = \"beanId\";\n    Mockito.when(environment.getProperty(ExecutorManager.KEY_EXECUTORS_DEFAULT)).thenReturn(beanId);\n    new Expectations(BeanUtils.class) {\n      {\n        BeanUtils.getBean(beanId);\n        result = executor;\n      }\n    };\n\n    Assertions.assertSame(executor, executorManager.findExecutor(operationMeta, null));\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/executor/TestGroupExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.executor;\n\nimport static org.apache.servicecomb.core.executor.GroupExecutor.KEY_CORE_THREADS;\nimport static org.apache.servicecomb.core.executor.GroupExecutor.KEY_GROUP;\nimport static org.apache.servicecomb.core.executor.GroupExecutor.KEY_MAX_IDLE_SECOND;\nimport static org.apache.servicecomb.core.executor.GroupExecutor.KEY_MAX_QUEUE_SIZE;\nimport static org.apache.servicecomb.core.executor.GroupExecutor.KEY_MAX_THREADS;\nimport static org.apache.servicecomb.core.executor.GroupExecutor.KEY_OLD_MAX_THREAD;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.Executor;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport mockit.Deencapsulation;\n\npublic class TestGroupExecutor {\n  String strThreadTest = \"default\";\n\n  @BeforeEach\n  public void setup() {\n    Mockito.when(environment.getProperty(KEY_GROUP, int.class, 2)).thenReturn(2);\n    Mockito.when(environment.getProperty(KEY_CORE_THREADS, int.class, 25)).thenReturn(25);\n    Mockito.when(environment.getProperty(KEY_MAX_IDLE_SECOND, int.class, 60)).thenReturn(60);\n    Mockito.when(environment.getProperty(KEY_MAX_THREADS, int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(KEY_OLD_MAX_THREAD, int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(KEY_MAX_QUEUE_SIZE, int.class, Integer.MAX_VALUE))\n        .thenReturn(Integer.MAX_VALUE);\n  }\n\n  @AfterAll\n  public static void teardown() {\n  }\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  GroupExecutor groupExecutor = new GroupExecutor(environment);\n\n  @Test\n  public void groupCount() {\n    groupExecutor.initConfig();\n    Assertions.assertEquals(2, groupExecutor.groupCount);\n\n    Mockito.when(environment.getProperty(KEY_GROUP, int.class, 2)).thenReturn(4);\n    groupExecutor.initConfig();\n    Assertions.assertEquals(4, groupExecutor.groupCount);\n  }\n\n  @Test\n  public void coreThreads() {\n    groupExecutor.initConfig();\n    Assertions.assertEquals(25, groupExecutor.coreThreads);\n\n    Mockito.when(environment.getProperty(KEY_CORE_THREADS, int.class, 25)).thenReturn(100);\n    groupExecutor.initConfig();\n    Assertions.assertEquals(100, groupExecutor.coreThreads);\n  }\n\n  @Test\n  public void maxIdleInSecond() {\n    groupExecutor.initConfig();\n    Assertions.assertEquals(60, groupExecutor.maxIdleInSecond);\n\n    Mockito.when(environment.getProperty(KEY_MAX_IDLE_SECOND, int.class, 60)).thenReturn(100);\n    groupExecutor.initConfig();\n    Assertions.assertEquals(100, groupExecutor.maxIdleInSecond);\n  }\n\n  @Test\n  public void maxQueueSize() {\n    groupExecutor.initConfig();\n    Assertions.assertEquals(Integer.MAX_VALUE, groupExecutor.maxQueueSize);\n    Mockito.when(environment.getProperty(KEY_MAX_QUEUE_SIZE, int.class, Integer.MAX_VALUE)).thenReturn(100);\n    groupExecutor.initConfig();\n    Assertions.assertEquals(100, groupExecutor.maxQueueSize);\n  }\n\n  @Test\n  public void maxThreads() {\n    groupExecutor.initConfig();\n    Assertions.assertEquals(100, groupExecutor.maxThreads);\n\n    LogCollector collector = new LogCollector();\n    Mockito.when(environment.getProperty(KEY_OLD_MAX_THREAD, int.class, -1)).thenReturn(200);\n    groupExecutor.initConfig();\n    Assertions.assertEquals(200, groupExecutor.maxThreads);\n    Assertions.assertEquals(\n        \"servicecomb.executor.default.thread-per-group is deprecated, recommended to use servicecomb.executor.default.maxThreads-per-group.\",\n        collector.getEvents().get(collector.getEvents().size() - 2).getMessage().getFormattedMessage());\n    collector.tearDown();\n\n    Mockito.when(environment.getProperty(KEY_MAX_THREADS, int.class, -1)).thenReturn(300);\n    groupExecutor.initConfig();\n    Assertions.assertEquals(300, groupExecutor.maxThreads);\n  }\n\n  @Test\n  public void adjustCoreThreads() {\n    Mockito.when(environment.getProperty(KEY_MAX_THREADS, int.class, -1)).thenReturn(10);\n    LogCollector collector = new LogCollector();\n    groupExecutor.initConfig();\n    Assertions.assertEquals(10, groupExecutor.maxThreads);\n    Assertions.assertEquals(\n        \"coreThreads is bigger than maxThreads, change from 25 to 10.\",\n        collector.getEvents().get(collector.getEvents().size() - 2).getMessage().getFormattedMessage());\n    collector.tearDown();\n  }\n\n  @Test\n  public void testGroupExecutor() {\n    groupExecutor.init();\n    groupExecutor.execute(() -> {\n    });\n    Map<Long, Executor> threadExecutorMap = Deencapsulation.getField(groupExecutor, \"threadExecutorMap\");\n    Assertions.assertTrue((threadExecutorMap.size() > 0));\n\n    List<Executor> executorList = Deencapsulation.getField(groupExecutor, \"executorList\");\n    Assertions.assertTrue((executorList.size() > 1));\n\n    ReactiveExecutor oReactiveExecutor = new ReactiveExecutor();\n    oReactiveExecutor.execute(() -> strThreadTest = \"thread Ran\");\n    oReactiveExecutor.close();\n    Assertions.assertEquals(\"thread Ran\", strThreadTest);\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/executor/TestThreadPoolExecutorEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.executor;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.RejectedExecutionException;\nimport java.util.concurrent.TimeUnit;\nimport java.util.function.IntSupplier;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class TestThreadPoolExecutorEx {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestThreadPoolExecutorEx.class);\n\n  static class TestTask implements Runnable {\n    CountDownLatch notify = new CountDownLatch(1);\n\n    Future<?> future;\n\n    public void quit() throws ExecutionException, InterruptedException {\n      notify.countDown();\n      future.get();\n    }\n\n    @Override\n    public void run() {\n      try {\n        notify.await();\n      } catch (InterruptedException e) {\n        throw new IllegalStateException(e);\n      }\n    }\n  }\n\n  ThreadPoolExecutorEx executorEx = new ThreadPoolExecutorEx(2, 4, 2, TimeUnit.SECONDS,\n      new LinkedBlockingQueueEx(2), Executors.defaultThreadFactory());\n\n  public TestTask submitTask() {\n    TestTask task = new TestTask();\n    task.future = executorEx.submit(task);\n    return task;\n  }\n\n  @Test\n  public void schedule() throws ExecutionException, InterruptedException {\n    // init\n    Assertions.assertEquals(0, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(0, executorEx.getNotFinished());\n    Assertions.assertEquals(0, executorEx.getQueue().size());\n\n    // use core threads\n    TestTask t1 = submitTask();\n    Assertions.assertEquals(1, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(1, executorEx.getNotFinished());\n    Assertions.assertEquals(0, executorEx.getQueue().size());\n\n    TestTask t2 = submitTask();\n    Assertions.assertEquals(2, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(2, executorEx.getNotFinished());\n    Assertions.assertEquals(0, executorEx.getQueue().size());\n\n    // extend threads\n    TestTask t3 = submitTask();\n    Assertions.assertEquals(3, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(3, executorEx.getNotFinished());\n    Assertions.assertEquals(0, executorEx.getQueue().size());\n\n    TestTask t4 = submitTask();\n    Assertions.assertEquals(4, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(4, executorEx.getNotFinished());\n    Assertions.assertEquals(0, executorEx.getQueue().size());\n\n    // queue the tasks\n    TestTask t5 = submitTask();\n    Assertions.assertEquals(4, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(5, executorEx.getNotFinished());\n    Assertions.assertEquals(1, executorEx.getQueue().size());\n\n    TestTask t6 = submitTask();\n    Assertions.assertEquals(4, executorEx.getPoolSize());\n    Assertions.assertEquals(0, executorEx.getRejectedCount());\n    Assertions.assertEquals(6, executorEx.getNotFinished());\n    Assertions.assertEquals(2, executorEx.getQueue().size());\n\n    // reject the task\n    try {\n      submitTask();\n    } catch (RejectedExecutionException e) {\n\n    }\n    Assertions.assertEquals(4, executorEx.getPoolSize());\n    Assertions.assertEquals(1, executorEx.getRejectedCount());\n    Assertions.assertEquals(6, executorEx.getNotFinished());\n    Assertions.assertEquals(2, executorEx.getQueue().size());\n\n    // t1/t2/t3 finish\n    t1.quit();\n    t2.quit();\n    t3.quit();\n    Assertions.assertEquals(4, executorEx.getPoolSize());\n    Assertions.assertEquals(1, executorEx.getRejectedCount());\n    waitForResult(3, executorEx::getNotFinished);\n    waitForResult(0, executorEx.getQueue()::size);\n\n    // reuse thread\n    t3 = submitTask();\n    Assertions.assertEquals(4, executorEx.getPoolSize());\n    Assertions.assertEquals(1, executorEx.getRejectedCount());\n    waitForResult(4, executorEx::getNotFinished);\n    waitForResult(0, executorEx.getQueue()::size);\n\n    t3.quit();\n    t4.quit();\n    t5.quit();\n    t6.quit();\n    waitForResult(2, executorEx::getPoolSize);\n    executorEx.shutdown();\n  }\n\n  private void waitForResult(int expect, IntSupplier supplier) {\n    long max = 30000;\n    long waited = 0;\n\n    for (; ; ) {\n      if (waited > max) {\n        throw new IllegalStateException(\"timed out waiting.\");\n      }\n      int actual = supplier.getAsInt();\n      if (expect == actual) {\n        return;\n      }\n\n      LOGGER.info(\"waiting for thread result, expect:{}, actual: {}.\", expect, actual);\n      try {\n        TimeUnit.MILLISECONDS.sleep(200);\n        waited += 200;\n      } catch (InterruptedException e) {\n        throw new IllegalStateException(e);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/filter/FilterChainTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.filter;\n\nimport static org.apache.servicecomb.core.filter.FilterNode.buildChain;\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport java.util.List;\nimport java.util.Vector;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationConfig;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.filter.impl.ScheduleFilter;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport mockit.Expectations;\nimport mockit.Mocked;\n\npublic class FilterChainTest {\n  static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();\n\n  static String THREAD_NAME;\n\n  @Mocked\n  Invocation invocation;\n\n  @Mocked\n  OperationMeta operationMeta;\n\n  @Mocked\n  OperationConfig operationConfig;\n\n  List<String> msg = new Vector<>();\n\n  Filter recordThreadFilter = new AbstractFilter() {\n    @Override\n    public String getName() {\n      return \"f2\";\n    }\n\n    @Override\n    public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n      msg.add(Thread.currentThread().getName());\n      if (nextNode == null) {\n        return CompletableFuture.completedFuture(Response.ok(null));\n      }\n\n      return nextNode.onFilter(invocation);\n    }\n  };\n\n  Filter scheduler = new ScheduleFilter();\n\n  Filter exceptionFilter = new AbstractFilter() {\n    @Override\n    public String getName() {\n      return \"f1\";\n    }\n\n    @Override\n    public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n      throw new IllegalStateException(\"e1\");\n    }\n  };\n\n  @BeforeClass\n  public static void beforeClass() {\n    try {\n      THREAD_NAME = EXECUTOR.submit(() -> Thread.currentThread().getName()).get();\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  private void mockInvocation() {\n    new Expectations() {\n      {\n        invocation.getOperationMeta();\n        result = operationMeta;\n\n        operationMeta.getExecutor();\n        result = EXECUTOR;\n\n        operationConfig.getNanoRequestWaitInPoolTimeout(anyString);\n        result = Long.MAX_VALUE;\n      }\n    };\n  }\n\n  @Test\n  public void should_switch_thread_after_schedule() throws ExecutionException, InterruptedException {\n    mockInvocation();\n\n    buildChain(recordThreadFilter, scheduler, recordThreadFilter)\n        .onFilter(invocation)\n        .get();\n\n    assertThat(msg).containsExactly(\"main\", THREAD_NAME);\n  }\n\n  @Test\n  public void should_stop_chain_when_first_filter_throw_exception() {\n    ExecutionException executionException = (ExecutionException) catchThrowable(\n        () -> buildChain(exceptionFilter, recordThreadFilter)\n            .onFilter(invocation)\n            .get());\n\n    assertThat(msg).isEmpty();\n    assertThat(executionException.getCause())\n        .isInstanceOf(IllegalStateException.class)\n        .hasMessage(\"e1\");\n  }\n\n  @Test\n  public void should_stop_chain_when_middle_filter_throw_exception() {\n    ExecutionException executionException = (ExecutionException) catchThrowable(\n        () -> buildChain(recordThreadFilter, exceptionFilter, recordThreadFilter)\n            .onFilter(invocation)\n            .get());\n\n    assertThat(msg).containsExactly(\"main\");\n    assertThat(executionException.getCause())\n        .isInstanceOf(IllegalStateException.class)\n        .hasMessage(\"e1\");\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.filter.impl;\n\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\nimport static org.apache.servicecomb.core.exception.ExceptionCodes.DEFAULT_VALIDATE;\nimport static org.apache.servicecomb.core.exception.converter.ConstraintViolationExceptionConverter.KEY_CODE;\nimport static org.apache.servicecomb.core.filter.impl.ParameterValidatorFilter.ENABLE_EL;\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport java.util.List;\n\nimport org.apache.commons.lang3.reflect.MethodUtils;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.exception.converter.ConstraintViolationExceptionConverter;\nimport org.apache.servicecomb.core.exception.converter.ValidateDetail;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.MutablePropertySources;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\nimport jakarta.validation.Valid;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.NotNull;\nimport mockit.Expectations;\nimport mockit.Mocked;\n\npublic class ParameterValidatorFilterTest {\n  public static class BaseModel {\n    @NotNull(message = \"can not be null\")\n    private String name;\n\n    public String getName() {\n      return name;\n    }\n\n    public BaseModel setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  public static class Model extends BaseModel {\n    @NotBlank(message = \"can not be blank\")\n    @JsonProperty(value = \"nick-name\")\n    private String nickName;\n\n    public String getNickName() {\n      return nickName;\n    }\n\n    public Model setNickName(String nickName) {\n      this.nickName = nickName;\n      return this;\n    }\n  }\n\n  public static class Controller {\n    public void op(@NotNull(message = \"not null\") String query, @Valid Model model) {\n\n    }\n  }\n\n  ParameterValidatorFilter filter = new ParameterValidatorFilter();\n\n  @Mocked\n  Invocation invocation;\n\n  @Mocked\n  SwaggerProducerOperation operation;\n\n  ConfigurableEnvironment environment;\n\n  @Before\n  public void setUp() throws Exception {\n    environment = Mockito.mock(ConfigurableEnvironment.class);\n    SCBEngine engine = SCBBootstrap.createSCBEngineForTest(environment);\n    MutablePropertySources sources = new MutablePropertySources();\n\n    Mockito.when(environment.getProperty(ENABLE_EL, boolean.class, false)).thenReturn(false);\n    Mockito.when(environment.getPropertySources()).thenReturn(sources);\n    filter.setEnvironment(environment);\n    filter.afterPropertiesSet();\n    engine.setEnvironment(environment);\n    new Expectations() {\n      {\n        operation.getProducerInstance();\n        result = new Controller();\n\n        operation.getProducerMethod();\n        result = MethodUtils.getAccessibleMethod(Controller.class, \"op\", String.class, Model.class);\n\n        invocation.toProducerArguments();\n        result = new Object[] {null, new Model()};\n      }\n    };\n  }\n\n  private InvocationException getException() {\n    Throwable throwable = catchThrowable(() -> filter.onFilter(invocation, FilterNode.EMPTY).get());\n    return Exceptions.convert(invocation, throwable, BAD_REQUEST);\n  }\n\n  private CommonExceptionData getExceptionData() {\n    InvocationException invocationException = getException();\n    return (CommonExceptionData) invocationException.getErrorData();\n  }\n\n  @Test\n  public void status_code_should_be_bad_request() {\n    InvocationException invocationException = getException();\n\n    assertThat(invocationException.getStatusCode()).isEqualTo(BAD_REQUEST.getStatusCode());\n  }\n\n  @Test\n  public void error_code_and_message_should_be_build_in_value() {\n    Mockito.when(environment.getProperty(KEY_CODE, String.class, DEFAULT_VALIDATE)).thenReturn(DEFAULT_VALIDATE);\n    CommonExceptionData errorData = getExceptionData();\n\n    assertThat(errorData.getCode()).isEqualTo(DEFAULT_VALIDATE);\n    assertThat(errorData.getMessage()).isEqualTo(\"invalid parameters.\");\n  }\n\n  @Test\n  public void should_allow_customize_error_code_by_configuration() {\n    Mockito.when(environment.getProperty(KEY_CODE, String.class, DEFAULT_VALIDATE)).thenReturn(\"test.0001\");\n    SPIServiceUtils.getTargetService(ExceptionConverter.class, ConstraintViolationExceptionConverter.class);\n    CommonExceptionData errorData = getExceptionData();\n\n    assertThat(errorData.getCode()).isEqualTo(\"test.0001\");\n  }\n\n  @Test\n  public void should_use_json_property_value_as_property_name() {\n    CommonExceptionData errorData = getExceptionData();\n    List<ValidateDetail> details = errorData.getDynamic(\"validateDetail\");\n\n    assertThat(details.stream().map(ValidateDetail::getPropertyPath))\n        .contains(\"op.model.nick-name\");\n  }\n\n  @Test\n  public void should_include_all_validate_detail() {\n    CommonExceptionData errorData = getExceptionData();\n    List<ValidateDetail> details = errorData.getDynamic(\"validateDetail\");\n\n    assertThat(details.stream().map(ValidateDetail::getPropertyPath))\n        .contains(\"op.query\", \"op.model.name\", \"op.model.nick-name\");\n    assertThat(details.stream().map(ValidateDetail::getMessage))\n        .contains(\"not null\", \"can not be null\", \"can not be blank\");\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.filter.impl;\n\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport java.lang.reflect.Method;\nimport java.time.Duration;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.Test;\n\nimport mockit.Expectations;\nimport mockit.Injectable;\nimport mockit.Mocked;\nimport mockit.Verifications;\n\npublic class ProducerOperationFilterTest {\n  ProviderOperationFilter filter = new ProviderOperationFilter();\n\n  @Injectable\n  Invocation invocation;\n\n  @Mocked\n  SwaggerProducerOperation producerOperation;\n\n  static InvocationContext threadInvocationContext;\n\n  public static class Controller {\n    public void sync() {\n      threadInvocationContext = ContextUtils.getInvocationContext();\n    }\n\n    public void syncException() {\n      throw new RuntimeExceptionWithoutStackTrace(\"syncException\");\n    }\n\n    public CompletableFuture<Void> async() {\n      threadInvocationContext = ContextUtils.getInvocationContext();\n      return CompletableFuture.completedFuture(null);\n    }\n\n    public CompletableFuture<Void> asyncException() {\n      throw new RuntimeExceptionWithoutStackTrace(\"asyncException\");\n    }\n  }\n\n  @Test\n  public void should_record_invocation_trace_time() throws NoSuchMethodException {\n    setInvokeSyncMethod();\n    filter.onFilter(invocation, FilterNode.EMPTY);\n\n    new Verifications() {\n      {\n        invocation.onBusinessMethodStart();\n        times = 1;\n\n        invocation.onBusinessFinish();\n        times = 1;\n      }\n    };\n  }\n\n  private void setInvokeMethod(String name) throws NoSuchMethodException {\n    Controller instance = new Controller();\n    Method method = instance.getClass().getMethod(name);\n    new Expectations() {\n      {\n        producerOperation.getProducerInstance();\n        result = instance;\n\n        producerOperation.getProducerMethod();\n        result = method;\n      }\n    };\n  }\n\n  private void setInvokeSyncMethod() throws NoSuchMethodException {\n    setInvokeMethod(\"sync\");\n  }\n\n  private void setInvokeAsyncMethod() throws NoSuchMethodException {\n    setInvokeMethod(\"async\");\n  }\n\n  @Test\n  public void should_provide_thread_local_invocation_context_for_sync_method() throws NoSuchMethodException {\n    setInvokeSyncMethod();\n\n    filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(threadInvocationContext).isSameAs(invocation);\n  }\n\n  @Test\n  public void should_clear_thread_local_invocation_context_after_sync_method() throws NoSuchMethodException {\n    setInvokeSyncMethod();\n\n    filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(ContextUtils.getInvocationContext()).isNull();\n  }\n\n  @Test\n  public void should_catch_sync_business_exception() throws NoSuchMethodException {\n    setInvokeMethod(\"syncException\");\n\n    CompletableFuture<Response> future = filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(future)\n        .failsWithin(Duration.ofSeconds(1))\n        .withThrowableOfType(ExecutionException.class)\n        .withCauseExactlyInstanceOf(RuntimeExceptionWithoutStackTrace.class)\n        .withMessage(\"org.apache.servicecomb.foundation.test.scaffolding.exception\" +\n            \".RuntimeExceptionWithoutStackTrace: syncException\");\n  }\n\n  @Test\n  public void should_provide_thread_local_invocation_context_for_async_method() throws NoSuchMethodException {\n    setInvokeAsyncMethod();\n\n    filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(threadInvocationContext).isSameAs(invocation);\n  }\n\n  @Test\n  public void should_clear_thread_local_invocation_context_after_async_method() throws NoSuchMethodException {\n    setInvokeAsyncMethod();\n\n    filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(ContextUtils.getInvocationContext()).isNull();\n  }\n\n  @Test\n  public void should_catch_async_business_exception() throws NoSuchMethodException {\n    setInvokeMethod(\"asyncException\");\n\n    CompletableFuture<Response> future = filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(future)\n        .failsWithin(Duration.ofSeconds(1))\n        .withThrowableOfType(ExecutionException.class)\n        .withCauseExactlyInstanceOf(RuntimeExceptionWithoutStackTrace.class)\n        .withMessage(\"org.apache.servicecomb.foundation.test.scaffolding\" +\n            \".exception.RuntimeExceptionWithoutStackTrace: asyncException\");\n  }\n\n  @Test\n  public void should_unify_IllegalArgumentException_message_when_convert_exception() throws NoSuchMethodException {\n    setInvokeSyncMethod();\n    new Expectations() {\n      {\n        invocation.toProducerArguments();\n        result = new Object[] {1};\n      }\n    };\n    CompletableFuture<Response> future = filter.onFilter(invocation, FilterNode.EMPTY);\n\n    assertThat(future)\n        .failsWithin(Duration.ofSeconds(1))\n        .withThrowableOfType(ExecutionException.class)\n        .withCauseExactlyInstanceOf(IllegalArgumentException.class);\n\n    InvocationException throwable = Exceptions\n        .convert(invocation, catchThrowable(future::get), INTERNAL_SERVER_ERROR);\n    assertThat(throwable).hasCauseInstanceOf(IllegalArgumentException.class);\n    CommonExceptionData data = (CommonExceptionData) throwable.getErrorData();\n    assertThat(data.getMessage()).isEqualTo(\"Parameters not valid or types not match.\");\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/invocation/ProducerInvocationFlowTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.invocation;\n\nimport static java.util.concurrent.CompletableFuture.completedFuture;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.Test;\n\nimport mockit.Expectations;\nimport mockit.Injectable;\nimport mockit.Mocked;\nimport mockit.Verifications;\n\npublic class ProducerInvocationFlowTest {\n  class TestFlow extends ProducerInvocationFlow {\n    public TestFlow(InvocationCreator invocationCreator) {\n      super(invocationCreator);\n    }\n\n    @Override\n    protected Invocation sendCreateInvocationException(Throwable throwable) {\n      sendException = Exceptions.unwrap(throwable);\n      return null;\n    }\n\n    @Override\n    protected void endResponse(Invocation invocation, Response response) {\n      sendInvocation = invocation;\n    }\n  }\n\n  FilterNode filterNode = FilterNode.EMPTY;\n\n  Throwable sendException;\n\n  Invocation sendInvocation;\n\n  @Injectable\n  Invocation invocation;\n\n  @Mocked\n  MicroserviceMeta microserviceMeta;\n\n  @Test\n  public void should_send_exception_response_when_failed_to_create_invocation() {\n    RuntimeException exception = new RuntimeExceptionWithoutStackTrace();\n    TestFlow flow = new TestFlow(() -> {\n      throw exception;\n    });\n\n    flow.run();\n\n    assertThat(sendException).isSameAs(exception);\n  }\n\n  private void mockFilterChain() {\n    new Expectations() {\n      {\n        microserviceMeta.getProviderFilterChain();\n        result = filterNode;\n      }\n    };\n  }\n\n  @Test\n  public void should_start_invocation_when_succeed_to_create_invocation() {\n    mockFilterChain();\n    TestFlow flow = new TestFlow(() -> completedFuture(invocation));\n\n    flow.run();\n\n    new Verifications() {\n      {\n        invocation.onStart((HttpServletRequestEx) any);\n        times = 1;\n      }\n    };\n  }\n\n  @Test\n  public void should_send_response_when_invocation_success() {\n    mockFilterChain();\n    TestFlow flow = new TestFlow(() -> completedFuture(invocation));\n\n    flow.run();\n\n    assertThat(sendInvocation).isSameAs(invocation);\n  }\n\n  @Test\n  public void should_finish_invocation_when_invocation_success() {\n    mockFilterChain();\n    TestFlow flow = new TestFlow(() -> completedFuture(invocation));\n\n    flow.run();\n\n    new Verifications() {\n      {\n        invocation.onFinish((Response) any);\n        times = 1;\n      }\n    };\n  }\n\n  private void mockInvocationFailed() {\n    filterNode = new FilterNode(new AbstractFilter() {\n      @Override\n      public String getName() {\n        return \"test\";\n      }\n\n      @Override\n      public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n        throw new RuntimeExceptionWithoutStackTrace();\n      }\n    });\n    mockFilterChain();\n  }\n\n  @Test\n  public void should_send_response_when_invocation_fail() {\n    mockInvocationFailed();\n    TestFlow flow = new TestFlow(() -> completedFuture(invocation));\n\n    flow.run();\n\n    assertThat(sendInvocation).isSameAs(invocation);\n  }\n\n  @Test\n  public void should_finish_invocation_when_invocation_fail() {\n    mockInvocationFailed();\n    TestFlow flow = new TestFlow(() -> completedFuture(invocation));\n\n    flow.run();\n\n    new Verifications() {\n      {\n        invocation.onFinish((Response) any);\n        times = 1;\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.invocation;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestInvocationStageTrace {\n  Invocation invocation;\n\n  InvocationStageTrace stageTrace;\n\n  @Mocked\n  Endpoint endpoint;\n\n  @Mocked\n  ReferenceConfig referenceConfig;\n\n  @Mocked\n  OperationMeta operationMeta;\n\n  @Mocked\n  InvocationRuntimeType invocationRuntimeType;\n\n  Map<String, Object> args = new HashMap<>();\n\n  static long nanoTime = 0;\n\n  @BeforeClass\n  public static void classSetup() {\n    new MockUp<System>() {\n      @Mock\n      long nanoTime() {\n        return nanoTime;\n      }\n    };\n  }\n\n  @Test\n  public void consumer() {\n    invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, args);\n    stageTrace = new InvocationStageTrace(invocation);\n\n    stageTrace.startCreateInvocation(1);\n    nanoTime = 2;\n    stageTrace.finishCreateInvocation();\n    stageTrace.startConsumerConnection();\n    nanoTime = 3;\n    stageTrace.finishConsumerConnection();\n    stageTrace.startConsumerEncodeRequest();\n    nanoTime = 4;\n    stageTrace.finishConsumerEncodeRequest();\n    stageTrace.startConsumerSendRequest();\n    nanoTime = 5;\n    stageTrace.finishConsumerSendRequest();\n    stageTrace.startWaitResponse();\n    nanoTime = 6;\n    stageTrace.finishWaitResponse();\n    stageTrace.startConsumerDecodeResponse();\n    nanoTime = 7;\n    stageTrace.finishConsumerDecodeResponse();\n\n    stageTrace.finish();\n\n    Assertions.assertEquals(1f, stageTrace.calcPrepare(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConnection(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConsumerEncodeRequest(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConsumerSendRequest(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcWait(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConsumerDecodeResponse(), 0.1f);\n    Assertions.assertEquals(6f, stageTrace.calcTotal(), 0.1f);\n  }\n\n  @Test\n  public void producer() {\n    invocation = new Invocation(endpoint, operationMeta, args);\n    stageTrace = new InvocationStageTrace(invocation);\n\n    stageTrace.startCreateInvocation(1);\n    nanoTime = 2;\n    stageTrace.finishCreateInvocation();\n    stageTrace.startProviderDecodeRequest();\n    nanoTime = 3;\n    stageTrace.finishProviderDecodeRequest();\n    stageTrace.startProviderQueue();\n    nanoTime = 4;\n    stageTrace.finishProviderQueue();\n    stageTrace.startBusinessExecute();\n    nanoTime = 5;\n    stageTrace.finishBusinessExecute();\n    stageTrace.startProviderEncodeResponse();\n    nanoTime = 6;\n    stageTrace.finishProviderEncodeResponse();\n    stageTrace.startProviderSendResponse();\n    nanoTime = 7;\n    stageTrace.finishProviderSendResponse();\n\n    stageTrace.finish();\n\n    Assertions.assertEquals(1f, stageTrace.calcPrepare(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcQueue(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcProviderDecodeRequest(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcProviderEncodeResponse(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcBusinessExecute(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcProviderSendResponse(), 0.1f);\n    Assertions.assertEquals(6f, stageTrace.calcTotal(), 0.1f);\n  }\n\n  @Test\n  public void edge() {\n    invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, args);\n    stageTrace = new InvocationStageTrace(invocation);\n    invocation.setEdge();\n\n    stageTrace.startCreateInvocation(1);\n    nanoTime = 2;\n    stageTrace.finishCreateInvocation();\n    stageTrace.startProviderDecodeRequest();\n    nanoTime = 3;\n    stageTrace.finishProviderDecodeRequest();\n    stageTrace.startConsumerConnection();\n    nanoTime = 4;\n    stageTrace.finishConsumerConnection();\n    stageTrace.startConsumerEncodeRequest();\n    nanoTime = 5;\n    stageTrace.finishConsumerEncodeRequest();\n    stageTrace.startConsumerSendRequest();\n    nanoTime = 6;\n    stageTrace.finishConsumerSendRequest();\n    stageTrace.startWaitResponse();\n    nanoTime = 7;\n    stageTrace.finishWaitResponse();\n    stageTrace.startConsumerDecodeResponse();\n    nanoTime = 8;\n    stageTrace.finishConsumerDecodeResponse();\n    stageTrace.startProviderEncodeResponse();\n    nanoTime = 10;\n    stageTrace.finishProviderEncodeResponse();\n    stageTrace.startProviderSendResponse();\n    nanoTime = 11;\n    stageTrace.finishProviderSendResponse();\n    stageTrace.finish();\n\n    Assertions.assertEquals(1f, stageTrace.calcPrepare(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConnection(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConsumerEncodeRequest(), 0.1f);\n\n    Assertions.assertEquals(1f, stageTrace.calcConsumerSendRequest(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcWait(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcConsumerDecodeResponse(), 0.1f);\n    Assertions.assertEquals(2f, stageTrace.calcProviderEncodeResponse(), 0.1f);\n    Assertions.assertEquals(1f, stageTrace.calcProviderSendResponse(), 0.1f);\n\n    Assertions.assertEquals(10f, stageTrace.calcTotal(), 0.1f);\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/invocation/endpoint/EndpointTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.invocation.endpoint;\n\nimport static com.google.common.collect.ImmutableMap.of;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class EndpointTest {\n  public interface TestSchema {\n    void say(Endpoint endpoint);\n  }\n\n  @Test\n  void should_ignore_endpoint_when_generate_swagger() {\n    SwaggerGenerator generator = SwaggerGenerator.create(TestSchema.class);\n    OpenAPI swagger = generator.generate();\n\n    assertThat(swagger.getInfo().getTitle()).contains(\"EndpointTest$TestSchema\");\n    assertThat(swagger.getPaths()).containsKey(\"/say\");\n    assertThat(swagger.getPaths().get(\"/say\").getPost().getOperationId()).isEqualTo(\"say\");\n    assertThat(swagger.getPaths().get(\"/say\").getPost().getResponses()).containsKey(\"200\");\n  }\n\n  @Test\n  void should_set_endpoint_to_invocation_when_map_arguments() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    SwaggerConsumer consumer = environment\n        .createConsumer(TestSchema.class, SwaggerGenerator.generate(TestSchema.class));\n    SwaggerConsumerOperation operation = consumer.findOperation(\"say\");\n\n    Endpoint endpoint = new Endpoint(Mockito.mock(Transport.class), null);\n    Invocation invocation = Mockito.mock(Invocation.class);\n    Holder<Object> holder = new Holder<>();\n    Mockito\n        .doAnswer(invocationOnMock -> {\n          holder.value = invocationOnMock.getArguments()[0];\n          return null;\n        })\n        .when(invocation)\n        .setEndpoint(Mockito.any());\n\n    Map<String, Object> argsMap = of(\"endpoint\", endpoint);\n    operation.getArgumentsMapper().invocationArgumentToSwaggerArguments(invocation, argsMap);\n\n    assertThat(holder.value).isSameAs(endpoint);\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/invocation/endpoint/EndpointUtilsTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.invocation.endpoint;\n\nimport static org.apache.servicecomb.core.invocation.endpoint.EndpointUtils.formatFromUri;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport org.junit.jupiter.api.Nested;\nimport org.junit.jupiter.api.Test;\n\nclass EndpointUtilsTest {\n  @Nested\n  class Http {\n    @Test\n    void should_convert_without_port() {\n      assertThat(formatFromUri(\"http://host\")).isEqualTo(\"rest://host:80\");\n    }\n\n    @Test\n    void should_convert_with_port() {\n      assertThat(formatFromUri(\"http://host:8080\")).isEqualTo(\"rest://host:8080\");\n    }\n\n    @Test\n    void should_not_lost_query_parameters() {\n      assertThat(formatFromUri(\"http://host?q1=v1&q2=v2\")).isEqualTo(\"rest://host:80?q1=v1&q2=v2\");\n    }\n  }\n\n  @Nested\n  class Https {\n    @Test\n    void should_convert_without_port() {\n      assertThat(formatFromUri(\"https://host\")).isEqualTo(\"rest://host:443?sslEnabled=true\");\n    }\n\n    @Test\n    void should_convert_with_port() {\n      assertThat(formatFromUri(\"https://host:8443\")).isEqualTo(\"rest://host:8443?sslEnabled=true\");\n    }\n\n    @Test\n    void should_not_lost_query_parameters() {\n      assertThat(formatFromUri(\"https://host?q1=v1&q2=v2\")).isEqualTo(\"rest://host:443?q1=v1&q2=v2&sslEnabled=true\");\n    }\n  }\n\n  @Nested\n  class H2C {\n    @Test\n    void should_convert_without_port() {\n      assertThat(formatFromUri(\"h2c://host\")).isEqualTo(\"rest://host:80?protocol=http2\");\n    }\n\n    @Test\n    void should_convert_with_port() {\n      assertThat(formatFromUri(\"h2c://host:8080\")).isEqualTo(\"rest://host:8080?protocol=http2\");\n    }\n\n    @Test\n    void should_not_lost_query_parameters() {\n      assertThat(formatFromUri(\"h2c://host?q1=v1&q2=v2\")).isEqualTo(\"rest://host:80?q1=v1&q2=v2&protocol=http2\");\n    }\n  }\n\n  @Nested\n  class H2 {\n    @Test\n    void should_convert_without_port() {\n      assertThat(formatFromUri(\"h2://host\")).isEqualTo(\"rest://host:443?sslEnabled=true&protocol=http2\");\n    }\n\n    @Test\n    void should_convert_with_port() {\n      assertThat(formatFromUri(\"h2://host:8443\")).isEqualTo(\"rest://host:8443?sslEnabled=true&protocol=http2\");\n    }\n\n    @Test\n    void should_not_lost_query_parameters() {\n      assertThat(formatFromUri(\"h2://host?q1=v1&q2=v2\"))\n          .isEqualTo(\"rest://host:443?q1=v1&q2=v2&sslEnabled=true&protocol=http2\");\n    }\n  }\n\n  @Nested\n  class NotProvideScheme {\n    @Test\n    void should_set_scheme_to_h2c() {\n      assertThat(formatFromUri(\"host\")).isEqualTo(\"rest://host:80?protocol=http2\");\n    }\n\n    @Test\n    void should_not_lost_query_parameters() {\n      assertThat(formatFromUri(\"host?q1=v1&q2=v2\")).isEqualTo(\"rest://host:80?q1=v1&q2=v2&protocol=http2\");\n    }\n  }\n\n  @Nested\n  class UnknownScheme {\n    @Test\n    void should_not_change() {\n      assertThat(formatFromUri(\"abc://host:123?q1=v1\")).isEqualTo(\"abc://host:123?q1=v1\");\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/invocation/timeout/PassingTimeStrategyTest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.invocation.timeout;\r\n\r\nimport static org.apache.servicecomb.core.invocation.timeout.PassingTimeStrategy.CHAIN_START_TIME;\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\nimport static org.assertj.core.api.Assertions.catchThrowable;\r\n\r\nimport java.util.concurrent.TimeUnit;\r\n\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.foundation.test.scaffolding.time.MockClock;\r\nimport org.junit.jupiter.api.Test;\r\n\r\nimport com.google.common.collect.ImmutableMap;\r\n\r\nclass PassingTimeStrategyTest {\r\n  PassingTimeStrategy strategy = new PassingTimeStrategy();\r\n\r\n  @Test\r\n  void should_init_when_start_as_first_node_of_a_process_but_not_first_of_a_chain() {\r\n    Invocation invocation = new Invocation();\r\n    invocation.setContext(ImmutableMap.of(CHAIN_START_TIME, \"10\"));\r\n\r\n    strategy.start(invocation);\r\n\r\n    assertThat(invocation.getContext(CHAIN_START_TIME)).isEqualTo(\"10\");\r\n    assertThat(invocation.<Long>getLocalContext(CHAIN_START_TIME)).isEqualTo(10L);\r\n  }\r\n\r\n  @Test\r\n  void should_do_nothing_when_start_not_as_first_node_of_a_process() {\r\n    Invocation invocation = new Invocation();\r\n    invocation.setContext(ImmutableMap.of());\r\n    invocation.setLocalContext(ImmutableMap.of(CHAIN_START_TIME, 10L));\r\n\r\n    Throwable throwable = catchThrowable(() -> strategy.start(invocation));\r\n\r\n    assertThat(throwable).isNull();\r\n  }\r\n\r\n  @Test\r\n  void should_calc_elapsed_time_as_passing_time() {\r\n    Invocation invocation = new Invocation();\r\n    invocation.addLocalContext(CHAIN_START_TIME, 10L);\r\n    strategy.setClock(new MockClock(100L));\r\n\r\n    long elapsedNanoTime = strategy.calculateElapsedNanoTime(invocation);\r\n\r\n    assertThat(elapsedNanoTime).isEqualTo(TimeUnit.MILLISECONDS.toNanos(90));\r\n  }\r\n}\r\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/invocation/timeout/ProcessingTimeStrategyTest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.core.invocation.timeout;\r\n\r\nimport static org.apache.servicecomb.core.invocation.timeout.ProcessingTimeStrategy.CHAIN_PROCESSING;\r\nimport static org.apache.servicecomb.core.invocation.timeout.ProcessingTimeStrategy.CHAIN_START_TIME;\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\nimport static org.assertj.core.api.Assertions.catchThrowable;\r\n\r\nimport org.apache.servicecomb.core.Invocation;\r\nimport org.apache.servicecomb.foundation.test.scaffolding.time.MockTicker;\r\nimport org.junit.jupiter.api.Test;\r\n\r\nimport com.google.common.collect.ImmutableMap;\r\n\r\nclass ProcessingTimeStrategyTest {\r\n  ProcessingTimeStrategy strategy = new ProcessingTimeStrategy();\r\n\r\n  @Test\r\n  void should_do_nothing_when_not_first_node_of_a_process() {\r\n    Invocation invocation = new Invocation();\r\n    invocation.setLocalContext(ImmutableMap.of(\r\n        CHAIN_START_TIME, 10L,\r\n        CHAIN_PROCESSING, 0L\r\n    ));\r\n\r\n    Throwable throwable = catchThrowable(() -> strategy.start(invocation));\r\n\r\n    assertThat(throwable).isNull();\r\n  }\r\n\r\n  @Test\r\n  void should_calc_elapsed_time_as_processing_time() {\r\n    strategy.setTicker(new MockTicker(50L));\r\n\r\n    Invocation invocation = new Invocation();\r\n    invocation.addLocalContext(CHAIN_START_TIME, 10L);\r\n    invocation.addLocalContext(CHAIN_PROCESSING, 20L);\r\n\r\n    long elapsedNanoTime = strategy.calculateElapsedNanoTime(invocation);\r\n\r\n    assertThat(elapsedNanoTime).isEqualTo(60L);\r\n  }\r\n\r\n  @Test\r\n  void should_update_processing_time_before_send() {\r\n    strategy = new ProcessingTimeStrategy() {\r\n      @Override\r\n      public void checkTimeout(Invocation invocation) {\r\n\r\n      }\r\n    };\r\n    strategy.setTicker(new MockTicker(50L));\r\n\r\n    Invocation invocation = new Invocation();\r\n    invocation.addLocalContext(CHAIN_START_TIME, 10L);\r\n    invocation.addLocalContext(CHAIN_PROCESSING, 20L);\r\n\r\n    strategy.beforeSendRequest(invocation);\r\n\r\n    assertThat(invocation.getContext(CHAIN_PROCESSING)).isEqualTo(\"60\");\r\n  }\r\n}\r\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/provider/Person.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider;\n\npublic class Person {\n  private String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/provider/consumer/TestInvokerUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.consumer;\n\nimport org.junit.jupiter.api.Test;\n\npublic class TestInvokerUtils {\n  @Test\n  public void testRetryInvocation503() {\n\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/provider/producer/TestProducerBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.producer;\n\nimport java.util.Arrays;\nimport java.util.concurrent.Executor;\n\nimport org.apache.servicecomb.core.BootListener.BootEvent;\nimport org.apache.servicecomb.core.BootListener.EventType;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestProducerBootListener {\n  ProducerBootListener producerBootListener = new ProducerBootListener();\n\n  @Test\n  public void onBootEvent_notClose() {\n    BootEvent event = new BootEvent();\n    event.setEventType(EventType.BEFORE_CLOSE);\n\n    // should not throw exception\n    producerBootListener.onBootEvent(event);\n  }\n\n  @Test\n  public void onBootEvent_close_unknown() {\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    OperationMeta op = Mockito.mock(OperationMeta.class);\n\n    Executor executor = new UnCloseableExecutor();\n    Mockito.when(scbEngine.getProducerMicroserviceMeta()).thenReturn(microserviceMeta);\n    Mockito.when(microserviceMeta.getOperations()).thenReturn(Arrays.asList(op));\n    Mockito.when(op.getExecutor()).thenReturn(executor);\n\n    try (LogCollector logCollector = new LogCollector()) {\n      BootEvent event = new BootEvent();\n      event.setScbEngine(scbEngine);\n      event.setEventType(EventType.AFTER_CLOSE);\n\n      producerBootListener.onBootEvent(event);\n\n      Assertions.assertEquals(\n          \"Executor org.apache.servicecomb.core.provider.producer.TestProducerBootListener$UnCloseableExecutor \"\n              + \"do not support close or shutdown, it may block service shutdown.\",\n          logCollector.getLastEvents().getMessage().getFormattedMessage());\n    }\n  }\n\n  public static class UnCloseableExecutor implements Executor {\n    @Override\n    public void execute(Runnable command) {\n      command.run();\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/provider/producer/TestProducerMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core.provider.producer;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestProducerMeta {\n  @Test\n  public void test1() {\n    Object instance = new Object();\n    ProducerMeta meta = new ProducerMeta(\"id\", instance);\n    Assertions.assertEquals(\"id\", meta.getSchemaId());\n    Assertions.assertEquals(instance, meta.getInstance());\n  }\n\n  @Test\n  public void test2() {\n    ProducerMeta meta = new ProducerMeta();\n    meta.setSchemaId(\"id1\");\n    Assertions.assertEquals(\"id1\", meta.getSchemaId());\n\n    meta.setInstance(1);\n    Assertions.assertEquals(1, meta.getInstance());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/provider/producer/TestProducerProviderManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.provider.producer;\n\nimport org.junit.jupiter.api.Test;\n\npublic class TestProducerProviderManager {\n  @Test\n  public void allowedNoProvider() {\n    // must not throw exception\n    new ProducerProviderManager(null).init();\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/registry/discovery/TestEndpointDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.registry.discovery;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestEndpointDiscoveryFilter {\n  EndpointDiscoveryFilter filter = new EndpointDiscoveryFilter();\n\n  DiscoveryContext context = new DiscoveryContext();\n\n  Invocation invocation;\n\n  @BeforeEach\n  public void setup() {\n\n  }\n\n  @AfterEach\n  public void teardown() {\n  }\n\n  @Test\n  public void getOrder() {\n    Assertions.assertEquals(Short.MAX_VALUE, filter.getOrder());\n  }\n\n  @Test\n  public void getTransportName() {\n    invocation = Mockito.mock(Invocation.class);\n    Mockito.when(invocation.getConfigTransportName()).thenReturn(CoreConst.RESTFUL);\n    context.setInputParameters(invocation);\n    Assertions.assertEquals(CoreConst.RESTFUL, filter.findTransportName(context, null));\n  }\n\n  @Test\n  public void createEndpointNullTransport() {\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    Mockito.when(transportManager.findTransport(CoreConst.RESTFUL)).thenReturn(null);\n    filter.setScbEngine(scbEngine);\n    Assertions.assertNull(filter.createEndpoint(null, CoreConst.RESTFUL, \"\", null));\n  }\n\n  @Test\n  public void createEndpointNormal() {\n    Transport transport = Mockito.mock(Transport.class);\n    StatefulDiscoveryInstance instance = Mockito.mock(StatefulDiscoveryInstance.class);\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n\n    String endpoint = \"rest://ip:port\";\n    Object address = new Object();\n\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    Mockito.when(transportManager.findTransport(CoreConst.RESTFUL)).thenReturn(transport);\n    Mockito.when(transport.parseAddress(endpoint)).thenReturn(address);\n    filter.setScbEngine(scbEngine);\n\n    Endpoint ep = (Endpoint) filter.createEndpoint(null, CoreConst.RESTFUL, endpoint, instance);\n    Assertions.assertSame(transport, ep.getTransport());\n    Assertions.assertSame(address, ep.getAddress());\n    Assertions.assertSame(instance, ep.getMicroserviceInstance());\n    Assertions.assertEquals(endpoint, ep.getEndpoint());\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.tracing;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class BraveTraceIdGeneratorTest {\n\n  @Test\n  public void generateStringId() {\n    TraceIdGenerator traceIdGenerator = new BraveTraceIdGenerator();\n    Assertions.assertNotEquals(traceIdGenerator.generate(), traceIdGenerator.generate());\n\n    String traceId = traceIdGenerator.generate();\n    try {\n      Long.parseLong(traceId, 16);\n    } catch (NumberFormatException e) {\n      Assertions.fail(\"wrong traceId format: \" + traceId);\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.transport;\n\nimport static org.apache.servicecomb.core.transport.AbstractTransport.PUBLISH_ADDRESS;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.net.IpPort;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.impl.SysProps;\n\npublic class TestAbstractTransport {\n  Environment environment = Mockito.mock(Environment.class);\n\n  static class MyAbstractTransport extends AbstractTransport {\n\n    @Override\n    public String getName() {\n      return \"my\";\n    }\n\n    @Override\n    public boolean init() {\n      return true;\n    }\n  }\n\n  @BeforeEach\n  public void setUp() {\n    Mockito.when(environment.getProperty(PUBLISH_ADDRESS, \"\")).thenReturn(\"\");\n    Mockito.when(environment.getProperty(\"servicecomb.my.publishPort\", int.class, 0)).thenReturn(0);\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testSetListenAddressWithoutSchemaChineseSpaceNewSC() throws UnsupportedEncodingException {\n    MyAbstractTransport transport = new MyAbstractTransport();\n    transport.setEnvironment(environment);\n    transport.setListenAddressWithoutSchema(\"127.0.0.1:9090\", Collections.singletonMap(\"country\", \"中 国\"));\n    Assertions.assertEquals(\"my://127.0.0.1:9090?country=\" + URLEncoder.encode(\"中 国\", StandardCharsets.UTF_8.name()),\n        transport.getEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testSetListenAddressWithoutSchemaNormalNotEncode() {\n    MyAbstractTransport transport = new MyAbstractTransport();\n    transport.setEnvironment(environment);\n    transport.setListenAddressWithoutSchema(\"127.0.0.1:9090\", Collections.singletonMap(\"country\", \"chinese\"));\n    Assertions.assertEquals(\"my://127.0.0.1:9090?country=chinese\", transport.getEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testSetListenAddressWithoutSchemaAlreadyHaveQuery() {\n    MyAbstractTransport transport = new MyAbstractTransport();\n    transport.setEnvironment(environment);\n    transport.setListenAddressWithoutSchema(\"127.0.0.1:9090?a=aValue\",\n        Collections.singletonMap(\"country\", \"chinese\"));\n    Assertions.assertEquals(\"my://127.0.0.1:9090?a=aValue&country=chinese\", transport.getEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testMyAbstractTransport() {\n    MyAbstractTransport transport = new MyAbstractTransport();\n    transport.setEnvironment(environment);\n    transport.setListenAddressWithoutSchema(\"127.0.0.1:9090\");\n    Assertions.assertEquals(\"my\", transport.getName());\n    Assertions.assertEquals(\"my://127.0.0.1:9090\", transport.getEndpoint().getEndpoint());\n    Assertions.assertEquals(\"127.0.0.1\", ((IpPort) transport.parseAddress(\"my://127.0.0.1:9090\")).getHostOrIp());\n    transport.setListenAddressWithoutSchema(\"0.0.0.0:9090\");\n    Assertions.assertNotEquals(\"my://127.0.0.1:9090\", transport.getEndpoint().getEndpoint());\n    transport.setListenAddressWithoutSchema(null);\n    Assertions.assertNull(transport.getEndpoint().getEndpoint());\n    Assertions.assertNull(transport.parseAddress(null));\n  }\n\n  @Test\n  public void testMyAbstractTransportException() {\n    MyAbstractTransport transport = new MyAbstractTransport();\n    transport.setEnvironment(environment);\n    Assertions.assertThrows(IllegalArgumentException.class, () ->\n        transport.setListenAddressWithoutSchema(\":127.0.0.1:9090\"));\n  }\n}\n"
  },
  {
    "path": "core/src/test/java/org/apache/servicecomb/core/transport/TestTransportManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.core.transport;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestTransportManager {\n  @Test\n  public void testTransportManagerInitFail()\n      throws Exception {\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Transport transport = Mockito.mock(Transport.class);\n    Mockito.when(transport.getName()).thenReturn(\"test\");\n    Mockito.when(transport.init()).thenReturn(false);\n    Mockito.when(transport.canInit()).thenReturn(true);\n    List<Transport> transports = Arrays.asList(transport);\n    TransportManager manager = new TransportManager();\n    manager.addTransportsBeforeInit(transports);\n\n    manager.init(scbEngine);\n    Assertions.assertEquals(manager.findTransport(\"test\"), transport);\n  }\n\n  @Test\n  public void testTransportManagerInitSuccess() throws Exception {\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Transport transport = Mockito.mock(Transport.class);\n    Endpoint endpoint = Mockito.mock(Endpoint.class);\n    Mockito.when(transport.getName()).thenReturn(\"test\");\n    Mockito.when(transport.init()).thenReturn(true);\n    Mockito.when(transport.canInit()).thenReturn(true);\n    Mockito.when(transport.getPublishEndpoint()).thenReturn(endpoint);\n    List<Transport> transports = Arrays.asList(transport);\n\n    TransportManager manager = new TransportManager();\n    manager.addTransportsBeforeInit(transports);\n\n    manager.init(scbEngine);\n    Assertions.assertEquals(manager.findTransport(\"test\"), transport);\n  }\n\n  @Test\n  public void testGroupByName() {\n    Transport t1 = Mockito.mock(Transport.class);\n    Mockito.when(t1.getName()).thenReturn(\"t1\");\n    Transport t21 = Mockito.mock(Transport.class);\n    Mockito.when(t21.getName()).thenReturn(\"t2\");\n    Transport t22 = Mockito.mock(Transport.class);\n    Mockito.when(t22.getName()).thenReturn(\"t2\");\n    TransportManager manager = new TransportManager();\n    manager.addTransportsBeforeInit(Arrays.asList(t1, t21, t22));\n\n    Map<String, List<Transport>> groups = manager.groupByName();\n    Assertions.assertEquals(2, groups.size());\n    Assertions.assertEquals(1, groups.get(\"t1\").size());\n    Assertions.assertEquals(t1, groups.get(\"t1\").get(0));\n    Assertions.assertEquals(2, groups.get(\"t2\").size());\n    Assertions.assertEquals(t21, groups.get(\"t2\").get(0));\n    Assertions.assertEquals(t22, groups.get(\"t2\").get(1));\n  }\n\n  @Test\n  public void testCheckTransportGroupInvalid() {\n    Transport t1 = Mockito.mock(Transport.class);\n    Mockito.when(t1.getOrder()).thenReturn(1);\n    Transport t2 = Mockito.mock(Transport.class);\n    Mockito.when(t2.getOrder()).thenReturn(1);\n\n    TransportManager manager = new TransportManager();\n    List<Transport> group = Arrays.asList(t1, t2);\n\n    try {\n      manager.checkTransportGroup(group);\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertTrue(e.getMessage().contains(\"have the same order\"));\n    }\n  }\n\n  @Test\n  public void testCheckTransportGroupValid() {\n    Transport t1 = Mockito.mock(Transport.class);\n    Mockito.when(t1.getOrder()).thenReturn(1);\n    Transport t2 = Mockito.mock(Transport.class);\n    Mockito.when(t2.getOrder()).thenReturn(2);\n\n    TransportManager manager = new TransportManager();\n    List<Transport> group = Arrays.asList(t1, t2);\n\n    try {\n      manager.checkTransportGroup(group);\n    } catch (ServiceCombException e) {\n      Assertions.fail(\"must not throw exception: \" + e.getMessage());\n    }\n  }\n\n  @Test\n  public void testChooseOneTransportFirst() {\n    Transport t1 = Mockito.mock(Transport.class);\n    Mockito.when(t1.getOrder()).thenReturn(1);\n    Mockito.when(t1.canInit()).thenReturn(true);\n    Transport t2 = Mockito.mock(Transport.class);\n    Mockito.when(t2.getOrder()).thenReturn(2);\n\n    TransportManager manager = new TransportManager();\n    List<Transport> group = Arrays.asList(t1, t2);\n\n    Assertions.assertEquals(t1, manager.chooseOneTransport(group));\n  }\n\n  @Test\n  public void testChooseOneTransportSecond() {\n    Transport t1 = Mockito.mock(Transport.class);\n    Mockito.when(t1.getOrder()).thenReturn(Integer.MAX_VALUE);\n    Mockito.when(t1.canInit()).thenReturn(true);\n    Transport t2 = Mockito.mock(Transport.class);\n    Mockito.when(t2.getOrder()).thenReturn(-1000);\n    Mockito.when(t2.canInit()).thenReturn(false);\n    TransportManager manager = new TransportManager();\n    List<Transport> group = Arrays.asList(t1, t2);\n\n    Assertions.assertEquals(t1, manager.chooseOneTransport(group));\n  }\n\n  @Test\n  public void testChooseOneTransportNone() {\n    Transport t1 = Mockito.mock(Transport.class);\n    Mockito.when(t1.getName()).thenReturn(\"t\");\n    Mockito.when(t1.getOrder()).thenReturn(1);\n    Mockito.when(t1.canInit()).thenReturn(false);\n    Transport t2 = Mockito.mock(Transport.class);\n    Mockito.when(t2.getOrder()).thenReturn(2);\n    Mockito.when(t2.canInit()).thenReturn(false);\n\n    TransportManager manager = new TransportManager();\n    List<Transport> group = Arrays.asList(t1, t2);\n\n    try {\n      manager.chooseOneTransport(group);\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\"all transport named t refused to init.\", e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "core/src/test/resources/META-INF/spring/cse.bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n  <bean id=\"servicecomb.executor.default\" class=\"org.apache.servicecomb.core.executor.GroupExecutor\"></bean>\n  <bean id=\"servicecomb.executor.reactive\" class=\"org.apache.servicecomb.core.executor.ReactiveExecutor\"></bean>\n</beans>\n"
  },
  {
    "path": "core/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "core/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nAPPLICATION_ID: app\nservice_description:\n  name: perfClient\n  version: 0.0.1\nservicecomb:\n  service:\n    registry:\n      address: http://127.0.0.1:30100\n  handler:\n    chain:\n      Consumer:\n        default: simpleLB\nzq:\n  - tlist: a\n  - tlist: b\n  - tlist: 1\n"
  },
  {
    "path": "core/src/test/resources/test/test/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservice_description:\n  name: default\n  version: 0.0.1\n  propertyExtendedClass: org.apache.servicecomb.serviceregistry.MicroServicePropertyExtendedStub\nservicecomb:\n  service:\n    registry:\n      address: http://127.0.0.1:30100\n      client:\n        httpVersion: HTTP_1_1\n        workerPoolSize: 1\n        timeout:\n          connection: 30000\n          idle: 30000\n      instance:\n        watch: true\n        preferIpAddress: false\n        healthCheck:\n          interval: 1\n          times: 5\n#ssl.keystore.path=\n#ssl.keystore.pass=\n#ssl.truststore.path=\n#ssl.truststore.pass=\n"
  },
  {
    "path": "core/src/test/resources/test/test/schema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\"\n  x-java-interface: \"gen.cse.ms.ut.SchemaIntf\"\nbasePath: \"/Schema\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /testint:\n    post:\n      operationId: \"testint\"\n      parameters:\n      - in: \"body\"\n        name: \"value\"\n        required: false\n        schema:\n          $ref: \"#/definitions/testintBody\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\ndefinitions:\n  testintBody:\n    type: \"object\"\n    properties:\n      value:\n        type: \"integer\"\n        format: \"int32\"\n"
  },
  {
    "path": "coverage-reports/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>coverage-reports</artifactId>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <!-- sort by project directory name, easy to check if the module is missed -->\n    <!-- clients -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-center-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-clients-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-kie-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>dashboard-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>http-client-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>service-center-client</artifactId>\n    </dependency>\n\n    <!-- common -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-access-log</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-protobuf</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n\n    <!-- core -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n\n    <!-- dynamic-config -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-apollo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-cc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-kie</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-nacos</artifactId>\n    </dependency>\n\n    <!-- edge -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n\n    <!-- foundations -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-metrics</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-protobuf</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-spi</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-ssl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n\n    <!-- governance -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicecomb-governance</artifactId>\n    </dependency>\n\n    <!-- handlers -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-fault-injection</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-flowcontrol-qps</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-publickey-auth</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-router</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-tracing-zipkin</artifactId>\n    </dependency>\n\n    <!-- metrics -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-prometheus</artifactId>\n    </dependency>\n\n    <!-- providers -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-pojo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-rest-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-springmvc</artifactId>\n    </dependency>\n\n    <!-- service registry -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-lightweight</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zero-config</artifactId>\n    </dependency>\n\n    <!-- solutions -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n\n    <!-- spring boot -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n\n    <!-- ServiceComb ServiceStage extension -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicestage</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>dashboard</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>darklaunch</artifactId>\n    </dependency>\n\n    <!-- swagger -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-spring-data</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-springmvc</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-springmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-validator</artifactId>\n    </dependency>\n\n    <!-- tracing -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>tracing-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>tracing-zipkin</artifactId>\n    </dependency>\n\n    <!-- transports -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-highway</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-vertx</artifactId>\n    </dependency>\n\n    <!-- test cases in demo folder, sort by folder name -->\n    <!-- demo-crossapp -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>crossapp-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>crossapp-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo-edge -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>authentication</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>business-1-0-0</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>business-1-1-0</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>business-2-0-0</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>consumer</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>edge-service</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>model</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo-jaxrs -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>jaxrs-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>jaxrs-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo-local-registry -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-local-registry-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-local-registry-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo-multi-registries -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-multi-registries-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-multi-registries-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo-pojo -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>pojo-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>pojo-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo-register-url-prefix -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-register-url-prefix-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-register-url-prefix-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo schema -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n\n    <!-- demo spring boot transport-->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-spring-boot-pojo-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-spring-boot-pojo-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-spring-boot-springmvc-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-spring-boot-springmvc-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo springmvc -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>springmvc-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>springmvc-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <!-- demo zeroconfig shcema discovery -->\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-zeroconfig-registry-client</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-zeroconfig-registry-server</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-zeroconfig-registry-tests</artifactId>\n      <version>${project.version}</version>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>jacoco</id>\n      <activation>\n        <activeByDefault>false</activeByDefault>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.jacoco</groupId>\n            <artifactId>jacoco-maven-plugin</artifactId>\n            <executions>\n              <execution>\n                <phase>verify</phase>\n                <goals>\n                  <goal>report-aggregate</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/README.md",
    "content": "This module contains integrated test cases. Running these test cases, should include profile\n\n```shell script\n-Pdocker\n```\n\n[java-chassis-samples][java-chassis-samples] project provides a lot of samples.\n\n[java-chassis-samples]: https://github.com/apache/servicecomb-samples/tree/master/java-chassis-samples\n"
  },
  {
    "path": "demo/assembly/assembly.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<assembly\n  xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd\">\n  <id>bin</id>\n  <formats>\n    <format>dir</format>\n  </formats>\n  <includeBaseDirectory>false</includeBaseDirectory>\n\n  <fileSets>\n    <fileSet>\n      <outputDirectory>/maven</outputDirectory>\n      <directory>${project.build.directory}</directory>\n      <includes>\n        <include>**/*.jar</include>\n      </includes>\n    </fileSet>\n    <fileSet>\n      <outputDirectory>/maven</outputDirectory>\n      <directory>${project.build.directory}/classes</directory>\n      <includes>\n        <include>certificates/*</include>\n      </includes>\n    </fileSet>\n  </fileSets>\n\n</assembly>\n"
  },
  {
    "path": "demo/demo-consul/README.md",
    "content": "# Notice\n\nThis integration tests is designed for Consul registry and configuration. And extra test cases include:\n\n* Test cases related to SpringMVC annotations that demo-springmvc can not cover.\n"
  },
  {
    "path": "demo/demo-consul/consumer/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-consul</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>consul-consumer</artifactId>\n  <name>Java Chassis::Demo::Consul::CONSUMER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-consul</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.ServerWebSocket;\nimport io.vertx.core.http.WebSocket;\n\n@RestSchema(schemaId = \"ClientWebsocketController\")\n@RequestMapping(path = \"/ws\")\npublic class ClientWebsocketController {\n  interface ProviderService {\n    WebSocket websocket();\n  }\n\n  @RpcReference(schemaId = \"WebsocketController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  @PostMapping(\"/websocket\")\n  @Transport(name = CoreConst.WEBSOCKET)\n  public void websocket(ServerWebSocket serverWebsocket) {\n    WebSocket providerWebSocket = providerService.websocket();\n    providerWebSocket.closeHandler(v -> serverWebsocket.close());\n    providerWebSocket.textMessageHandler(m -> {\n      serverWebsocket.writeTextMessage(m);\n    });\n    serverWebsocket.textMessageHandler(m -> {\n      providerWebSocket.writeTextMessage(m);\n    });\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsulConsumerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsulConsumerApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsulConsumerApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\n@RestSchema(schemaId = \"ConsumerController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerController {\n  @RpcReference(schemaId = \"ProviderController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  // consumer service which delegate the implementation to provider service.\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return providerService.sayHello(name);\n  }\n\n  @GetMapping(\"/getConfig\")\n  public String getConfig(@RequestParam(\"key\") String key) {\n    return providerService.getConfig(key);\n  }\n\n  @PostMapping(path = \"/testContentType\", consumes = MediaType.APPLICATION_JSON_VALUE)\n  @ResponseBody\n  public User testContentType(@RequestBody User user) {\n    return providerService.testContentType(user);\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"ConsumerHeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)\npublic class ConsumerHeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {\n  @RpcReference(microserviceName = \"provider\", schemaId = \"HeaderParamWithListSchema\")\n  private IHeaderParamWithListSchemaSpringMvc provider;\n\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return provider.headerListDefault(headerList);\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return provider.headerListCSV(headerList);\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return provider.headerListMULTI(headerList);\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return provider.headerListSSV(headerList);\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return provider.headerListPIPES(headerList);\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerReactiveStreamController {\n  interface ProviderReactiveStreamController {\n    Publisher<String> sseString();\n\n    Publisher<Model> sseModel();\n  }\n\n  @RpcReference(microserviceName = \"provider\", schemaId = \"ReactiveStreamController\")\n  ProviderReactiveStreamController controller;\n\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  @Transport(name = CoreConst.RESTFUL)\n  public Publisher<String> sseString() {\n    return controller.sseString();\n  }\n\n  @GetMapping(\"/sseModel\")\n  @Transport(name = CoreConst.RESTFUL)\n  public Publisher<Model> sseModel() {\n    return controller.sseModel();\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface ProviderService {\n  String sayHello(String name);\n\n  String getConfig(String key);\n\n  User testContentType(User user);\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\npublic class User {\n\n  private Long id;\n\n  private String name;\n\n  public Long getId() {\n    return id;\n  }\n\n  public void setId(Long id) {\n    this.id = id;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: demo-consul\n    version: 0.0.1\n    name: consumer\n    properties:\n      group: green\n\n  registry:\n    consul:\n      enabled: true\n      host: 127.0.0.1\n      scheme: http\n      discovery:\n        enabled: true\n        acl-token: ''\n        watch-seconds: 8\n\n  rest:\n    address: 0.0.0.0:9092?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n"
  },
  {
    "path": "demo/demo-consul/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-consul/gateway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-consul</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>consul-gateway</artifactId>\n  <name>Java Chassis::Demo::Consul::GATEWAY</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-consul</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-consul/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class GatewayApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/gateway/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: demo-consul\n    version: 0.0.1\n    name: gateway\n\n  registry:\n    consul:\n      enabled: true\n      host: 127.0.0.1\n      scheme: http\n      discovery:\n        enabled: true\n        acl-token: ''\n        watch-seconds: 8\n\n  rest:\n    address: 0.0.0.0:9090?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n        websocket:\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/ws/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n"
  },
  {
    "path": "demo/demo-consul/gateway/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-consul/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>demo-consul</artifactId>\n  <name>Java Chassis::Demo::Consul</name>\n  <packaging>pom</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>provider</module>\n    <module>consumer</module>\n    <module>gateway</module>\n    <module>test-client</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "demo/demo-consul/provider/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-consul</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>consul-provider</artifactId>\n  <name>Java Chassis::Demo::Consul::PROVIDER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-consul</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-consul</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.reactivex.rxjava3</groupId>\n      <artifactId>rxjava</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ConsulProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsulProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsulProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"HeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)\npublic class HeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController implements InitializingBean {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n//    return \"Hello \" + environment.getProperty(\"servicecomb.rest.address\");\n    return \"Hello \" + name;\n  }\n\n  @GetMapping(\"/getConfig\")\n  public String getConfig(@RequestParam(\"key\") String key) {\n    return environment.getProperty(key);\n  }\n\n  @PostMapping(path = \"/testContentType\", consumes = MediaType.APPLICATION_JSON_VALUE)\n  @ResponseBody\n  public User testContentType(@RequestBody User user) {\n    return user;\n  }\n\n  @Override\n  public void afterPropertiesSet() throws Exception {\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.reactivex.rxjava3.core.Flowable;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\n@Transport(name = CoreConst.RESTFUL)\npublic class ReactiveStreamController {\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  public Publisher<String> sseString() {\n    return Flowable.fromArray(\"a\", \"b\", \"c\");\n  }\n\n  @GetMapping(\"/sseModel\")\n  public Publisher<Model> sseModel() {\n    return Flowable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)\n        .map(item -> new Model(\"jack\", item.intValue()));\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\npublic class User {\n\n  private Long id;\n\n  private String name;\n\n  public Long getId() {\n    return id;\n  }\n\n  public void setId(Long id) {\n    this.id = id;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.ServerWebSocket;\n\n@RestSchema(schemaId = \"WebsocketController\")\n@RequestMapping(path = \"/ws\")\npublic class WebsocketController {\n  @PostMapping(\"/websocket\")\n  @Transport(name = CoreConst.WEBSOCKET)\n  public void websocket(ServerWebSocket serverWebsocket) {\n    AtomicInteger receiveCount = new AtomicInteger(0);\n    CountDownLatch startSend = new CountDownLatch(1);\n    serverWebsocket.textMessageHandler(s -> {\n      if (\"start\".equals(s)) {\n        startSend.countDown();\n        serverWebsocket.writeTextMessage(\"started\");\n        return;\n      }\n      receiveCount.getAndIncrement();\n    });\n    serverWebsocket.closeHandler((v) -> System.out.println(\"closed\"));\n\n    new Thread(() -> {\n      try {\n        startSend.await(30, TimeUnit.SECONDS);\n      } catch (InterruptedException e) {\n        e.printStackTrace();\n      }\n\n      serverWebsocket.writeTextMessage(\"hello\");\n\n      for (int i = 0; i < 5; i++) {\n        serverWebsocket.writeTextMessage(\"hello \" + i);\n        try {\n          Thread.sleep(500);\n        } catch (InterruptedException e) {\n          e.printStackTrace();\n        }\n      }\n      serverWebsocket.writeTextMessage(\"total \" + receiveCount.get());\n      serverWebsocket.close();\n    }).start();\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# spring boot configurations\nservicecomb:\n  service:\n    application: demo-consul\n    version: 0.0.1\n    name: provider\n    properties:\n      group: green\n\n  registry:\n    consul:\n      enabled: true\n      host: 127.0.0.1\n      scheme: http\n      discovery:\n        enabled: true\n        acl-token: ''\n        watch-seconds: 8\n\n  config:\n    consul:\n      enabled: true\n      host: 127.0.0.1\n      scheme: http\n      acl-token: ''\n      watch-seconds: 8\n\n  rest:\n    address: 0.0.0.0:9094?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  cors:\n    enabled: true\n    origin: \"*\"\n    allowCredentials: false\n    allowedMethod: \"*\"\n    maxAge: 3600\n\n\nkey1: 1\nkey2: 3\nkey3: 5\n\ntest1: env\ntest2: applition\ntest3: service\ntest4: version\ntest5: tag\n"
  },
  {
    "path": "demo/demo-consul/provider/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-consul/test-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-consul</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>consul-test-client</artifactId>\n  <name>Java Chassis::Demo::Consul::TEST-CLIENT</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.kiwiproject</groupId>\n      <artifactId>consul-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.gson</groupId>\n      <artifactId>gson</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>hashicorp/consul:1.21</name>\n                    <alias>consul</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <wait>\n                        <log>consulServer</log>\n                        <tcp>\n                          <ports>\n                            <port>8500</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>8500:8500</port>\n                      </ports>\n                      <env>\n                        <ALLOW_NONE_AUTHENTICATION>yes</ALLOW_NONE_AUTHENTICATION>\n                      </env>\n                    </run>\n                  </image>\n                  <image>\n                    <name>consul-provider:${project.version}</name>\n                    <alias>consul-provider</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.consul.enabled=true\n                          -Dservicecomb.registry.consul.scheme=http\n                          -Dservicecomb.registry.consul.host=consul\n                          -Dservicecomb.registry.consul.port=8500\n                          -Dservicecomb.config.consul.enabled=true\n                          -Dservicecomb.config.consul.scheme=http\n                          -Dservicecomb.config.consul.host=consul\n                          -Dservicecomb.config.consul.port=8500\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/consul-provider-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>consul:consul</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9094</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9094:9094</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>consul-consumer:${project.version}</name>\n                    <alias>consul-consumer</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.consul.enabled=true\n                          -Dservicecomb.registry.consul.scheme=http\n                          -Dservicecomb.registry.consul.host=consul\n                          -Dservicecomb.registry.consul.port=8500\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/consul-consumer-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>consul:consul</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9092</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9092:9092</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>consul-gateway:${project.version}</name>\n                    <alias>consul-gateway</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.consul.enabled=true\n                          -Dservicecomb.registry.consul.scheme=http\n                          -Dservicecomb.registry.consul.host=consul\n                          -Dservicecomb.registry.consul.port=8500\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/consul-gateway-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>consul:consul</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9090:9090</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface Config {\n  String GATEWAY_URL = \"http://localhost:9090\";\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ConsulConfigIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport com.google.common.net.HostAndPort;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.ConditionWaiter.SleepUtil;\nimport org.kiwiproject.consul.Consul;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\nimport java.util.concurrent.TimeUnit;\n\n@Component\npublic class ConsulConfigIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsulConfigIT.class);\n\n  @Override\n  public void testRestTransport() throws Exception {\n\n    testEnvironment();\n    testApplication();\n    testService();\n    testVersion();\n    testTag();\n    testOverride();\n  }\n\n  private void testOverride() {\n\n    putValue(\"/servicecomb/config/environment/production/application2.properties\",\n        \"testValue=t1\");\n    putValue(\"/servicecomb/config/application/production/demo-consul/application2.properties\",\n        \"testValue=t2\");\n    testGetConfig(\"testValue\", \"t2\");\n    putValue(\"/servicecomb/config/service/production/demo-consul/provider/application2.properties\",\n        \"testValue=t3\");\n    testGetConfig(\"testValue\", \"t3\");\n    putValue(\"/servicecomb/config/version/production/demo-consul/provider/0.0.1/application2.properties\",\n        \"testValue=t4\");\n    testGetConfig(\"testValue\", \"t4\");\n    putValue(\"/servicecomb/config/tag/production/demo-consul/provider/0.0.1/tag1/application2.properties\",\n        \"testValue=t5\");\n    testGetConfig(\"testValue\", \"t5\");\n  }\n\n  private void testEnvironment() {\n\n    putValue(\"/servicecomb/config/environment/production/application.properties\",\n        \"test1=env\");\n    putValue(\"/servicecomb/config/environment/production/application.properties\",\n        \"test1=env1\");\n\n    testGetConfig(\"test1\", \"env1\");\n  }\n\n\n  private void testApplication() {\n\n    putValue(\"/servicecomb/config/application/production/demo-consul/application.properties\",\n        \"test2=applition\");\n    putValue(\"/servicecomb/config/application/production/demo-consul/application.properties\",\n        \"test2=applition2\");\n    testGetConfig(\"test2\", \"applition2\");\n  }\n\n  private void testService() {\n\n    putValue(\"/servicecomb/config/service/production/demo-consul/provider/application.properties\",\n        \"test3=service\");\n    putValue(\"/servicecomb/config/service/production/demo-consul/provider/application.properties\",\n        \"test3=service3\");\n    testGetConfig(\"test3\", \"service3\");\n  }\n\n  private void testVersion() {\n\n    putValue(\"/servicecomb/config/version/production/demo-consul/provider/0.0.1/application.properties\",\n        \"test3=version\");\n    putValue(\"/servicecomb/config/version/production/demo-consul/provider/0.0.1/application.properties\",\n        \"test4=version4\");\n    testGetConfig(\"test4\", \"version4\");\n  }\n\n  private void testTag() {\n\n    putValue(\"/servicecomb/config/tag/production/demo-consul/provider/0.0.1/tag1/application.properties\",\n        \"test5=tag\");\n    putValue(\"/servicecomb/config/tag/production/demo-consul/provider/0.0.1/tag1/application.properties\",\n        \"test5=tag5\");\n    testGetConfig(\"test5\", \"tag5\");\n  }\n\n  public void putValue(String key, String value) {\n    try {\n      Consul.Builder builder = Consul.builder().withHostAndPort(HostAndPort.fromParts(\"127.0.0.1\", 8500));\n      Consul consulClient = builder.build();\n      consulClient.keyValueClient().putValue(key, value);\n      LOGGER.info(\"Value set successfully:{}\", value);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n\n  private void testGetConfig(String key, String expectValue) {\n\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=\" + key, String.class);\n\n    for (int i = 0; i < 4; i++) {\n      if (StringUtils.equals(expectValue, result)) {\n        TestMgr.check(expectValue, result);\n        break;\n      }\n      SleepUtil.sleep(500, TimeUnit.MILLISECONDS);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HeaderParamWithListSchemaIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHeaderListDefault();\n    testHeaderListMulti();\n    testHeaderListCSV();\n    testHeaderListSSV();\n    testHeaderListPipes();\n  }\n\n  // default to multi\n  private void testHeaderListDefault() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListDefault\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListPipes() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a|b|c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListPIPES\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListSSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a b c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListSSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListCSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a,b,c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n\n    headers.add(\"headerList\", \"a, b, c\");\n    entity = new HttpEntity<>(headers);\n    result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListMulti() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListMULTI\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HelloWorldIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHelloWorld();\n    testGetConfig();\n  }\n\n  private void testGetConfig() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key1\", String.class);\n    TestMgr.check(\"1\", result);\n    result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key2\", String.class);\n    TestMgr.check(\"3\", result);\n    result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key3\", String.class);\n    TestMgr.check(\"5\", result);\n  }\n\n  private void testHelloWorld() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/sayHello?name=World\", String.class);\n    TestMgr.check(\"Hello World\", result);\n\n    // test trace id added\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"X-B3-TraceId\", \"81de2eb7691c2bbb\");\n    HttpEntity<Object> entity = new HttpEntity(headers);\n    ResponseEntity<String> response =\n        template.exchange(Config.GATEWAY_URL + \"/sayHello?name=World\", HttpMethod.GET, entity, String.class);\n    TestMgr.check(1, response.getHeaders().get(\"X-B3-TraceId\").size());\n    TestMgr.check(\"81de2eb7691c2bbb\", response.getHeaders().getFirst(\"X-B3-TraceId\"));\n    TestMgr.check(\"Hello World\", response.getBody());\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ProviderIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class ProviderIT implements CategorizedTestCase {\n\n  RestOperations template = new RestTemplate();\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProviderIT.class);\n\n  @Override\n  public void testRestTransport() throws Exception {\n\n    User user = getUser(\"Application/json\");\n    TestMgr.check(1L, user.getId());\n    TestMgr.check(\"czd\", user.getName());\n\n    User user2 = getUser(\"application/json\");\n    TestMgr.check(1L, user2.getId());\n    TestMgr.check(\"czd\", user2.getName());\n\n    User user3 = getUser(\"APPLICATION/JSON\");\n    TestMgr.check(1L, user3.getId());\n    TestMgr.check(\"czd\", user3.getName());\n  }\n\n  private User getUser(String contentType) throws IOException {\n    HttpHeaders headers = new HttpHeaders();\n    headers.set(\"Content-Type\", contentType);\n\n    String requestBody = \"\"\"\n        {\n            \"id\": 1,\n            \"name\": \"czd\"\n        }\n        \"\"\";\n\n    HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);\n\n    String url = Config.GATEWAY_URL + \"/testContentType\";\n    ResponseEntity<String> response = template.exchange(\n        url, HttpMethod.POST, entity, String.class);\n\n    User user = JsonUtils.readValue(response.getBody().getBytes(StandardCharsets.UTF_8), User.class);\n    return user;\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ReactiveStreamIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient.Model;\nimport org.reactivestreams.Publisher;\nimport org.reactivestreams.Subscriber;\nimport org.reactivestreams.Subscription;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ReactiveStreamIT implements CategorizedTestCase {\n  @Autowired\n  @Qualifier(\"reactiveStreamProvider\")\n  ReactiveStreamClient reactiveStreamProvider;\n\n  @Autowired\n  @Qualifier(\"reactiveStreamGateway\")\n  ReactiveStreamClient reactiveStreamGateway;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testSseString(reactiveStreamProvider);\n    testSseModel(reactiveStreamProvider);\n    testSseString(reactiveStreamGateway);\n    testSseModel(reactiveStreamGateway);\n  }\n\n  private void testSseModel(ReactiveStreamClient client) throws Exception {\n    Publisher<Model> result = client.sseModel();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(Model s) {\n        buffer.append(s.getName()).append(s.getAge());\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"jack0jack1jack2jack3jack4\", buffer.toString());\n  }\n\n  private void testSseString(ReactiveStreamClient client) throws Exception {\n    Publisher<String> result = client.sseString();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(String s) {\n        buffer.append(s);\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"abc\", buffer.toString());\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class TestClientApplication {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args);\n\n      run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"consumer\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ThirdSvcConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.reactivestreams.Publisher;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.WebSocket;\n\n@Configuration\npublic class ThirdSvcConfiguration {\n  @RequestMapping(path = \"/ws\")\n  public interface WebsocketClient {\n    @PostMapping(\"/websocket\")\n    @Transport(name = CoreConst.WEBSOCKET)\n    WebSocket websocket();\n  }\n\n  @RequestMapping(path = \"/\")\n  public interface ReactiveStreamClient {\n    class Model {\n      private String name;\n\n      private int age;\n\n      public Model() {\n\n      }\n\n      public Model(String name, int age) {\n        this.name = name;\n        this.age = age;\n      }\n\n      public int getAge() {\n        return age;\n      }\n\n      public Model setAge(int age) {\n        this.age = age;\n        return this;\n      }\n\n      public String getName() {\n        return name;\n      }\n\n      public Model setName(String name) {\n        this.name = name;\n        return this;\n      }\n    }\n\n    @GetMapping(\"/sseString\")\n    Publisher<String> sseString();\n\n    @GetMapping(\"/sseModel\")\n    Publisher<Model> sseModel();\n  }\n\n  @Bean\n  public RegistryBean providerServiceBean() {\n    return new RegistryBean()\n        .addSchemaInterface(\"ReactiveStreamController\", ReactiveStreamClient.class)\n        .setAppId(\"demo-consul\")\n        .setServiceName(\"provider\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(\n            new Instance().setEndpoints(List.of(\"rest://localhost:9094\")))));\n  }\n\n  @Bean\n  public RegistryBean gatewayServiceBean() {\n    return new RegistryBean()\n        .addSchemaInterface(\"ReactiveStreamController\", ReactiveStreamClient.class)\n        .addSchemaInterface(\"WebsocketController\", WebsocketClient.class)\n        .setAppId(\"demo-consul\")\n        .setServiceName(\"gateway\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(\n            new Instance().setEndpoints(List.of(\"rest://localhost:9090?websocketEnabled=true\")))));\n  }\n\n  @Bean(\"reactiveStreamProvider\")\n  public ReactiveStreamClient reactiveStreamProvider() {\n    return Invoker.createProxy(\"provider\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n\n  @Bean(\"reactiveStreamGateway\")\n  public ReactiveStreamClient reactiveStreamGateway() {\n    return Invoker.createProxy(\"gateway\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n\n  @Bean\n  public WebsocketClient gatewayWebsocketClient() {\n    return Invoker.createProxy(\"gateway\", \"WebsocketController\", WebsocketClient.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\npublic class User {\n\n  private Long id;\n\n  private String name;\n\n  public Long getId() {\n    return id;\n  }\n\n  public void setId(Long id) {\n    this.id = id;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.WebsocketClient;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport io.vertx.core.http.WebSocket;\n\n@Component\npublic class WebsocketIT implements CategorizedTestCase {\n  @Autowired\n  private WebsocketClient websocketClient;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    StringBuffer sb = new StringBuffer();\n    AtomicBoolean closed = new AtomicBoolean(false);\n    CountDownLatch latchStarted = new CountDownLatch(1);\n    CountDownLatch latch = new CountDownLatch(1);\n\n    WebSocket webSocket = websocketClient.websocket();\n    webSocket.textMessageHandler(s -> {\n      if (\"started\".equals(s)) {\n        latchStarted.countDown();\n        return;\n      }\n      sb.append(s);\n      sb.append(\" \");\n      webSocket.writeTextMessage(s);\n    });\n    webSocket.closeHandler(v -> {\n      closed.set(true);\n      latch.countDown();\n    });\n\n    webSocket.writeTextMessage(\"start\");\n    int i = 0;\n    for (; i < 10; i++) {\n      if (!latchStarted.await(3, TimeUnit.SECONDS)) {\n        webSocket.writeTextMessage(\"start\");\n        continue;\n      }\n      break;\n    }\n    TestMgr.check(i < 10, true);\n    latch.await(30, TimeUnit.SECONDS);\n    TestMgr.check(sb.toString(), \"hello hello 0 hello 1 hello 2 hello 3 hello 4 total 6 \");\n    TestMgr.check(closed.get(), true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: demo-consul\n    name: test-client\n    version: 0.0.1\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n\n  config:\n    consul:\n      enabled: true\n      host: 127.0.0.1\n      scheme: http\n      acl-token: ''\n      instance-tag: tag1\n\ntest1: env\ntest2: applition\ntest3: service\ntest4: version\ntest5: tag\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-consul/test-client/src/test/java/org/apache/servicecomb/samples/ConsulIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = TestClientApplication.class)\npublic class ConsulIT {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsulIT.class);\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() {\n    try {\n      TestClientApplication.run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-crossapp</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>crossapp-client</artifactId>\n  <name>Java Chassis::Demo::CrossApp::Client</name>\n\n  <dependencies>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.crossapp.CrossappClient</demo.main>\n  </properties>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>crossapp-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-client/src/main/java/org/apache/servicecomb/demo/crossapp/CrossappClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.crossapp;\n\nimport java.util.Collections;\nimport java.util.TreeSet;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.HttpServerErrorException;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@SpringBootApplication\npublic class CrossappClient {\n  @RpcReference(microserviceName = \"appServer:appService\", schemaId = \"helloworld\")\n  private static HelloWorld helloWorld;\n\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(CrossappClient.class).web(WebApplicationType.NONE).run(args);\n\n    run();\n  }\n\n  public static void run() {\n    System.setProperty(\"sun.net.http.allowRestrictedHeaders\", \"true\");\n\n    String result = InvokerUtils.syncInvoke(\"appServer:appService\", \"helloworld\",\n        \"sayHello\", null, String.class);\n    TestMgr.check(\"hello world\", result);\n\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    result = restTemplate.getForObject(\"cse://appServer:appService/helloworld/hello\", String.class);\n    TestMgr.check(\"hello world\", result);\n    result = restTemplate.getForObject(\"servicecomb://appServer:appService/helloworld/hello\", String.class);\n    TestMgr.check(\"hello world\", result);\n\n    result = helloWorld.sayHello();\n    TestMgr.check(\"hello world\", result);\n\n    testCorsHandlerOptions();\n    testCorsHandlerGet();\n\n    TestMgr.summary();\n    System.setProperty(\"sun.net.http.allowRestrictedHeaders\", \"false\");\n  }\n\n  private static void testCorsHandlerOptions() {\n    // first domain\n    RestOperations springRestTemplate = new RestTemplate();\n    MultiValueMap<String, String> requestHeaders = new LinkedMultiValueMap<>();\n    requestHeaders.put(\"Origin\", Collections.singletonList(\"http://test.domain:8080\"));\n    requestHeaders.put(\"Access-Control-Request-Method\", Collections.singletonList(\"PUT\"));\n    HttpEntity<Object> requestEntity = new HttpEntity<>(requestHeaders);\n    ResponseEntity<String> responseEntity = springRestTemplate\n        .exchange(\"http://127.0.0.1:8080/helloworld/hello\", HttpMethod.OPTIONS, requestEntity,\n            String.class);\n    TestMgr.check(\"204\", responseEntity.getStatusCode().value());\n    TreeSet<String> sortedSet = new TreeSet<>(responseEntity.getHeaders().get(\"Access-Control-Allow-Methods\"));\n    TestMgr.check(\"[DELETE,POST,GET,PUT]\", sortedSet);\n    sortedSet = new TreeSet<>(responseEntity.getHeaders().get(\"Access-Control-Allow-Headers\"));\n    TestMgr.check(\"[abc,def]\", sortedSet);\n    TestMgr.check(\"http://test.domain:8080\",\n        responseEntity.getHeaders().getFirst(\"Access-Control-Allow-Origin\"));\n\n    // second domain\n    requestHeaders = new LinkedMultiValueMap<>();\n    requestHeaders.put(\"Origin\", Collections.singletonList(\"http://test.domain:9090\"));\n    requestHeaders.put(\"Access-Control-Request-Method\", Collections.singletonList(\"PUT\"));\n    requestEntity = new HttpEntity<>(requestHeaders);\n    responseEntity = springRestTemplate\n        .exchange(\"http://127.0.0.1:8080/helloworld/hello\", HttpMethod.OPTIONS, requestEntity,\n            String.class);\n    TestMgr.check(\"204\", responseEntity.getStatusCode().value());\n    sortedSet = new TreeSet<>(responseEntity.getHeaders().get(\"Access-Control-Allow-Methods\"));\n    TestMgr.check(\"[DELETE,POST,GET,PUT]\", sortedSet);\n    sortedSet = new TreeSet<>(responseEntity.getHeaders().get(\"Access-Control-Allow-Headers\"));\n    TestMgr.check(\"[abc,def]\", sortedSet);\n    TestMgr.check(\"http://test.domain:9090\",\n        responseEntity.getHeaders().getFirst(\"Access-Control-Allow-Origin\"));\n  }\n\n  private static void testCorsHandlerGet() {\n    // allowed origin\n    RestOperations springRestTemplate = new RestTemplate();\n    MultiValueMap<String, String> requestHeaders = new LinkedMultiValueMap<>();\n    requestHeaders.put(\"Origin\", Collections.singletonList(\"http://test.domain:8080\"));\n    HttpEntity<Object> requestEntity = new HttpEntity<>(requestHeaders);\n    ResponseEntity<String> responseEntity = springRestTemplate\n        .exchange(\"http://127.0.0.1:8080/helloworld/hello\", HttpMethod.GET, requestEntity,\n            String.class);\n\n    TestMgr.check(\"200\", responseEntity.getStatusCode().value());\n    TestMgr.check(\"hello world\", responseEntity.getBody());\n\n    // allowed origin\n    requestHeaders = new LinkedMultiValueMap<>();\n    requestHeaders.put(\"Origin\", Collections.singletonList(\"http://test.domain:9090\"));\n    requestEntity = new HttpEntity<>(requestHeaders);\n    responseEntity = springRestTemplate\n        .exchange(\"http://127.0.0.1:8080/helloworld/hello\", HttpMethod.GET, requestEntity,\n            String.class);\n\n    TestMgr.check(\"200\", responseEntity.getStatusCode().value());\n    TestMgr.check(\"hello world\", responseEntity.getBody());\n\n    // not allowed origin\n    try {\n      requestHeaders = new LinkedMultiValueMap<>();\n      requestHeaders.put(\"Origin\", Collections.singletonList(\"http://test.domain:7070\"));\n      requestEntity = new HttpEntity<>(requestHeaders);\n      springRestTemplate\n          .exchange(\"http://127.0.0.1:8080/helloworld/hello\", HttpMethod.GET, requestEntity,\n              String.class);\n      TestMgr.fail(\"must throw\");\n    } catch (HttpServerErrorException e) {\n      TestMgr.check(500, e.getStatusCode().value());\n      TestMgr.check(true, e.getMessage().contains(\"500 CORS Rejected\"));\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-client/src/main/java/org/apache/servicecomb/demo/crossapp/HelloWorld.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.crossapp;\n\npublic interface HelloWorld {\n  String sayHello();\n}\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: appClient\n    name: appClientService\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  handler:\n    chain:\n      Consumer:\n        default: loadbalance\n  loadbalance:\n    appServer:appService:\n      transactionControl:\n        policy: org.apache.servicecomb.loadbalance.filter.SimpleTransactionControlFilter\n        options:\n          tag0: value0\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-client/src/test/java/org/apache/servicecomb/demo/crossapp/CrossAppIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.crossapp;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = CrossappClient.class)\npublic class CrossAppIT {\n\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    CrossappClient.run();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-crossapp</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>crossapp-server</artifactId>\n  <name>Java Chassis::Demo::CrossApp::Server</name>\n\n  <dependencies>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.crossapp.CrossappServer</demo.main>\n  </properties>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-server/src/main/java/org/apache/servicecomb/demo/crossapp/CrossappServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.crossapp;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class CrossappServer {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(CrossappServer.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-server/src/main/java/org/apache/servicecomb/demo/crossapp/HelloWorldImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.crossapp;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\n@RestSchema(schemaId = \"helloworld\")\n@Path(\"helloworld\")\npublic class HelloWorldImpl {\n  @GET\n  @Path(\"hello\")\n  public String sayHello() {\n    return \"hello world\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-crossapp/crossapp-server/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: appServer\n    name: appService\n    version: 0.0.1\n    properties:\n      allowCrossApp: true\n      tag0: value0\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n  cors:\n    enabled: true\n    origin: \"http://test.domain:8080,http://test.domain:9090\"\n    allowedHeader: abc,def\n    allowedMethod: GET,PUT,POST,DELETE\n    exposedHeader: abc,def\n    maxAge: 1\n"
  },
  {
    "path": "demo/demo-crossapp/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-crossapp</artifactId>\n  <name>Java Chassis::Demo::CrossApp</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>crossapp-server</module>\n    <module>crossapp-client</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/README.md",
    "content": "# 使用微服务引擎专业版的测试用例\n\n* 首先登陆华为云华南区，获取 AK/SK。 测试机器设置环境变量： CREDENTIALS_AK、CREDENTIALS_SK。\n* 在配置中心增加如下配置：\n  * consumer.yaml\n\n```yaml\ncse:\n  v1:\n    test:\n      foo: foo\n      dynamicString: a,b\n      dynamicArray:\n        - m\n        - n\n```\n\n* 依次启动 provider、provider-canary、consumer、gateway\n* 在配置中心增加如下配置：\n  * cse.v1.test.bar: bar\n\n* 执行 tests-client 里面的集成测试用例\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v1</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v1-consumer</artifactId>\n  <name>Java Chassis::Demo::CSE-V1::CONSUMER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsumerApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsumerApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerConfigController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ConsumerConfigController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerConfigController {\n  private Environment environment;\n\n  private ConsumerConfigurationProperties consumerConfigurationProperties;\n\n  @Autowired\n  public ConsumerConfigController(Environment environment,\n      ConsumerConfigurationProperties consumerConfigurationProperties) {\n    this.environment = environment;\n    this.consumerConfigurationProperties = consumerConfigurationProperties;\n  }\n\n  @GetMapping(\"/config\")\n  public String config(@RequestParam(\"key\") String key) {\n    return environment.getProperty(key);\n  }\n\n  @GetMapping(\"/foo\")\n  public String foo() {\n    return consumerConfigurationProperties.getFoo();\n  }\n\n  @GetMapping(\"/bar\")\n  public String bar() {\n    return consumerConfigurationProperties.getBar();\n  }\n\n  @GetMapping(\"/dynamicString\")\n  public String dynamicString(@RequestParam(\"key\") String key) {\n    return environment.getProperty(key);\n  }\n\n  @GetMapping(\"/dynamicArray\")\n  @SuppressWarnings(\"unchecked\")\n  public List<String> dynamicArray() {\n    return consumerConfigurationProperties.getDynamicArray();\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerConfigurationProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.stereotype.Component;\n\n@ConfigurationProperties(\"cse.v1.test\")\n@Component\npublic class ConsumerConfigurationProperties {\n  private String foo;\n\n  private String bar;\n\n  private List<String> dynamicArray;\n\n  public String getFoo() {\n    return foo;\n  }\n\n  public void setFoo(String foo) {\n    this.foo = foo;\n  }\n\n  public String getBar() {\n    return bar;\n  }\n\n  public void setBar(String bar) {\n    this.bar = bar;\n  }\n\n  public List<String> getDynamicArray() {\n    return dynamicArray;\n  }\n\n  public void setDynamicArray(List<String> dynamicArray) {\n    this.dynamicArray = dynamicArray;\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ConsumerController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerController {\n  @RpcReference(schemaId = \"ProviderController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  // consumer service which delegate the implementation to provider service.\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return providerService.sayHello(name);\n  }\n\n  @GetMapping(\"/sayHelloCanary\")\n  public String sayHelloCanary(@RequestParam(\"name\") String name) {\n    return providerService.sayHelloCanary(name);\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface ProviderService {\n  String sayHello(String name);\n\n  String sayHelloCanary(String name);\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v1\n    name: consumer\n    version: 0.0.1\n  registry:\n    sc:\n      address: https://cse.cn-south-1.myhuaweicloud.com\n      watch: false\n  config:\n    client:\n      serverUri: https://cse.cn-south-1.myhuaweicloud.com\n      fileSource: consumer.yaml\n\n  rest:\n    address: 0.0.0.0:9092  # should be same with server.port to use web container\n\n  routeRule:\n    provider: |\n      - precedence: 1\n        match:\n          headers:\n            canary:\n              exact: new\n        route:\n          - weight: 20\n            tags:\n              version: 0.0.1\n          - weight: 80\n            tags:\n              version: 0.0.2\n      - precedence: 2\n        match:\n          headers:\n            canary:\n              exact: old\n        route:\n          - weight: 100\n            tags:\n              version: 0.0.1\n      - precedence: 3\n        match:\n          headers:\n            canary:\n              exact: fallback\n        route:\n          - weight: 100\n            tags:\n              version: 0.0.3\n        fallback:\n          - weight: 20\n            tags:\n              version: 0.0.1\n          - weight: 80\n            tags:\n              version: 0.0.2\n      - precedence: 4\n        emptyProtection: false\n        match:\n          headers:\n            canary:\n              exact: emptyProtectionClose100\n        route:\n          - weight: 100\n            tags:\n              version: 0.0.3\n      - precedence: 5\n        emptyProtection: false\n        match:\n          headers:\n            canary:\n              exact: emptyProtectionCloseLess100\n        route:\n          - weight: 50\n            tags:\n              version: 0.0.3\n      - precedence: 6\n        emptyProtection: false\n        match:\n          headers:\n            canary:\n              exact: emptyProtectionCloseFallback\n        route:\n          - weight: 100\n            tags:\n              version: 0.0.3\n        fallback:\n          - weight: 100\n            tags:\n              version: 0.0.1\n      - precedence: 7\n        emptyProtection: false\n        match:\n          headers:\n            canary:\n              exact: emptyProtectionClose100-2\n        route:\n          - weight: 50\n            tags:\n              version: 0.0.1\n          - weight: 50\n            tags:\n              version: 0.0.3\n\n\n  router:\n    type: router\n    header: canary\n\n  # Configure AK/SK credentials if needed. Default not enabled.\n  credentials:\n    akskEnabled: true\n    accessKey: ${CREDENTIALS_AK}\n    secretKey: ${CREDENTIALS_SK}\n    akskCustomCipher: default\n    project: cn-south-1\n"
  },
  {
    "path": "demo/demo-cse-v1/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./file/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10 MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v1/gateway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v1</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v1-gateway</artifactId>\n  <name>Java Chassis::Demo::CSE-V1::GATEWAY</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class GatewayApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/gateway/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# override common configurations in common module\nservicecomb-config-order: 100\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v1\n    name: gateway\n    version: 0.0.1\n  registry:\n    sc:\n      address: https://cse.cn-south-1.myhuaweicloud.com\n      watch: false\n  config:\n    client:\n      serverUri: https://cse.cn-south-1.myhuaweicloud.com\n\n  rest:\n    address: 0.0.0.0:9090?sslEnabled=false\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n\n  matchGroup:\n    canary-header: |\n      matches:\n        - headers:\n            canary:\n              prefix: \"\"\n  mapper:\n    canary-header: |\n      target:\n        canary: $H{canary}\n\n  # Configure AK/SK credentials if needed. Default not enabled.\n  credentials:\n    akskEnabled: true\n    accessKey: ${CREDENTIALS_AK}\n    secretKey: ${CREDENTIALS_SK}\n    akskCustomCipher: default\n    project: cn-south-1\n"
  },
  {
    "path": "demo/demo-cse-v1/gateway/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./gateway/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10 MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v1/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-cse-v1</artifactId>\n  <name>Java Chassis::Demo::CSE-V1</name>\n  <packaging>pom</packaging>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>dashboard</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>darklaunch</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-cc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicestage</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>provider</module>\n    <module>provider-canary</module>\n    <module>consumer</module>\n    <module>gateway</module>\n    <module>test-client</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/provider/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v1</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v1-provider</artifactId>\n  <name>Java Chassis::Demo::CSE-V1::PROVIDER</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/provider/src/main/java/org/apache/servicecomb/samples/ProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController {\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return \"Hello \" + name;\n  }\n\n  @GetMapping(\"/sayHelloCanary\")\n  public String sayHelloCanary(@RequestParam(\"name\") String name) {\n    return \"Hello Canary \" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/provider/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v1\n    name: provider\n    version: 0.0.1\n  registry:\n    sc:\n      address: https://cse.cn-south-1.myhuaweicloud.com\n      watch: false\n  config:\n    client:\n      serverUri: https://cse.cn-south-1.myhuaweicloud.com\n\n  rest:\n    address: 0.0.0.0:9093 # should be same with server.port to use web container\n\n# Configure AK/SK credentials if needed. Default not enabled.\n  credentials:\n    akskEnabled: true\n    accessKey: ${CREDENTIALS_AK}\n    secretKey: ${CREDENTIALS_SK}\n    akskCustomCipher: default\n    project: cn-south-1\n"
  },
  {
    "path": "demo/demo-cse-v1/provider/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./user/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v1/provider-canary/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v1</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v1-provider-canary</artifactId>\n  <name>Java Chassis::Demo::CSE-V1::PROVIDER CANARY</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/provider-canary/src/main/java/org/apache/servicecomb/samples/ProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/provider-canary/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController {\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return \"Hello in canary \" + name;\n  }\n\n  @GetMapping(\"/sayHelloCanary\")\n  public String sayHelloCanary(@RequestParam(\"name\") String name) {\n    return \"Hello Canary in canary \" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/provider-canary/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v1\n    name: provider\n    version: 0.0.2\n  registry:\n    sc:\n      address: https://cse.cn-south-1.myhuaweicloud.com\n      watch: false\n  config:\n    client:\n      serverUri: https://cse.cn-south-1.myhuaweicloud.com\n\n  rest:\n    address: 0.0.0.0:9095\n\n# Configure AK/SK credentials if needed. Default not enabled.\n  credentials:\n    akskEnabled: true\n    accessKey: ${CREDENTIALS_AK}\n    secretKey: ${CREDENTIALS_SK}\n    akskCustomCipher: default\n    project: cn-south-1\n"
  },
  {
    "path": "demo/demo-cse-v1/provider-canary/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./user/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v1</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v1-test-client</artifactId>\n  <name>Java Chassis::Demo::CSE-V1::TEST-CLIENT</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface Config {\n  String GATEWAY_URL = \"http://localhost:9090\";\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/ConsumerConfigIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class ConsumerConfigIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testConfig();\n    testFooBar();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testConfig() {\n    String result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v1.test.foo\", String.class);\n    TestMgr.check(\"foo\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v1.test.bar\", String.class);\n    TestMgr.check(\"bar\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/dynamicString?key=cse.v1.test.dynamicString\", String.class);\n    TestMgr.check(\"a,b\", result);\n\n    List<String> listResult = template\n        .getForObject(Config.GATEWAY_URL + \"/dynamicArray\", List.class);\n    TestMgr.check(2, listResult.size());\n    TestMgr.check(\"m\", listResult.get(0));\n    TestMgr.check(\"n\", listResult.get(1));\n  }\n\n  private void testFooBar() {\n    String result = template.getForObject(Config.GATEWAY_URL + \"/foo\", String.class);\n    TestMgr.check(\"foo\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/bar\", String.class);\n    TestMgr.check(\"bar\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n\n@Component\npublic class HelloWorldIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHelloWorldFallback();\n    testHelloWorldNoHeader();\n    testHelloWorld();\n    testHelloWorldCanary();\n    testHelloWorldEmptyProtectionCloseWeight100();\n    testHelloWorldeEmptyProtectionCloseWeightLess100();\n    testHelloWorldEmptyProtectionCloseFallback();\n    testHelloWorldEmptyProtectionCloseWeight100Two();\n  }\n\n  private void testHelloWorld() {\n    for (int i = 0; i < 10; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"old\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      String result = template\n          .exchange(Config.GATEWAY_URL + \"/sayHello?name=World\", HttpMethod.GET, entity, String.class).getBody();\n      TestMgr.check(\"Hello World\", result);\n    }\n  }\n\n  private void testHelloWorldCanary() {\n    int oldCount = 0;\n    int newCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"new\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      String result = template\n          .exchange(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", HttpMethod.GET, entity, String.class).getBody();\n      if (result.equals(\"Hello Canary World\")) {\n        oldCount++;\n      } else if (result.equals(\"Hello Canary in canary World\")) {\n        newCount++;\n      } else {\n        TestMgr.fail(\"not expected result testHelloWorldCanary\");\n        return;\n      }\n    }\n\n    double ratio = oldCount / (float) (oldCount + newCount);\n    TestMgr.check(ratio > 0.1 && ratio < 0.3, true);\n  }\n\n  private void testHelloWorldFallback() {\n    int oldCount = 0;\n    int newCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"fallback\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      String result = template\n          .exchange(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", HttpMethod.GET, entity, String.class).getBody();\n      if (result.equals(\"\\\"Hello Canary World\\\"\")) {\n        oldCount++;\n      } else if (result.equals(\"\\\"Hello Canary in canary World\\\"\")) {\n        newCount++;\n      } else {\n        TestMgr.fail(\"not expected result testHelloWorldCanary\");\n        return;\n      }\n    }\n\n    double ratio = oldCount / (float) (oldCount + newCount);\n    TestMgr.check(Math.abs(ratio - 0.2) <= 0.1, true);\n  }\n\n  private void testHelloWorldNoHeader() {\n    int oldCount = 0;\n    int newCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      String result = template\n          .getForObject(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", String.class);\n      if (result.equals(\"\\\"Hello Canary World\\\"\")) {\n        oldCount++;\n      } else if (result.equals(\"\\\"Hello Canary in canary World\\\"\")) {\n        newCount++;\n      } else {\n        TestMgr.fail(\"not expected result testHelloWorldCanary\");\n        return;\n      }\n    }\n\n    double ratio = oldCount / (float) (oldCount + newCount);\n    TestMgr.check(Double.compare(ratio, 0.5) == 0, true);\n  }\n\n  private void testHelloWorldEmptyProtectionCloseWeight100() {\n    int failCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"emptyProtectionClose100\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      try {\n        template.exchange(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", HttpMethod.GET,\n            entity, String.class);\n      } catch (Exception e) {\n        failCount++;\n      }\n    }\n\n    TestMgr.check(failCount == 20, true);\n  }\n\n  private void testHelloWorldeEmptyProtectionCloseWeightLess100() {\n    int failCount = 0;\n    int succCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"emptyProtectionCloseLess100\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      try {\n        template.exchange(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", HttpMethod.GET,\n            entity, String.class);\n        succCount++;\n      } catch (Exception e) {\n        failCount++;\n      }\n    }\n\n    TestMgr.check(succCount == 20, true);\n  }\n\n  private void testHelloWorldEmptyProtectionCloseFallback() {\n    int failCount = 0;\n    int succCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"emptyProtectionCloseFallback\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      try {\n        template.exchange(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", HttpMethod.GET,\n            entity, String.class);\n        succCount++;\n      } catch (Exception e) {\n        failCount++;\n      }\n    }\n\n    TestMgr.check(succCount == 20, true);\n  }\n\n  private void testHelloWorldEmptyProtectionCloseWeight100Two() {\n    int failCount = 0;\n    int succCount = 0;\n\n    for (int i = 0; i < 20; i++) {\n      MultiValueMap<String, String> headers = new HttpHeaders();\n      headers.add(\"canary\", \"emptyProtectionClose100-2\");\n      HttpEntity<Object> entity = new HttpEntity<>(headers);\n      try {\n        template.exchange(Config.GATEWAY_URL + \"/sayHelloCanary?name=World\", HttpMethod.GET,\n            entity, String.class);\n        succCount++;\n      } catch (Exception e) {\n        failCount++;\n      }\n    }\n\n    TestMgr.check(failCount == succCount, true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class TestClientApplication {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args);\n\n      CategorizedTestCaseRunner.runCategorizedTestCase(\"consumer\");\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v1\n    name: test-client\n    version: 0.0.1\n  registry:\n    sc:\n      address: https://cse.cn-south-1.myhuaweicloud.com\n      watch: false\n  config:\n    client:\n      serverUri: https://cse.cn-south-1.myhuaweicloud.com\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n\n  # Configure AK/SK credentials if needed. Default not enabled.\n  credentials:\n    akskEnabled: true\n    accessKey: ${CREDENTIALS_AK}\n    secretKey: ${CREDENTIALS_SK}\n    akskCustomCipher: default\n    project: cn-south-1\n"
  },
  {
    "path": "demo/demo-cse-v1/test-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./user/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v2/README.md",
    "content": "# 使用微服务引擎2.0的测试用例\n\n* 参考：https://support.huaweicloud.com/devg-cse/cse_devg_0036.html 安装微服务引擎2.0\n\n* 设置环境变量:\n  * PAAS_CSE_SC_ENDPOINT: 注册中心的地址\n  * PAAS_CSE_CC_ENDPOINT: 配置中心的地址\n\n* 依次启动 provider、consumer、gateway\n\n* 在配置中心增加如下配置：\n* 应用级配置：consumer.yaml。类型为 yaml。\n\n```yaml\ncse:\n  v2:\n    test:\n      foo: foo\n```\n\n  * 自定义配置：priority1.yaml。label信息： public=default 。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority: v1\n      common: common\n```\n\n  * 自定义配置：priority1.yaml。label信息： public=default,extra=default 。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority: v1\n      extra: common\n```\n\n  * 应用级配置：priority2.yaml。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority: v2\n```\n\n  * 服务级配置：priority3.yaml，微服务性选择consumer。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority: v3\n```\n\n* 应用级配置：consumerApp.yaml，应用选择demo-java-chassis-cse-v2。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority1: v1\n```\n\n* 服务级配置：consumerService.yaml，微服务性选择consumer。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority1: v2\n```\n\n  * 应用级配置： cse.v2.test.bar: bar 。 类型为 text。\n\n* 执行 tests-client 里面的集成测试用例 （成功）\n\n* 修改\n  * priority1.yaml。label信息： public=default 。类型为 yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority: v4\n```\n\n* 执行 tests-client 里面的集成测试用例 （成功）\n\n* 修改\n  * 应用级priority3.yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority: v5\n```\n\n* 执行 tests-client 里面的集成测试用例 （失败）\n\n* 修改\n  * 应用级priority3.yaml。label信息：\n```yaml\ncse:\n  v2:\n    test:\n      priority: v3\n```\n\n* 执行 tests-client 里面的集成测试用例 （成功）\n* 修改\n  * 应用级consumerApp.yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority1: v10\n```\n\n* 执行 tests-client 里面的集成测试用例 （成功）\n* 修改\n  * 服务级配置：consumerService.yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority1: v20\n```\n\n* 执行 tests-client 里面的集成测试用例 （成功）\n\n* 修改\n  * 版本级配置：consumerIns.yaml。\n```yaml\ncse:\n  v2:\n    test:\n      priority1: v30\n```\n\n* 执行 tests-client 里面的集成测试用例 （失败）\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v2</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v2-consumer</artifactId>\n  <name>Java Chassis::Demo::CSE-V2::CONSUMER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsumerApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsumerApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerConfigController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ConsumerConfigController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerConfigController {\n  private Environment environment;\n\n  private ConsumerConfigurationProperties consumerConfigurationProperties;\n\n  @Autowired\n  public ConsumerConfigController(Environment environment, ConsumerConfigurationProperties consumerConfigurationProperties) {\n    this.environment = environment;\n    this.consumerConfigurationProperties = consumerConfigurationProperties;\n  }\n\n  @GetMapping(\"/config\")\n  public String config(@RequestParam(\"key\") String key) {\n    return environment.getProperty(key);\n  }\n\n  @GetMapping(\"/foo\")\n  public String foo() {\n    return consumerConfigurationProperties.getFoo();\n  }\n\n  @GetMapping(\"/bar\")\n  public String bar() {\n    return consumerConfigurationProperties.getBar();\n  }\n\n  @GetMapping(\"/priority\")\n  public String priority() {\n    return consumerConfigurationProperties.getPriority();\n  }\n\n  @GetMapping(\"/common\")\n  public String common() {\n    return consumerConfigurationProperties.getCommon();\n  }\n\n  @GetMapping(\"/extra\")\n  public String extra() {\n    return consumerConfigurationProperties.getExtra();\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerConfigurationProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.stereotype.Component;\n\n@ConfigurationProperties(\"cse.v2.test\")\n@Component\npublic class ConsumerConfigurationProperties {\n  private String foo;\n\n  private String bar;\n\n  private String priority;\n\n  private String common;\n\n  private String extra;\n\n  public String getFoo() {\n    return foo;\n  }\n\n  public void setFoo(String foo) {\n    this.foo = foo;\n  }\n\n  public String getBar() {\n    return bar;\n  }\n\n  public void setBar(String bar) {\n    this.bar = bar;\n  }\n\n  public String getPriority() {\n    return priority;\n  }\n\n  public void setPriority(String priority) {\n    this.priority = priority;\n  }\n\n  public String getCommon() {\n    return common;\n  }\n\n  public void setCommon(String common) {\n    this.common = common;\n  }\n\n  public String getExtra() {\n    return extra;\n  }\n\n  public void setExtra(String extra) {\n    this.extra = extra;\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ConsumerController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerController {\n  @RpcReference(schemaId = \"ProviderController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  // consumer service which delegate the implementation to provider service.\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return providerService.sayHello(name);\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface ProviderService {\n  String sayHello(String name);\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v2\n    name: consumer\n    version: 0.0.1\n  registry:\n    sc:\n      address: ${PAAS_CSE_SC_ENDPOINT:http://127.0.0.1:30100}\n      watch: false\n  kie:\n    serverUri: ${PAAS_CSE_CC_ENDPOINT:http://127.0.0.1:30110}\n    customLabel: public\n    customLabelValue: default\n\n  rest:\n    address: 0.0.0.0:9092  # should be same with server.port to use web container\n"
  },
  {
    "path": "demo/demo-cse-v2/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./file/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10 MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v2/gateway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v2</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v2-gateway</artifactId>\n  <name>Java Chassis::Demo::CSE-V2::GATEWAY</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v2/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class GatewayApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/gateway/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# override common configurations in common module\nservicecomb-config-order: 100\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v2\n    name: gateway\n    version: 0.0.1\n  registry:\n    sc:\n      address: ${PAAS_CSE_SC_ENDPOINT:http://127.0.0.1:30100}\n      watch: false\n\n  kie:\n    serverUri: ${PAAS_CSE_CC_ENDPOINT:http://127.0.0.1:30110}\n    customLabel: public\n\n  rest:\n    address: 0.0.0.0:9090?sslEnabled=false\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n"
  },
  {
    "path": "demo/demo-cse-v2/gateway/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./gateway/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10 MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v2/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-cse-v2</artifactId>\n  <name>Java Chassis::Demo::CSE-V2</name>\n  <packaging>pom</packaging>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-kie</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>provider</module>\n    <module>consumer</module>\n    <module>gateway</module>\n    <module>test-client</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v2/provider/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v2</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v2-provider</artifactId>\n  <name>Java Chassis::Demo::CSE-V2::PROVIDER</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v2/provider/src/main/java/org/apache/servicecomb/samples/ProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController {\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return \"Hello \" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/provider/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# spring boot configurations\nserver:\n  port: 9093  # should be same with servicecomb.rest.address to use web container\n\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v2\n    name: provider\n    version: 0.0.1\n  registry:\n    sc:\n      address: ${PAAS_CSE_SC_ENDPOINT:http://127.0.0.1:30100}\n      watch: false\n  kie:\n    serverUri: ${PAAS_CSE_CC_ENDPOINT:http://127.0.0.1:30110}\n    customLabel: public\n\n  rest:\n    address: 0.0.0.0:9093 # should be same with server.port to use web container\n"
  },
  {
    "path": "demo/demo-cse-v2/provider/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./user/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-cse-v2</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>cse-v2-test-client</artifactId>\n  <name>Java Chassis::Demo::CSE-V2::TEST-CLIENT</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/src/main/java/org/apache/servicecomb/samples/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface Config {\n  String GATEWAY_URL = \"http://localhost:9090\";\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/src/main/java/org/apache/servicecomb/samples/ConsumerConfigIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class ConsumerConfigIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testConfig();\n    testFooBar();\n  }\n\n  private void testConfig() {\n    String result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v2.test.foo\", String.class);\n    TestMgr.check(\"foo\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v2.test.bar\", String.class);\n    TestMgr.check(\"bar\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v2.test.priority\", String.class);\n    TestMgr.check(\"v1\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v2.test.common\", String.class);\n    TestMgr.check(\"common\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v2.test.extra\", String.class);\n    TestMgr.check(\"common\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/config?key=cse.v2.test.priority1\", String.class);\n    TestMgr.check(\"v2\", result);\n  }\n\n  private void testFooBar() {\n    String result = template.getForObject(Config.GATEWAY_URL + \"/bar\", String.class);\n    TestMgr.check(\"bar\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/foo\", String.class);\n    TestMgr.check(\"foo\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/priority\", String.class);\n    TestMgr.check(\"v1\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/common\", String.class);\n    TestMgr.check(\"common\", result);\n    result = template.getForObject(Config.GATEWAY_URL + \"/extra\", String.class);\n    TestMgr.check(\"common\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HelloWorldIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHelloWorld();\n  }\n\n  private void testHelloWorld() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/sayHello?name=World\", String.class);\n    TestMgr.check(\"Hello World\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class TestClientApplication {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args);\n\n      CategorizedTestCaseRunner.runCategorizedTestCase(\"consumer\");\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# spring boot configurations\nserver:\n  port: 9093  # should be same with servicecomb.rest.address to use web container\n\n# override common configurations in common module\nservicecomb-config-order: 10\n\nservicecomb:\n  service:\n    application: demo-java-chassis-cse-v2\n    name: test-client\n    version: 0.0.1\n  registry:\n    sc:\n      address: ${PAAS_CSE_SC_ENDPOINT:http://127.0.0.1:30100}\n      watch: false\n  kie:\n    serverUri: ${PAAS_CSE_CC_ENDPOINT:http://127.0.0.1:30110}\n    customLabel: public\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n"
  },
  {
    "path": "demo/demo-cse-v2/test-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish -->\n\n<configuration>\n  <Properties>\n    <Property name=\"log_path\">./user/log/</Property>\n  </Properties>\n\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n    </Console>\n    <RollingFile name=\"DailyRollingFile\" fileName=\"${log_path}/output.log\"\n      filePattern=\"${log_path}/zcrTest%d{yyyy-MM-dd}.log\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n      <Policies>\n        <TimeBasedTriggeringPolicy interval=\"1\" />\n        <SizeBasedTriggeringPolicy size=\"10MB\" />\n      </Policies>\n    </RollingFile>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\" />\n      <AppenderRef ref=\"DailyRollingFile\" />\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-edge/README.md",
    "content": "# About edge service API compatibility\n\n* Edge service use the latest version of the microservice meta. e.g. For business 1.0.0, 1.1.0, 2.0.0 have the following APIs:\n\n    * 1.0.0: /business/v1/add\n    * 1.1.0: /business/v1/add, /business/v1/dec\n    * 2.0.0: /business/v2/add, /business/v2/dec\n\n    If users invoke /business/v1/add, edge service will give NOT FOUND, because 2.0.0 microservice meta do not have this API. Even using router to route all /business/v1/* requests to 1.1.0, path locating happens before load balance.\n\n* It's very important to keep your API compatibility cross versions if these versions need work together. e.g.\n\n    * 1.0.0: /business/v1/add\n    * 1.1.0: /business/v1/add, /business/v1/dec\n    * 2.0.0: /business/v1/add, /business/v1/dec, /business/v2/add, /business/v2/dec\n\n    Together with router, /business/v1/add will go correctly to 1.0.0 or 1.1.0, and /business/v2/add will go correctly to 2.0.0. Without router, /business/v2/add may route to 1.0.0 or 1.1.0 and NOT FOUND is reported.\n"
  },
  {
    "path": "demo/demo-edge/authentication/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>authentication</artifactId>\n  <name>Java Chassis::Demo::Edge::Authentication</name>\n  <dependencies>\n  </dependencies>\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.edge.authentication.AuthMain</demo.main>\n  </properties>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/authentication/src/main/java/org/apache/servicecomb/demo/edge/authentication/AuthImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.authentication;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"auth\")\n@RequestMapping(path = \"auth/v1\")\npublic class AuthImpl {\n  @PostMapping(path = \"/auth\")\n  public boolean auth(@RequestHeader(name = \"info\") String info) {\n    return true;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/authentication/src/main/java/org/apache/servicecomb/demo/edge/authentication/AuthMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.authentication;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class AuthMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(AuthMain.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/authentication/src/main/java/org/apache/servicecomb/demo/edge/authentication/encrypt/EncryptImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.authentication.encrypt;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"encrypt\")\n@RequestMapping(path = \"auth/v1\")\npublic class EncryptImpl {\n  @GetMapping(path = \"/queryUserId\")\n  public String queryUserId(String serviceToken) {\n    return serviceToken + \"-userId\";\n  }\n\n  @GetMapping(path = \"/queryHcr\")\n  public Hcr queryHcr(String hcrId) {\n    Hcr hcr = new Hcr();\n    hcr.setBodyKey(\"bodyKey-\" + hcrId + \"-\");\n    hcr.setSignatureKey(\"signatureKey-\" + hcrId + \"-\");\n    return hcr;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/authentication/src/main/java/org/apache/servicecomb/demo/edge/authentication/encrypt/Hcr.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.authentication.encrypt;\n\npublic class Hcr {\n  private String bodyKey;\n\n  private String signatureKey;\n\n  public String getBodyKey() {\n    return bodyKey;\n  }\n\n  public void setBodyKey(String bodyKey) {\n    this.bodyKey = bodyKey;\n  }\n\n  public String getSignatureKey() {\n    return signatureKey;\n  }\n\n  public void setSignatureKey(String signatureKey) {\n    this.signatureKey = signatureKey;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/authentication/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-edge/authentication/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: edge\n    name: auth\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:7070?protocol=http2\n    server:\n      http2:\n        useAlpnEnabled: false\n      # for test case run in one core machine\n      verticle-count: 1\n"
  },
  {
    "path": "demo/demo-edge/business-1-1-0/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>business-1-1-0</artifactId>\n  <name>Java Chassis::Demo::Edge::Business 1.1.0</name>\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.edge.business.BusinessMain_V1_1_0</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>model</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/business-1-1-0/src/main/java/org/apache/servicecomb/demo/edge/business/BusinessMain_V1_1_0.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class BusinessMain_V1_1_0 {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(BusinessMain_V1_1_0.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-1-1-0/src/main/java/org/apache/servicecomb/demo/edge/business/Impl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport org.apache.servicecomb.demo.edge.model.AppClientDataRsp;\nimport org.apache.servicecomb.demo.edge.model.ChannelRequestBase;\nimport org.apache.servicecomb.demo.edge.model.ResultWithInstance;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RestSchema(schemaId = \"news-v1\")\n@RequestMapping(path = \"/business/v1\")\npublic class Impl {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @RequestMapping(path = \"/channel/news/subscribe\", method = RequestMethod.POST)\n  public AppClientDataRsp subscribeNewsColumn(@RequestBody ChannelRequestBase request) {\n    AppClientDataRsp response = new AppClientDataRsp();\n    String rsp = \"result from 1.1.0\";\n    response.setRsp(rsp);\n    return response;\n  }\n\n  @RequestMapping(path = \"/add\", method = RequestMethod.GET)\n  public ResultWithInstance add(int x, int y) {\n    return ResultWithInstance.create(x + y, environment);\n  }\n\n  @RequestMapping(path = \"/dec\", method = RequestMethod.GET)\n  public ResultWithInstance dec(int x, int y) {\n    return ResultWithInstance.create(x - y, environment);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-1-1-0/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-edge/business-1-1-0/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: edge\n    name: business\n    version: 1.1.0\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8090\n    server:\n      verticle-count: 1\n"
  },
  {
    "path": "demo/demo-edge/business-1.0.0/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>business-1-0-0</artifactId>\n  <name>Java Chassis::Demo::Edge::Business 1.0.0</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.edge.business.BusinessMain_V1_0_0</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>model</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/business-1.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/BusinessMain_V1_0_0.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class BusinessMain_V1_0_0 {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(BusinessMain_V1_0_0.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-1.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/Impl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport org.apache.servicecomb.demo.edge.model.AppClientDataRsp;\nimport org.apache.servicecomb.demo.edge.model.ChannelRequestBase;\nimport org.apache.servicecomb.demo.edge.model.ResultWithInstance;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RestSchema(schemaId = \"news-v1\")\n@RequestMapping(path = \"/business/v1\")\npublic class Impl {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @RequestMapping(path = \"/channel/news/subscribe\", method = RequestMethod.POST)\n  public AppClientDataRsp subscribeNewsColumn(@RequestBody ChannelRequestBase request) {\n    AppClientDataRsp response = new AppClientDataRsp();\n    String rsp = \"result from 1.0.0\";\n    response.setRsp(rsp);\n    return response;\n  }\n\n  @RequestMapping(path = \"/add\", method = RequestMethod.GET)\n  public ResultWithInstance add(int x, int y) {\n    return ResultWithInstance.create(x + y, environment);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-1.0.0/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-edge/business-1.0.0/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: edge\n    name: business\n    version: 1.0.0\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n    server:\n      verticle-count: 1\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>business-2-0-0</artifactId>\n  <name>Java Chassis::Demo::Edge::Business 2.0.0</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.edge.business.BusinessMain_V2_0_0</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>model</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/BusinessMain_V2_0_0.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class BusinessMain_V2_0_0 {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(BusinessMain_V2_0_0.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/EdgeServiceGovernanceService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\n\n@RestSchema(schemaId = \"EdgeServiceGovernanceService\")\n@RequestMapping(path = \"/business/v2\")\npublic class EdgeServiceGovernanceService {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EdgeServiceGovernanceService.class);\n\n  private Map<String, Integer> retryTimes = new HashMap<>();\n\n  private AtomicInteger instanceIsolationIndex = new AtomicInteger();\n\n  @GetMapping(\"/testEdgeServiceRetry\")\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\"),\n      @ApiResponse(responseCode = \"502\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\")})\n  public String testEdgeServiceRetry(@RequestParam(name = \"invocationID\") String invocationID) {\n    LOGGER.info(\"invoke service: {}\", invocationID);\n    retryTimes.putIfAbsent(invocationID, 0);\n    retryTimes.put(invocationID, retryTimes.get(invocationID) + 1);\n\n    int retry = retryTimes.get(invocationID);\n\n    if (retry == 3) {\n      return \"try times: \" + retry;\n    }\n    throw new InvocationException(502, \"retry\", \"retry\");\n  }\n\n  @GetMapping(\"/testEdgeServiceInstanceIsolation\")\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\"),\n      @ApiResponse(responseCode = \"502\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\")})\n  public String testEdgeServiceInstanceIsolation(@RequestParam(name = \"name\") String name) {\n    if (instanceIsolationIndex.getAndIncrement() % 3 != 0) {\n      throw new InvocationException(502, \"InstanceIsolation\", \"InstanceIsolation\");\n    }\n    return name;\n  }\n\n  @GetMapping(\"/testEdgeServiceInstanceBulkhead\")\n  public String testEdgeServiceInstanceBulkhead(@RequestParam(name = \"name\") String name) {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/Impl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport org.apache.servicecomb.demo.edge.model.AppClientDataRsp;\nimport org.apache.servicecomb.demo.edge.model.ChannelRequestBase;\nimport org.apache.servicecomb.demo.edge.model.ResultWithInstance;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RestSchema(schemaId = \"news-v1\")\n@RequestMapping(path = \"/business/v1\")\npublic class Impl {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @RequestMapping(path = \"/channel/news/subscribe\", method = RequestMethod.POST)\n  public AppClientDataRsp subscribeNewsColumn(@RequestBody ChannelRequestBase request) {\n    AppClientDataRsp response = new AppClientDataRsp();\n    String rsp = \"result from 2.0.0\";\n    response.setRsp(rsp);\n    return response;\n  }\n\n  @RequestMapping(path = \"/add\", method = RequestMethod.GET)\n  public ResultWithInstance add(int x, int y) {\n    return ResultWithInstance.create(x + y, environment);\n  }\n\n  @RequestMapping(path = \"/dec\", method = RequestMethod.GET)\n  public ResultWithInstance dec(int x, int y) {\n    return ResultWithInstance.create(x - y, environment);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/ImplV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.RandomAccessFile;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.demo.edge.model.AppClientDataRsp;\nimport org.apache.servicecomb.demo.edge.model.ChannelRequestBase;\nimport org.apache.servicecomb.demo.edge.model.DependTypeA;\nimport org.apache.servicecomb.demo.edge.model.RecursiveSelfType;\nimport org.apache.servicecomb.demo.edge.model.ResultWithInstance;\nimport org.apache.servicecomb.demo.edge.model.User;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\n\n@RestSchema(schemaId = \"news-v2\")\n@RequestMapping(path = \"/business/v2\")\npublic class ImplV2 {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  File tempDir = new File(\"target/downloadTemp\");\n\n  public ImplV2() throws IOException {\n    FileUtils.forceMkdir(tempDir);\n  }\n\n  @RequestMapping(path = \"/channel/news/subscribe\", method = RequestMethod.POST)\n  public AppClientDataRsp subscribeNewsColumn(@RequestBody ChannelRequestBase request) {\n    AppClientDataRsp response = new AppClientDataRsp();\n    String rsp = \"result from 2.0.0\";\n    response.setRsp(rsp);\n    return response;\n  }\n\n  @RequestMapping(path = \"/add\", method = RequestMethod.GET)\n  public ResultWithInstance add(int x, int y) {\n    return ResultWithInstance.create(x + y, environment);\n  }\n\n  @RequestMapping(path = \"/dec\", method = RequestMethod.GET)\n  public ResultWithInstance dec(int x, int y) {\n    return ResultWithInstance.create(x - y, environment);\n  }\n\n  @GetMapping(path = \"/download\")\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = File.class)), description = \"\"),\n  })\n  public ResponseEntity<InputStream> download() throws IOException {\n    return ResponseEntity\n        .ok()\n        .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE)\n        .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=download.txt\")\n        .body(new ByteArrayInputStream(\"download\".getBytes(StandardCharsets.UTF_8)));\n  }\n\n  protected File createBigFile() throws IOException {\n    File file = new File(tempDir, \"bigFile.txt\");\n    file.delete();\n    RandomAccessFile randomAccessFile = new RandomAccessFile(file, \"rw\");\n    randomAccessFile.setLength(10 * 1024 * 1024);\n    randomAccessFile.close();\n    return file;\n  }\n\n  @GetMapping(path = \"/bigFile\")\n  public File bigFile() throws IOException {\n    return createBigFile();\n  }\n\n  @PostMapping(path = \"recursiveSelf\")\n  public RecursiveSelfType recursiveSelf(@RequestBody RecursiveSelfType value) {\n    return value;\n  }\n\n  @PostMapping(path = \"dependType\")\n  public DependTypeA dependType(@RequestBody DependTypeA value) {\n    return value;\n  }\n\n  @PostMapping(path = \"encrypt\")\n  public User encrypt(@RequestBody User value) {\n    return value;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToProducerResponseConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business.error;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class CustomExceptionToProducerResponseConverter implements\n    ExceptionConverter<IllegalStateException> {\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof IllegalStateException;\n  }\n\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, IllegalStateException e,\n      StatusType genericStatus) {\n    IllegalStateErrorData data = new IllegalStateErrorData();\n    data.setId(500);\n    data.setMessage(e.getMessage());\n    data.setState(e.getMessage());\n    return new InvocationException(Status.INTERNAL_SERVER_ERROR, data);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business.error;\n\npublic class ErrorData {\n  private int id;\n\n  private String message;\n\n  public int getId() {\n    return id;\n  }\n\n  public void setId(int id) {\n    this.id = id;\n  }\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business.error;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RestSchema(schemaId = \"error-v2\")\n@RequestMapping(path = \"/business/v2/error\")\npublic class ErrorService {\n  @RequestMapping(path = \"/add\", method = RequestMethod.GET)\n  public int add(int x, int y) {\n    if (x == 99) {\n      throw new NullPointerException(\"un expected NPE test.\");\n    }\n    if (x == 88) {\n      ErrorData data = new ErrorData();\n      data.setId(12);\n      data.setMessage(\"not allowed id.\");\n      throw new InvocationException(Status.FORBIDDEN, data);\n    }\n    if (x == 77) {\n      throw new IllegalStateException(\"77\");\n    }\n    return x + y;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.business.error;\n\npublic class IllegalStateErrorData {\n  private int id;\n\n  private String message;\n\n  private String state;\n\n  public int getId() {\n    return id;\n  }\n\n  public void setId(int id) {\n    this.id = id;\n  }\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public String getState() {\n    return state;\n  }\n\n  public void setState(String state) {\n    this.state = state;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.core.exception.ExceptionConverter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.edge.business.error.CustomExceptionToProducerResponseConverter\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-edge/business-2.0.0/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: edge\n    name: business\n    version: 2.0.0\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8091\n    server:\n      verticle-count: 1\n"
  },
  {
    "path": "demo/demo-edge/consumer/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>consumer</artifactId>\n  <name>Java Chassis::Demo::Edge::Consumer</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.edge.consumer.ConsumerMain</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>model</artifactId>\n      <version>${project.version}</version>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>authentication:${project.version}</name>\n                    <alias>authentication</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/authentication-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>7070</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                  <image>\n                    <name>business-1-0-0:${project.version}</name>\n                    <alias>business-1-0-0</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/business-1-0-0-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                  <image>\n                    <name>business-1-1-0:${project.version}</name>\n                    <alias>business-1-1-0</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/business-1-1-0-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8090:8090</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                  <image>\n                    <name>business-2-0-0:${project.version}</name>\n                    <alias>business-2-0-0</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/business-2-0-0-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>Register microservice instance success</log>\n                        <tcp>\n                          <ports>\n                            <port>8091</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8091:8091</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                  <image>\n                    <name>edge-service:${project.version}</name>\n                    <alias>edge-service</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/edge-service-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>Register microservice instance success</log>\n                        <!--\n                            the log waiting of the plugin has a bug and fails frequently\n                            refer to https://github.com/fabric8io/docker-maven-plugin/issues/767\n                            this http checking is used as a temporary solution\n                        -->\n                        <tcp>\n                          <ports>\n                            <port>18090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>18090:18090</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.consumer;\n\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.demo.edge.model.AppClientDataRsp;\nimport org.apache.servicecomb.demo.edge.model.ChannelRequestBase;\nimport org.apache.servicecomb.demo.edge.model.DependTypeA;\nimport org.apache.servicecomb.demo.edge.model.DependTypeB;\nimport org.apache.servicecomb.demo.edge.model.RecursiveSelfType;\nimport org.apache.servicecomb.demo.edge.model.ResultWithInstance;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.util.Assert;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.HttpClientErrorException;\nimport org.springframework.web.client.HttpServerErrorException;\nimport org.springframework.web.client.RestOperations;\n\npublic class Consumer {\n  RestOperations template = RestTemplateBuilder.create();\n\n  ChannelRequestBase request = new ChannelRequestBase();\n\n  String edgePrefix;\n\n  List<ResultWithInstance> addV1Result = new ArrayList<>();\n\n  List<ResultWithInstance> decV1Result = new ArrayList<>();\n\n  List<ResultWithInstance> addV2Result = new ArrayList<>();\n\n  List<ResultWithInstance> decV2Result = new ArrayList<>();\n\n  DiscoveryManager discoveryManager = BeanUtils.getBean(DiscoveryManager.class);\n\n  Environment environment = BeanUtils.getBean(Environment.class);\n\n  public Consumer() {\n    request.setDeviceId(\"2a5cc42ff60006ac\");\n    request.setServiceToken(\n        \"c2VydmliZVRva2VuPTAwMjAwMDg2MDAwMDAwMDAwODMyYzYzamV1ZnV1cWdpYXgmRGV2aWNIVHIw\"\n            + \"ZT0wJkRLdmljZUIEPTg2MzgoMDAyMDA0NDcwMiZhcHBJRD1jb20uaHVhd2VpLndhbGxldA\");\n    request.setPhoneType(\"VTR-AL00\");\n    request.setUserId(\"20086000000000832\");\n    request.setCmdId(\"5\");\n    request.setNet(\"1\");\n    request.setUserGrant(\"000\");\n    request.setSysVer(\"EMUI5.1\");\n    request.setTs(\"1497356427334\");\n    request.setChannelId(\"3\");\n    request.setLocation(null);\n    request.setCmdVer(\"2.0\");\n    request.setLanguage(\"zh_CN\");\n  }\n\n  public void run(String prefix) {\n    prepareEdge(prefix);\n\n    testRecursiveSelf();\n    testDependType();\n    testDownload();\n    testDownloadBigFile();\n    testErrorCode();\n\n    invoke(\"/v1/add\", 2, 1, addV1Result);\n    invoke(\"/v1/add\", 3, 1, addV1Result);\n    invoke(\"/v1/add\", 4, 1, addV1Result);\n    invoke(\"/v1/add\", 5, 1, addV1Result);\n\n    invoke(\"/v1/dec\", 2, 1, decV1Result);\n    invoke(\"/v1/dec\", 3, 1, decV1Result);\n\n    invoke(\"/v2/add\", 2, 1, addV2Result);\n    invoke(\"/v2/add\", 3, 1, addV2Result);\n\n    invoke(\"/v2/dec\", 2, 1, decV2Result);\n    invoke(\"/v2/dec\", 3, 1, decV2Result);\n\n    printResults(\"v1/add\", addV1Result);\n    printResults(\"v1/dec\", decV1Result);\n    printResults(\"v2/add\", addV2Result);\n    printResults(\"v2/dec\", decV2Result);\n\n    checkResult(\"v1/add\", addV1Result, \"1.0.0\", \"1.1.0\");\n    checkResult(\"v1/dec\", decV1Result, \"1.1.0\");\n    checkResult(\"v2/add\", addV2Result, \"2.0.0\");\n    checkResult(\"v2/dec\", decV2Result, \"2.0.0\");\n  }\n\n  public void testEncrypt() {\n    prepareEdge(\"encryptApi\");\n    String url = edgePrefix + \"/v2/encrypt\";\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.MULTIPART_FORM_DATA);\n\n    MultiValueMap<String, String> form = new LinkedMultiValueMap<>();\n    form.add(\"name\", \"userName\");\n    form.add(\"age\", \"10\");\n    form.add(\"serviceToken\", \"serviceTokenTest\");\n    form.add(\"hcrId\", \"hcrIdTest\");\n    form.add(\"body\", \"bodyKey-hcrIdTest-{\\\"body1\\\":\\\"b1\\\",\\\"body2\\\":\\\"b2\\\",\\\"body3\\\":\\\"b3\\\"}\");\n\n    HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(form, headers);\n\n    @SuppressWarnings(\"unchecked\")\n    Map<String, Object> result = (Map<String, Object>) template.postForObject(url, entity, Map.class);\n    Assert.isTrue(result.containsKey(\"signature\"), \"must exist signature\");\n    result.remove(\"signature\");\n\n    String expected = \"{name=userName, age=10, userId=serviceTokenTest-userId, body1=b1, body2=b2, body3=b3}\";\n    Assert.isTrue(expected.equalsIgnoreCase(result.toString()),\n        String.format(\"expected: %s\\nreal    : %s\", expected, result));\n  }\n\n  protected void testRecursiveSelf() {\n    String url = edgePrefix + \"/v2/recursiveSelf\";\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_JSON);\n\n    RecursiveSelfType recursiveSelfType = new RecursiveSelfType();\n    recursiveSelfType.setField(new RecursiveSelfType());\n    recursiveSelfType.getField().setValue(10);\n\n    HttpEntity<RecursiveSelfType> entity = new HttpEntity<>(recursiveSelfType, headers);\n\n    RecursiveSelfType response = template.postForObject(url, entity, RecursiveSelfType.class);\n    Assert.isTrue(response.getValue() == 0, \"default must be 0\");\n    Assert.isTrue(response.getField().getValue() == 10, \"must be 10\");\n    Assert.isNull(response.getField().getField(), \"must be null\");\n  }\n\n  @SuppressWarnings({\"rawtypes\"})\n  protected void testErrorCode() {\n    String url = edgePrefix + \"/v2/error/add\";\n\n    int response = template.getForObject(url + \"?x=2&y=3\", Integer.class);\n    Assert.isTrue(response == 5, \"not get 5.\");\n\n    try {\n      Map raw = template.getForObject(url + \"?x=99&y=3\", Map.class);\n    } catch (HttpServerErrorException e) {\n      Assert.isTrue(e.getStatusCode().value() == 500, \"x99\");\n      Assert.isTrue(e.getResponseBodyAsString().contains(\"un expected NPE test.\"), \"x99\");\n    }\n\n    try {\n      template.getForObject(url + \"?x=88&y=3\", Map.class);\n      Assert.isTrue(false, \"x88\");\n    } catch (HttpClientErrorException e) {\n      Assert.isTrue(e.getStatusCode().value() == 403, \"x88\");\n      Assert.isTrue(e.getResponseBodyAsString().equals(\"{\\\"id\\\":12,\\\"message\\\":\\\"not allowed id.\\\"}\"), \"x88\");\n    }\n    try {\n      template.getForObject(url + \"?x=77&y=3\", Map.class);\n      Assert.isTrue(false, \"x77\");\n    } catch (HttpServerErrorException e) {\n      Assert.isTrue(e.getStatusCode().value() == 500, \"x77\");\n      Assert.isTrue(e.getResponseBodyAsString().equals(\"{\\\"id\\\":500,\\\"message\\\":\\\"77\\\",\\\"state\\\":\\\"77\\\"}\"), \"x77\");\n    }\n  }\n\n  protected void testDependType() {\n    String url = edgePrefix + \"/v2/dependType\";\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_JSON);\n\n    DependTypeA dependTypeA = new DependTypeA();\n    dependTypeA.setB(new DependTypeB());\n    dependTypeA.getB().setValue(10);\n\n    HttpEntity<DependTypeA> entity = new HttpEntity<>(dependTypeA, headers);\n\n    DependTypeA response = template.postForObject(url, entity, DependTypeA.class);\n    Assert.isTrue(response.getB().getValue() == 10, \"must be 10\");\n  }\n\n  protected void testDownloadBigFile() {\n    String url = edgePrefix + \"/v2/bigFile\";\n    AtomicInteger size = new AtomicInteger();\n\n    template.execute(url, HttpMethod.GET, req -> {\n    }, resp -> {\n      byte[] buf = new byte[1 * 1024 * 1024];\n      try (InputStream is = resp.getBody()) {\n        for (; ; ) {\n          int len = is.read(buf);\n          if (len == -1) {\n            break;\n          }\n\n          size.addAndGet(len);\n        }\n      }\n      return null;\n    });\n    Assert.isTrue(size.get() == 10 * 1024 * 1024, \"size is : \" + size.get() + \" not 10 * 1024 * 1024\");\n    System.out.println(\"test download bigFile finished\");\n  }\n\n  protected void testDownload() {\n    String url = edgePrefix + \"/v2/download\";\n    String content = template.getForObject(url, String.class);\n    Assert.isTrue(\"download\".equals(content), \"content is : \" + content + \" not download\");\n    System.out.println(\"test download finished\");\n  }\n\n  private void checkResult(String name, List<ResultWithInstance> results, String... expectedVersions) {\n    Set<String> versions = new HashSet<>();\n    Set<String> remained = new HashSet<>(Arrays.asList(expectedVersions));\n    for (ResultWithInstance result : results) {\n      versions.add(result.getVersion());\n      remained.remove(result.getVersion());\n    }\n\n    Assert.isTrue(remained.isEmpty(),\n        String.format(\"%s expectedVersions %s, real versions %s.\",\n            name,\n            Arrays.deepToString(expectedVersions),\n            versions));\n  }\n\n  protected void printResults(String name, List<ResultWithInstance> results) {\n    System.out.println(name);\n    for (ResultWithInstance result : results) {\n      System.out.println(result);\n    }\n    System.out.println(\"\");\n  }\n\n  protected void invoke(String appendUrl, int x, int y, List<ResultWithInstance> results) {\n    String url = edgePrefix + appendUrl + String.format(\"?x=%d&y=%d\", x, y);\n    ResultWithInstance result = template.getForObject(url, ResultWithInstance.class);\n    results.add(result);\n  }\n\n  private URIEndpointObject prepareEdge(String prefix) {\n    DiscoveryInstance instance = discoveryManager.findServiceInstances(\n            BootStrapProperties.readApplication(environment), \"edge\")\n        .stream()\n        .findFirst()\n        .get();\n    URIEndpointObject edgeAddress = new URIEndpointObject(instance.getEndpoints().get(0));\n    edgePrefix = String.format(\"http://%s:%d/%s/business\", edgeAddress.getHostOrIp(), edgeAddress.getPort(), prefix);\n    return edgeAddress;\n  }\n\n  protected void invokeBusiness(String urlPrefix, ChannelRequestBase request) {\n    List<String> result = new ArrayList<>(6);\n    for (int i = 0; i < 6; i++) {\n      String url = urlPrefix + \"/channel/news/subscribe\";\n\n      HttpHeaders headers = new HttpHeaders();\n      headers.setContentType(MediaType.APPLICATION_JSON);\n\n      HttpEntity<ChannelRequestBase> entity = new HttpEntity<>(request, headers);\n\n      ResponseEntity<AppClientDataRsp> response = template.postForEntity(url, entity, AppClientDataRsp.class);\n      result.add(response.getBody().getRsp());\n    }\n    Assert.isTrue(result.contains(\"result from 2.0.0\"), \"invokeBusiness not balance\");\n    Assert.isTrue(result.contains(\"result from 1.1.0\"), \"invokeBusiness not balance\");\n    Assert.isTrue(result.contains(\"result from 1.0.0\"), \"invokeBusiness not balance\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/ConsumerMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.consumer;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.edge.model.ChannelRequestBase;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsumerMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(ConsumerMain.class).web(WebApplicationType.NONE).run(args);\n\n    runTest();\n  }\n\n  public static void runTest() throws Exception {\n    new Consumer().testEncrypt();\n    new Consumer().invokeBusiness(\"cse://business/business/v1\", new ChannelRequestBase());\n\n    System.out.println(\"Running api dispatcher.\");\n    new Consumer().run(\"api\");\n    System.out.println(\"Running rest dispatcher.\");\n    new Consumer().run(\"rest\");\n    System.out.println(\"Running url dispatcher.\");\n    new Consumer().run(\"url\");\n// Common Http Dispatcher do not have OperationMeta, can not use router.\n//    System.out.println(\"Running http dispatcher.\");\n//    new Consumer().run(\"http\");\n\n    System.out.println(\"All test case finished.\");\n\n    runCategorizedTest();\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      throw new IllegalStateException(\"tests failed\");\n    }\n  }\n\n  private static void runCategorizedTest() throws Exception {\n    CategorizedTestCaseRunner\n        .runCategorizedTestCase(\"edge\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/EdgeServiceGovernanceTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.consumer;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.HttpClientErrorException;\nimport org.springframework.web.client.HttpServerErrorException;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class EdgeServiceGovernanceTest implements CategorizedTestCase {\n  RestOperations template = RestTemplateBuilder.create();\n\n  String edgePrefix;\n\n  @Autowired\n  Environment environment;\n\n  @Autowired\n  DiscoveryManager discoveryManager;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    prepareEdge(\"url\");\n    // edge service do not support retry\n//    testEdgeServiceRetry();\n    testEdgeServiceInstanceBulkhead();\n    testEdgeServiceInstanceIsolation(); // may isolate instance for 5 seconds.\n    Thread.sleep(6000); // ensure isolation is open for new requests\n  }\n\n  private void testEdgeServiceInstanceBulkhead() throws Exception {\n    String url = edgePrefix + \"/business/v2/testEdgeServiceInstanceBulkhead\";\n\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed503 = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              String result = template.getForObject(url + \"?name={1}\", String.class, \"hello\");\n              if (!\"hello\".equals(result)) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (!(e instanceof HttpServerErrorException)) {\n                notExpectedFailed.set(true);\n              } else {\n                if (((HttpServerErrorException) e).getStatusCode().value() == 503) {\n                  expectedFailed503.set(true);\n                }\n              }\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(true, expectedFailed503.get());\n    TestMgr.check(false, notExpectedFailed.get());\n  }\n\n  private void testEdgeServiceInstanceIsolation() throws Exception {\n    String url = edgePrefix + \"/business/v2/testEdgeServiceInstanceIsolation\";\n\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed404 = new AtomicBoolean(false);\n    AtomicBoolean expectedFailed502 = new AtomicBoolean(false);\n    AtomicBoolean expectedFailed503 = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              String result = template.getForObject(url + \"?name={1}\", String.class, \"hello\");\n              if (!\"hello\".equals(result)) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (e instanceof HttpClientErrorException) {\n                // isolate 2.0.0 and other instance will give 404\n                if (((HttpClientErrorException) e).getStatusCode().value() == 404) {\n                  expectedFailed404.set(true);\n                } else {\n                  notExpectedFailed.set(true);\n                }\n              } else if (e instanceof HttpServerErrorException) {\n                // instance isolated and return 503\n                if (((HttpServerErrorException) e).getStatusCode().value() == 503) {\n                  expectedFailed503.set(true);\n                }\n                // provider throw 502 exception to trigger instance isolation\n                if (((HttpServerErrorException) e).getStatusCode().value() == 502) {\n                  expectedFailed502.set(true);\n                }\n              } else {\n                notExpectedFailed.set(true);\n              }\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(true, expectedFailed404.get());\n    TestMgr.check(true, expectedFailed502.get());\n    TestMgr.check(true, expectedFailed503.get());\n    TestMgr.check(false, notExpectedFailed.get());\n  }\n\n  private URIEndpointObject prepareEdge(String prefix) {\n    DiscoveryInstance microserviceInstance = discoveryManager.findServiceInstances(\n            BootStrapProperties.readApplication(environment), \"edge\")\n        .stream()\n        .findFirst()\n        .get();\n    URIEndpointObject edgeAddress = new URIEndpointObject(microserviceInstance.getEndpoints().get(0));\n    edgePrefix = String.format(\"http://%s:%d/%s\", edgeAddress.getHostOrIp(), edgeAddress.getPort(), prefix);\n    return edgeAddress;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-edge/consumer/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: edge\n    name: consumer\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    client.http2.useAlpnEnabled: false\n  handler:\n    chain:\n      Consumer:\n        default: loadbalance\n"
  },
  {
    "path": "demo/demo-edge/consumer/src/test/java/org/apache/servicecomb/demo/edge/consumer/EdgeDemoIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.consumer;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = ConsumerMain.class)\npublic class EdgeDemoIT {\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    ConsumerMain.runTest();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>edge-service</artifactId>\n  <name>Java Chassis::Demo::Edge::Service</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.edge.EdgeMain</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/EdgeMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class EdgeMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(EdgeMain.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/authentication/encrypt/Hcr.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.authentication.encrypt;\n\npublic class Hcr {\n  private String bodyKey;\n\n  private String signatureKey;\n\n  public String getBodyKey() {\n    return bodyKey;\n  }\n\n  public void setBodyKey(String bodyKey) {\n    this.bodyKey = bodyKey;\n  }\n\n  public String getSignatureKey() {\n    return signatureKey;\n  }\n\n  public void setSignatureKey(String signatureKey) {\n    this.signatureKey = signatureKey;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.SimpleType;\n\npublic class CustomResponseMetaMapper implements ResponseMetaMapper {\n  private static final Map<Integer, JavaType> CODES = new HashMap<>(1);\n\n  static {\n    CODES.put(500, SimpleType.constructUnsafe(IllegalStateErrorData.class));\n  }\n\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n\n  @Override\n  public Map<Integer, JavaType> getMapper() {\n    return CODES;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/EdgeConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service;\n\npublic interface EdgeConst {\n  String ENCRYPT_CONTEXT = \"encryptContext\";\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/EdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestProducerInvocationFlow;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.edge.core.AbstractEdgeDispatcher;\nimport org.apache.servicecomb.edge.core.EdgeInvocationCreator;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;\n\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class EdgeDispatcher extends AbstractEdgeDispatcher {\n  @Override\n  public int getOrder() {\n    return 10000;\n  }\n\n  @Override\n  public void init(Router router) {\n    String regex = \"/api/([^\\\\\\\\/]+)/([^\\\\\\\\/]+)/(.*)\";\n    // cookies handler are enabled by default start from 3.8.3\n    router.routeWithRegex(regex).handler(createBodyHandler());\n    router.routeWithRegex(regex).failureHandler(this::onFailure).handler(this::onRequest);\n  }\n\n  protected void onRequest(RoutingContext context) {\n    Map<String, String> pathParams = context.pathParams();\n    String microserviceName = pathParams.get(\"param0\");\n    String path = context.request().path().substring(4);\n\n    requestByFilter(context, microserviceName, path);\n  }\n\n  protected void requestByFilter(RoutingContext context, String microserviceName, String path) {\n    HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context);\n    HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response());\n    InvocationCreator creator = new EdgeInvocationCreator(context, requestEx, responseEx,\n        microserviceName, path);\n    new RestProducerInvocationFlow(creator, requestEx, responseEx)\n        .run();\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service;\n\npublic class IllegalStateErrorData {\n  private int id;\n\n  private String message;\n\n  private String state;\n\n  public int getId() {\n    return id;\n  }\n\n  public void setId(int id) {\n    this.id = id;\n  }\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public String getState() {\n    return state;\n  }\n\n  public void setState(String state) {\n    this.state = state;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/Encrypt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service.encrypt;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;\n\npublic interface Encrypt {\n  CompletableFuture<String> queryUserId(String serviceToken);\n\n  CompletableFuture<Hcr> queryHcr(String hcrId);\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/EncryptContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.service.encrypt;\n\nimport org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;\n\npublic class EncryptContext {\n  private Hcr hcr;\n\n  private String userId;\n\n  public EncryptContext(Hcr hcr, String userId) {\n    this.hcr = hcr;\n    this.userId = userId;\n  }\n\n  public Hcr getHcr() {\n    return hcr;\n  }\n\n  public void setHcr(Hcr hcr) {\n    this.hcr = hcr;\n  }\n\n  public String getUserId() {\n    return userId;\n  }\n\n  public void setUserId(String userId) {\n    this.userId = userId;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/EncryptEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service.encrypt;\n\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.common.rest.RestProducerInvocationFlow;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;\nimport org.apache.servicecomb.demo.edge.service.EdgeConst;\nimport org.apache.servicecomb.edge.core.AbstractEdgeDispatcher;\nimport org.apache.servicecomb.edge.core.EdgeInvocationCreator;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class EncryptEdgeDispatcher extends AbstractEdgeDispatcher {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EncryptEdgeDispatcher.class);\n\n  private Encrypt encrypt = Invoker.createProxy(\"auth\", \"encrypt\", Encrypt.class);\n\n  private String prefix = \"encryptApi\";\n\n  @Override\n  public int getOrder() {\n    return 10000;\n  }\n\n  @Override\n  public void init(Router router) {\n    String regex = \"/\" + prefix + \"/([^\\\\\\\\/]+)/(.*)\";\n    // cookies handler are enabled by default start from 3.8.3\n    router.routeWithRegex(regex).handler(createBodyHandler());\n    router.routeWithRegex(regex).failureHandler(this::onFailure).handler(this::onRequest);\n  }\n\n  protected void onRequest(RoutingContext context) {\n    HttpServerRequest httpServerRequest = context.request();\n\n    // queryUserId always success\n    CompletableFuture<String> userIdFuture = queryUserId(httpServerRequest);\n    queryHcr(httpServerRequest).thenCombine(userIdFuture, (hcr, userId) -> {\n      // hcr and userId all success\n      routeToBackend(context, hcr, userId);\n      return null;\n    }).whenComplete((v, e) -> {\n      // failed to query hcr\n      if (e != null) {\n        context.response().end(\"failed to query hcr: \" + e.getMessage());\n        return;\n      }\n    });\n  }\n\n  private CompletableFuture<String> queryUserId(HttpServerRequest httpServerRequest) {\n    String serviceToken = httpServerRequest.getParam(\"serviceToken\");\n    if (serviceToken == null) {\n      // no need to query userId\n      return CompletableFuture.completedFuture(null);\n    }\n\n    CompletableFuture<String> future = new CompletableFuture<>();\n    encrypt.queryUserId(serviceToken).whenComplete((userId, e) -> {\n      if (e != null) {\n        // treat as success, just userId is null\n        LOGGER.error(\"Failed to query userId, serviceToken={}.\", serviceToken, e);\n      }\n\n      future.complete(userId);\n    });\n\n    return future;\n  }\n\n  private CompletableFuture<Hcr> queryHcr(HttpServerRequest httpServerRequest) {\n    String hcrId = httpServerRequest.getParam(\"hcrId\");\n    return encrypt.queryHcr(hcrId);\n  }\n\n  private void routeToBackend(RoutingContext context, Hcr hcr, String userId) {\n    Map<String, String> pathParams = context.pathParams();\n    String microserviceName = pathParams.get(\"param0\");\n    String path = context.request().path().substring(prefix.length() + 1);\n\n    requestByFilter(context, microserviceName, path,\n        new EncryptContext(hcr, userId));\n  }\n\n  protected void requestByFilter(RoutingContext context, String microserviceName, String path\n      , EncryptContext encryptContext) {\n    HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context);\n    HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response());\n    InvocationCreator creator = new EdgeInvocationCreator(context, requestEx, responseEx,\n        microserviceName, path) {\n      @Override\n      public CompletableFuture<Invocation> createAsync() {\n        CompletableFuture<Invocation> result = super.createAsync();\n        return result.whenComplete((invocation, throwable)\n            -> {\n          if (throwable == null) {\n            invocation.getHandlerContext().put(EdgeConst.ENCRYPT_CONTEXT, encryptContext);\n          }\n        });\n      }\n    };\n    new RestProducerInvocationFlow(creator, requestEx, responseEx)\n        .run();\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/filter/DecodeBodyFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.service.encrypt.filter;\n\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;\nimport org.apache.servicecomb.demo.edge.service.EdgeConst;\nimport org.apache.servicecomb.demo.edge.service.encrypt.EncryptContext;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.stereotype.Component;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n@Component\npublic class DecodeBodyFilter extends AbstractFilter implements EdgeFilter {\n  private JavaType bodyType = TypeFactory.defaultInstance().constructMapType(Map.class, String.class, String[].class);\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER - 1790;\n  }\n\n  @Override\n  public String getName() {\n    return \"test-edge-decode-body\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    EncryptContext encryptContext = (EncryptContext) invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT);\n    if (encryptContext == null) {\n      return nextNode.onFilter(invocation);\n    }\n    Hcr hcr = encryptContext.getHcr();\n\n    String encodedBody = invocation.getRequestEx().getParameter(\"body\");\n    if (encodedBody == null) {\n      return nextNode.onFilter(invocation);\n    }\n\n    encodedBody = encodedBody.substring(hcr.getBodyKey().length());\n\n    try {\n      Map<String, String[]> decodedBody = RestObjectMapperFactory.getRestObjectMapper()\n          .readValue(encodedBody, bodyType);\n      invocation.getRequestEx().getParameterMap().putAll(decodedBody);\n    } catch (Throwable e) {\n      // should be a meaning exception response\n      return CompletableFuture.failedFuture(e);\n    }\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/filter/EdgeSignatureRequestFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.service.encrypt.filter;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;\nimport org.apache.servicecomb.demo.edge.service.EdgeConst;\nimport org.apache.servicecomb.demo.edge.service.encrypt.EncryptContext;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\nimport com.google.common.hash.Hasher;\nimport com.google.common.hash.Hashing;\n\n@Component\npublic class EdgeSignatureRequestFilter extends AbstractFilter implements EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EdgeSignatureRequestFilter.class);\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER - 1800;\n  }\n\n  @Override\n  public String getName() {\n    return \"test-edge-signature-request\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    EncryptContext encryptContext = (EncryptContext) invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT);\n    if (encryptContext == null) {\n      return nextNode.onFilter(invocation);\n    }\n    Hcr hcr = encryptContext.getHcr();\n\n    // signature for query and form\n    List<String> names = Collections.list(invocation.getRequestEx().getParameterNames());\n    names.sort(Comparator.naturalOrder());\n\n    Hasher hasher = Hashing.sha256().newHasher();\n    hasher.putString(hcr.getSignatureKey(), StandardCharsets.UTF_8);\n    for (String name : names) {\n      hasher.putString(name, StandardCharsets.UTF_8);\n      hasher.putString(invocation.getRequestEx().getParameter(name), StandardCharsets.UTF_8);\n    }\n    LOGGER.info(\"afterReceiveRequest signature: {}\", hasher.hash());\n\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/filter/EdgeSignatureResponseFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.service.encrypt.filter;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.demo.edge.authentication.encrypt.Hcr;\nimport org.apache.servicecomb.demo.edge.service.EdgeConst;\nimport org.apache.servicecomb.demo.edge.service.encrypt.EncryptContext;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\nimport com.google.common.hash.Hasher;\nimport com.google.common.hash.Hashing;\n\nimport io.vertx.core.buffer.Buffer;\n\n@Component\npublic class EdgeSignatureResponseFilter extends AbstractFilter implements EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EdgeSignatureResponseFilter.class);\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1991;\n  }\n\n  @Override\n  public String getName() {\n    return \"test-edge-signature-response\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    return nextNode.onFilter(invocation).whenComplete((response, throwable) -> {\n      if (throwable != null) {\n        return;\n      }\n      EncryptContext encryptContext = (EncryptContext) invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT);\n      if (encryptContext == null) {\n        return;\n      }\n      Hcr hcr = encryptContext.getHcr();\n\n      // bad practice: it's better to set signature in response header\n      Buffer bodyBuffer = response.getResult();\n      String body = bodyBuffer.toString();\n      if (body.endsWith(\"}\")) {\n        Hasher hasher = Hashing.sha256().newHasher();\n        hasher.putString(hcr.getSignatureKey(), StandardCharsets.UTF_8);\n        hasher.putString(body, StandardCharsets.UTF_8);\n        String signature = hasher.hash().toString();\n        LOGGER.info(\"beforeSendResponse signature: {}\", signature);\n\n        body = body.substring(0, body.length() - 1) + \",\\\"signature\\\":\\\"\" + signature + \"\\\"}\";\n        response.setResult(Buffer.buffer(body));\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/encrypt/filter/UserIdFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.service.encrypt.filter;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.demo.edge.service.EdgeConst;\nimport org.apache.servicecomb.demo.edge.service.encrypt.EncryptContext;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class UserIdFilter extends AbstractFilter implements EdgeFilter {\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER - 1790;\n  }\n\n  @Override\n  public String getName() {\n    return \"test-edge-user-id\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    EncryptContext encryptContext = (EncryptContext) invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT);\n    if (encryptContext == null) {\n      return nextNode.onFilter(invocation);\n    }\n\n    String userId = encryptContext.getUserId();\n    if (userId != null) {\n      invocation.getRequestEx().setParameter(\"userId\", userId);\n    }\n\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/handler/Auth.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service.handler;\n\nimport java.util.concurrent.CompletableFuture;\n\npublic interface Auth {\n  CompletableFuture<Boolean> auth(String info);\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/handler/AuthHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.service.handler;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.demo.edge.service.EdgeConst;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\nimport jakarta.ws.rs.core.Response.Status;\n\n@Component\npublic class AuthHandler extends AbstractFilter implements EdgeFilter {\n  private static Logger LOGGER = LoggerFactory.getLogger(AuthHandler.class);\n\n  private static Auth auth;\n\n  static {\n    auth = Invoker.createProxy(\"auth\", \"auth\", Auth.class);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER - 1980;\n  }\n\n  @Override\n  public boolean enabledForMicroservice(String application, String serviceName) {\n    // Do not enable for service auth and not enable for internal management access(myself)\n    return !\"auth\".equals(serviceName) && !\"edge\".equals(serviceName);\n  }\n\n  @Override\n  public String getName() {\n    return \"test-auth\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT) != null) {\n      return nextNode.onFilter(invocation);\n    }\n\n    return auth.auth(\"\").thenCompose(result -> doHandle(invocation, nextNode, result));\n  }\n\n  protected CompletableFuture<Response> doHandle(Invocation invocation, FilterNode nextNode, Boolean authSucc) {\n    if (!authSucc) {\n      return CompletableFuture.failedFuture(new InvocationException(Status.UNAUTHORIZED, (Object) \"auth failed\"));\n    }\n\n    LOGGER.debug(\"auth success.\");\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.edge.service.CustomResponseMetaMapper\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.edge.service.EdgeDispatcher\norg.apache.servicecomb.demo.edge.service.encrypt.EncryptEdgeDispatcher\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-edge/edge-service/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: edge\n    name: edge\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  edge:\n    filter:\n      addHeader:\n        enabled: true\n        allowedHeaders: xxx\n  rest:\n    address: 0.0.0.0:18090\n    server:\n      # for test case run in one core machine\n      verticle-count: 1\n    client:\n      verticle-count: 1\n      http2.useAlpnEnabled: false\n  handler:\n    chain:\n      Consumer:\n        default: auth,loadbalance,instance-isolation-consumer,instance-bulkhead-consumer\n        service:\n          auth: loadbalance,instance-isolation-consumer,instance-bulkhead-consumer\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: true\n          prefix: rest\n          withVersion: true\n          prefixSegmentCount: 1\n        url:\n          enabled: true\n          mappings:\n            businessV1:\n              prefixSegmentCount: 1\n              path: \"/url/business/v1/.*\"\n              microserviceName: business\n            businessV2:\n              prefixSegmentCount: 1\n              path: \"/url/business/v2/.*\"\n              microserviceName: business\n        http:\n          enabled: true\n          mappings:\n            businessV2:\n              prefixSegmentCount: 1\n              path: \"/http/business/v2/.*\"\n              microserviceName: business\n            businessV1:\n              prefixSegmentCount: 1\n              path: \"/http/business/v1/add.*\"\n              microserviceName: business\n            businessV1_1:\n              prefixSegmentCount: 1\n              path: \"/http/business/v1/dec.*\"\n              microserviceName: business\n\n  # 服务治理配置\n  matchGroup:\n    testEdgeServiceRetry: |\n      matches:\n        - apiPath:\n            exact: \"/business/v2/testEdgeServiceRetry\"\n    testEdgeServiceInstanceIsolation: |\n      matches:\n        - apiPath:\n            exact: \"/business/v2/testEdgeServiceInstanceIsolation\"\n    testEdgeServiceInstanceBulkhead: |\n      matches:\n        - apiPath:\n            exact: \"/business/v2/testEdgeServiceInstanceBulkhead\"\n  # retry not supported now\n  #  retry:\n  #    testEdgeServiceRetry: |\n  #      maxAttempts: 2\n  #      retryOnSame: 0\n  instanceIsolation:\n    testEdgeServiceInstanceIsolation: |\n      minimumNumberOfCalls: 10\n      slidingWindowSize: 20\n      slidingWindowType: COUNT_BASED\n      failureRateThreshold: 50\n      slowCallRateThreshold: 100\n      slowCallDurationThreshold: 3000\n      waitDurationInOpenState: 3000\n      permittedNumberOfCallsInHalfOpenState: 10\n  instanceBulkhead:\n    testEdgeServiceInstanceBulkhead: |\n      maxConcurrentCalls: 1\n      maxWaitDuration: 1\n\n  # enable router for edge service\n  router:\n    type: router\n  routeRule:\n    business: |\n      - precedence: 2\n        match:\n          apiPath:\n            prefix: \"/business/v2\"\n        route:\n          - weight: 100\n            tags:\n              version: 2.0.0\n      - precedence: 1\n        match:\n          apiPath:\n            prefix: \"/business/v1/dec\"\n        route:\n          - weight: 50\n            tags:\n              version: 1.1.0\n          - weight: 50\n            tags:\n              version: 2.0.0\n"
  },
  {
    "path": "demo/demo-edge/model/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>model</artifactId>\n  <name>Java Chassis::Demo::Edge::Model</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/AppClientDataRsp.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.model;\n\npublic class AppClientDataRsp {\n  private String rsp;\n\n  public String getRsp() {\n    return rsp;\n  }\n\n  public void setRsp(String rsp) {\n    this.rsp = rsp;\n  }\n\n  @Override\n  public String toString() {\n    return \"AppClientDataRsp [rsp=\" + rsp + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/ChannelRequestBase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.model;\n\npublic class ChannelRequestBase {\n  private String deviceId;\n\n  private String serviceToken;\n\n  private String phoneType;\n\n  private String userId;\n\n  private String cmdId;\n\n  private String net;\n\n  private String userGrant;\n\n  private String sysVer;\n\n  private String ts;\n\n  private String channelId;\n\n  private String location;\n\n  private String cmdVer;\n\n  private String version;\n\n  private String language;\n\n  public String getDeviceId() {\n    return deviceId;\n  }\n\n  public void setDeviceId(String deviceId) {\n    this.deviceId = deviceId;\n  }\n\n  public String getServiceToken() {\n    return serviceToken;\n  }\n\n  public void setServiceToken(String serviceToken) {\n    this.serviceToken = serviceToken;\n  }\n\n  public String getPhoneType() {\n    return phoneType;\n  }\n\n  public void setPhoneType(String phoneType) {\n    this.phoneType = phoneType;\n  }\n\n  public String getUserId() {\n    return userId;\n  }\n\n  public void setUserId(String userId) {\n    this.userId = userId;\n  }\n\n  public String getCmdId() {\n    return cmdId;\n  }\n\n  public void setCmdId(String cmdId) {\n    this.cmdId = cmdId;\n  }\n\n  public String getNet() {\n    return net;\n  }\n\n  public void setNet(String net) {\n    this.net = net;\n  }\n\n  public String getUserGrant() {\n    return userGrant;\n  }\n\n  public void setUserGrant(String userGrant) {\n    this.userGrant = userGrant;\n  }\n\n  public String getSysVer() {\n    return sysVer;\n  }\n\n  public void setSysVer(String sysVer) {\n    this.sysVer = sysVer;\n  }\n\n  public String getTs() {\n    return ts;\n  }\n\n  public void setTs(String ts) {\n    this.ts = ts;\n  }\n\n  public String getChannelId() {\n    return channelId;\n  }\n\n  public void setChannelId(String channelId) {\n    this.channelId = channelId;\n  }\n\n  public String getLocation() {\n    return location;\n  }\n\n  public void setLocation(String location) {\n    this.location = location;\n  }\n\n  public String getCmdVer() {\n    return cmdVer;\n  }\n\n  public void setCmdVer(String cmdVer) {\n    this.cmdVer = cmdVer;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public String getLanguage() {\n    return language;\n  }\n\n  public void setLanguage(String language) {\n    this.language = language;\n  }\n\n  @Override\n  public String toString() {\n    return \"ChannelRequestBase [deviceId=\" + deviceId + \", serviceToken=\" + serviceToken + \", phoneType=\" + phoneType\n        + \", userId=\" + userId + \", cmdId=\" + cmdId + \", net=\" + net + \", userGrant=\" + userGrant + \", sysVer=\" + sysVer\n        + \", ts=\" + ts + \", channelId=\" + channelId + \", location=\" + location + \", cmdVer=\" + cmdVer + \", version=\"\n        + version + \", language=\" + language + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/DependTypeA.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.model;\n\npublic class DependTypeA {\n  private DependTypeB b;\n\n  public DependTypeB getB() {\n    return b;\n  }\n\n  public void setB(DependTypeB b) {\n    this.b = b;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/DependTypeB.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.model;\n\npublic class DependTypeB {\n  private DependTypeA a;\n\n  private int value;\n\n  public DependTypeA getA() {\n    return a;\n  }\n\n  public void setA(DependTypeA a) {\n    this.a = a;\n  }\n\n  public int getValue() {\n    return value;\n  }\n\n  public void setValue(int value) {\n    this.value = value;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/RecursiveSelfType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.model;\n\npublic class RecursiveSelfType {\n  private RecursiveSelfType field;\n\n  private int value;\n\n  public RecursiveSelfType getField() {\n    return field;\n  }\n\n  public void setField(RecursiveSelfType field) {\n    this.field = field;\n  }\n\n  public int getValue() {\n    return value;\n  }\n\n  public void setValue(int value) {\n    this.value = value;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/ResultWithInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.edge.model;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.springframework.core.env.Environment;\n\npublic class ResultWithInstance {\n  private int result;\n\n  private String serviceId;\n\n  private String instanceId;\n\n  private String version;\n\n  public static ResultWithInstance create(int value, Environment environment) {\n    ResultWithInstance result = new ResultWithInstance();\n    result.setResult(value);\n    result.setVersion(BootStrapProperties.readServiceVersion(environment));\n\n    return result;\n  }\n\n  public int getResult() {\n    return result;\n  }\n\n  public void setResult(int result) {\n    this.result = result;\n  }\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  @Override\n  public String toString() {\n    return \"ResultWithInstance [result=\" + result + \", serviceId=\" + serviceId + \", instanceId=\" + instanceId\n        + \", version=\" + version + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/model/src/main/java/org/apache/servicecomb/demo/edge/model/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.edge.model;\n\npublic class User {\n  private String name;\n\n  private int age;\n\n  private String userId;\n\n  private String body1;\n\n  private String body2;\n\n  private String body3;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n\n  public String getUserId() {\n    return userId;\n  }\n\n  public void setUserId(String userId) {\n    this.userId = userId;\n  }\n\n  public String getBody1() {\n    return body1;\n  }\n\n  public void setBody1(String body1) {\n    this.body1 = body1;\n  }\n\n  public String getBody2() {\n    return body2;\n  }\n\n  public void setBody2(String body2) {\n    this.body2 = body2;\n  }\n\n  public String getBody3() {\n    return body3;\n  }\n\n  public void setBody3(String body3) {\n    this.body3 = body3;\n  }\n}\n"
  },
  {
    "path": "demo/demo-edge/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-edge</artifactId>\n  <name>Java Chassis::Demo::Edge</name>\n  <packaging>pom</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>model</module>\n    <module>edge-service</module>\n    <module>business-1.0.0</module>\n    <module>business-1-1-0</module>\n    <module>business-2.0.0</module>\n    <module>authentication</module>\n    <module>consumer</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "demo/demo-etcd/README.md",
    "content": "# Notice\n\nThis integration tests is designed for Etcd registry and configuration. And extra test cases include:\n\n* Test cases related to SpringMVC annotations that demo-springmvc can not cover.\n"
  },
  {
    "path": "demo/demo-etcd/consumer/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-etcd</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>etcd-consumer</artifactId>\n  <name>Java Chassis::Demo::Etcd::CONSUMER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.protobuf</groupId>\n      <artifactId>protobuf-java</artifactId>\n      <version>3.25.5</version>\n      <scope>runtime</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-etcd</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-etcd</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.ServerWebSocket;\nimport io.vertx.core.http.WebSocket;\n\n@RestSchema(schemaId = \"ClientWebsocketController\")\n@RequestMapping(path = \"/ws\")\npublic class ClientWebsocketController {\n  interface ProviderService {\n    WebSocket websocket();\n  }\n\n  @RpcReference(schemaId = \"WebsocketController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  @PostMapping(\"/websocket\")\n  @Transport(name = CoreConst.WEBSOCKET)\n  public void websocket(ServerWebSocket serverWebsocket) {\n    WebSocket providerWebSocket = providerService.websocket();\n    providerWebSocket.closeHandler(v -> serverWebsocket.close());\n    providerWebSocket.textMessageHandler(m -> {\n      serverWebsocket.writeTextMessage(m);\n    });\n    serverWebsocket.textMessageHandler(m -> {\n      providerWebSocket.writeTextMessage(m);\n    });\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\n@RestSchema(schemaId = \"ConsumerController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerController {\n  @RpcReference(schemaId = \"ProviderController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  // consumer service which delegate the implementation to provider service.\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return providerService.sayHello(name);\n  }\n\n  @GetMapping(\"/getConfig\")\n  public String getConfig(@RequestParam(\"key\") String key) {\n    return providerService.getConfig(key);\n  }\n\n  @PostMapping(path = \"/testContentType\", consumes = MediaType.APPLICATION_JSON_VALUE)\n  @ResponseBody\n  public User testContentType(@RequestBody User user) {\n    return providerService.testContentType(user);\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"ConsumerHeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)\npublic class ConsumerHeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {\n  @RpcReference(microserviceName = \"provider\", schemaId = \"HeaderParamWithListSchema\")\n  private IHeaderParamWithListSchemaSpringMvc provider;\n\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return provider.headerListDefault(headerList);\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return provider.headerListCSV(headerList);\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return provider.headerListMULTI(headerList);\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return provider.headerListSSV(headerList);\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return provider.headerListPIPES(headerList);\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerReactiveStreamController {\n  interface ProviderReactiveStreamController {\n    Publisher<String> sseString();\n\n    Publisher<Model> sseModel();\n  }\n\n  @RpcReference(microserviceName = \"provider\", schemaId = \"ReactiveStreamController\")\n  ProviderReactiveStreamController controller;\n\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  @Transport(name = CoreConst.RESTFUL)\n  public Publisher<String> sseString() {\n    return controller.sseString();\n  }\n\n  @GetMapping(\"/sseModel\")\n  @Transport(name = CoreConst.RESTFUL)\n  public Publisher<Model> sseModel() {\n    return controller.sseModel();\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/EtcdConsumerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class EtcdConsumerApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(EtcdConsumerApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface ProviderService {\n  String sayHello(String name);\n\n  String getConfig(String key);\n\n  User testContentType(User user);\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/java/org/apache/servicecomb/samples/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\npublic class User {\n\n  private Long id;\n\n  private String name;\n\n  public Long getId() {\n    return id;\n  }\n\n  public void setId(Long id) {\n    this.id = id;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-etcd\n    version: 0.0.1\n    name: consumer\n    properties:\n      group: red\n  registry:\n    etcd:\n      connectString: http://127.0.0.1:2379\n  config:\n    etcd:\n      connectString: http://127.0.0.1:2379\n\n  rest:\n    address: 0.0.0.0:9092?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n"
  },
  {
    "path": "demo/demo-etcd/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-etcd/gateway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-etcd</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>etcd-gateway</artifactId>\n  <name>Java Chassis::Demo::Etcd::GATEWAY</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.protobuf</groupId>\n      <artifactId>protobuf-java</artifactId>\n      <version>3.25.5</version>\n      <scope>runtime</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-etcd</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-etcd/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class GatewayApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/gateway/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-etcd\n    version: 0.0.1\n    name: gateway\n  registry:\n    etcd:\n      enabled: true\n      connectString: http://127.0.0.1:2379\n\n  rest:\n    address: 0.0.0.0:9090?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n        websocket:\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/ws/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n"
  },
  {
    "path": "demo/demo-etcd/gateway/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-etcd/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-etcd</artifactId>\n  <name>Java Chassis::Demo::Etcd</name>\n  <packaging>pom</packaging>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>provider</module>\n    <module>consumer</module>\n    <module>gateway</module>\n    <module>test-client</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "demo/demo-etcd/provider/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-etcd</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>etcd-provider</artifactId>\n  <name>Java Chassis::Demo::Etcd::PROVIDER</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.protobuf</groupId>\n      <artifactId>protobuf-java</artifactId>\n      <version>3.25.5</version>\n      <scope>runtime</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-etcd</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-etcd</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.reactivex.rxjava3</groupId>\n      <artifactId>rxjava</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/EtcdProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class EtcdProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(EtcdProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"HeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)\npublic class HeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController implements InitializingBean {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n//    return \"Hello \" + environment.getProperty(\"servicecomb.rest.address\");\n    return \"Hello \" + name;\n  }\n\n  @GetMapping(\"/getConfig\")\n  public String getConfig(@RequestParam(\"key\") String key) {\n    return environment.getProperty(key);\n  }\n\n  @PostMapping(path = \"/testContentType\", consumes = MediaType.APPLICATION_JSON_VALUE)\n  @ResponseBody\n  public User testContentType(@RequestBody User user) {\n    return user;\n  }\n\n  @Override\n  public void afterPropertiesSet() throws Exception {\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.reactivex.rxjava3.core.Flowable;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\n@Transport(name = CoreConst.RESTFUL)\npublic class ReactiveStreamController {\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  public Publisher<String> sseString() {\n    return Flowable.fromArray(\"a\", \"b\", \"c\");\n  }\n\n  @GetMapping(\"/sseModel\")\n  public Publisher<Model> sseModel() {\n    return Flowable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)\n        .map(item -> new Model(\"jack\", item.intValue()));\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\npublic class User {\n\n  private Long id;\n\n  private String name;\n\n  public Long getId() {\n    return id;\n  }\n\n  public void setId(Long id) {\n    this.id = id;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.ServerWebSocket;\n\n@RestSchema(schemaId = \"WebsocketController\")\n@RequestMapping(path = \"/ws\")\npublic class WebsocketController {\n  @PostMapping(\"/websocket\")\n  @Transport(name = CoreConst.WEBSOCKET)\n  public void websocket(ServerWebSocket serverWebsocket) {\n    // Client may have not registered message handler, and messages sent may get lost.\n    // So we sleep for a while to send message.\n    AtomicInteger receiveCount = new AtomicInteger(0);\n    serverWebsocket.textMessageHandler(s -> {\n      receiveCount.getAndIncrement();\n    });\n    serverWebsocket.closeHandler((v) -> System.out.println(\"closed\"));\n\n    new Thread(() -> {\n      try {\n        Thread.sleep(1000);\n      } catch (InterruptedException e) {\n        e.printStackTrace();\n      }\n\n      serverWebsocket.writeTextMessage(\"hello\");\n\n      for (int i = 0; i < 5; i++) {\n        serverWebsocket.writeTextMessage(\"hello \" + i);\n        try {\n          Thread.sleep(500);\n        } catch (InterruptedException e) {\n          e.printStackTrace();\n        }\n      }\n      serverWebsocket.writeTextMessage(\"total \" + receiveCount.get());\n      serverWebsocket.close();\n    }).start();\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# spring boot configurations\nservicecomb:\n  service:\n    application: demo-etcd\n    version: 0.0.1\n    name: provider\n    properties:\n      group: green\n  registry:\n    etcd:\n      connectString: http://127.0.0.1:2379\n  config:\n    etcd:\n      connectString: http://127.0.0.1:2379\n      instance-tag: tag1\n\n  rest:\n    address: 0.0.0.0:9094?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  cors:\n    enabled: true\n    origin: \"*\"\n    allowCredentials: false\n    allowedMethod: \"*\"\n    maxAge: 3600\n\n\nkey1: 1\nkey2: 3\nkey3: 5\n\ntest1: env\ntest2: applition\ntest3: service\ntest4: version\ntest5: tag\n"
  },
  {
    "path": "demo/demo-etcd/provider/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-etcd/test-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-etcd</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>etcd-test-client</artifactId>\n  <name>Java Chassis::Demo::Etcd::TEST-CLIENT</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.etcd</groupId>\n      <artifactId>jetcd-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.protobuf</groupId>\n      <artifactId>protobuf-java</artifactId>\n      <version>3.25.5</version>\n      <scope>runtime</scope>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>bitnami/etcd:3.5.16</name>\n                    <alias>etcd</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <wait>\n                        <log>etcdserver</log>\n                        <tcp>\n                          <ports>\n                            <port>2379</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>2379:2379</port>\n                      </ports>\n                      <env>\n                        <ALLOW_NONE_AUTHENTICATION>yes</ALLOW_NONE_AUTHENTICATION>\n                      </env>\n                    </run>\n                  </image>\n                  <image>\n                    <name>etcd-provider:${project.version}</name>\n                    <alias>etcd-provider</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.etcd.connectString=http://etcd:2379\n                          -Dservicecomb.config.etcd.connectString=http://etcd:2379\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/etcd-provider-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>etcd:etcd</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9094</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9094:9094</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>etcd-consumer:${project.version}</name>\n                    <alias>etcd-consumer</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.etcd.connectString=http://etcd:2379\n                          -Dservicecomb.config.etcd.connectString=http://etcd:2379\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/etcd-consumer-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>etcd:etcd</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9092</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9092:9092</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>etcd-gateway:${project.version}</name>\n                    <alias>etcd-gateway</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.etcd.connectString=http://etcd:2379\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/etcd-gateway-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>etcd:etcd</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9090:9090</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface Config {\n  String GATEWAY_URL = \"http://localhost:9090\";\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/EtcdConfigIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.ConditionWaiter.SleepUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\nimport io.etcd.jetcd.ByteSequence;\nimport io.etcd.jetcd.Client;\n\n@Component\npublic class EtcdConfigIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(EtcdConfigIT.class);\n\n  @Override\n  public void testRestTransport() throws Exception {\n\n    testEnvironment();\n    testApplication();\n    testService();\n    testVersion();\n    testTag();\n    testOverride();\n  }\n\n  private void testOverride() {\n\n    putValue(\"/servicecomb/config/environment/production/application2.properties\",\n        \"testValue=t1\");\n    putValue(\"/servicecomb/config/application/production/demo-etcd/application2.properties\",\n        \"testValue=t2\");\n    testGetConfig(\"testValue\", \"t2\");\n    putValue(\"/servicecomb/config/service/production/demo-etcd/provider/application2.properties\",\n        \"testValue=t3\");\n    testGetConfig(\"testValue\", \"t3\");\n    putValue(\"/servicecomb/config/version/production/demo-etcd/provider/0.0.1/application2.properties\",\n        \"testValue=t4\");\n    testGetConfig(\"testValue\", \"t4\");\n    putValue(\"/servicecomb/config/tag/production/demo-etcd/provider/0.0.1/tag1/application2.properties\",\n        \"testValue=t5\");\n    testGetConfig(\"testValue\", \"t5\");\n  }\n\n  private void testEnvironment() {\n\n    putValue(\"/servicecomb/config/environment/production/application.properties\",\n        \"test1=env\");\n    putValue(\"/servicecomb/config/environment/production/application.properties\",\n        \"test1=env1\");\n\n    testGetConfig(\"test1\", \"env1\");\n  }\n\n\n  private void testApplication() {\n\n    putValue(\"/servicecomb/config/application/production/demo-etcd/application.properties\",\n        \"test2=applition\");\n    putValue(\"/servicecomb/config/application/production/demo-etcd/application.properties\",\n        \"test2=applition2\");\n    testGetConfig(\"test2\", \"applition2\");\n  }\n\n  private void testService() {\n\n    putValue(\"/servicecomb/config/service/production/demo-etcd/provider/application.properties\",\n        \"test3=service\");\n    putValue(\"/servicecomb/config/service/production/demo-etcd/provider/application.properties\",\n        \"test3=service3\");\n    testGetConfig(\"test3\", \"service3\");\n  }\n\n  private void testVersion() {\n\n    putValue(\"/servicecomb/config/version/production/demo-etcd/provider/0.0.1/application.properties\",\n        \"test3=version\");\n    putValue(\"/servicecomb/config/version/production/demo-etcd/provider/0.0.1/application.properties\",\n        \"test4=version4\");\n    testGetConfig(\"test4\", \"version4\");\n  }\n\n  private void testTag() {\n\n    putValue(\"/servicecomb/config/tag/production/demo-etcd/provider/0.0.1/tag1/application.properties\",\n        \"test5=tag\");\n    putValue(\"/servicecomb/config/tag/production/demo-etcd/provider/0.0.1/tag1/application.properties\",\n        \"test5=tag5\");\n    testGetConfig(\"test5\", \"tag5\");\n  }\n\n\n  public void putValue(String key, String value) {\n    try (Client client = Client.builder().endpoints(\"http://localhost:2379\").build()) {\n\n      client.getKVClient().put(\n          ByteSequence.from(key, StandardCharsets.UTF_8),\n          ByteSequence.from(value, StandardCharsets.UTF_8)\n      ).get();\n\n      LOGGER.info(\"Value set successfully:{}\", value);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n\n  private void testGetConfig(String key, String expectValue) {\n\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=\" + key, String.class);\n\n    for (int i = 0; i < 4; i++) {\n      if (StringUtils.equals(expectValue, result)) {\n        TestMgr.check(expectValue, result);\n        break;\n      }\n      SleepUtil.sleep(500, TimeUnit.MILLISECONDS);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HeaderParamWithListSchemaIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHeaderListDefault();\n    testHeaderListMulti();\n    testHeaderListCSV();\n    testHeaderListSSV();\n    testHeaderListPipes();\n  }\n\n  // default to multi\n  private void testHeaderListDefault() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListDefault\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListPipes() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a|b|c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListPIPES\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListSSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a b c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListSSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListCSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a,b,c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n\n    headers.add(\"headerList\", \"a, b, c\");\n    entity = new HttpEntity<>(headers);\n    result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListMulti() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListMULTI\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HelloWorldIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHelloWorld();\n    testGetConfig();\n  }\n\n  private void testGetConfig() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key1\", String.class);\n    TestMgr.check(\"1\", result);\n    result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key2\", String.class);\n    TestMgr.check(\"3\", result);\n    result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key3\", String.class);\n    TestMgr.check(\"5\", result);\n  }\n\n  private void testHelloWorld() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/sayHello?name=World\", String.class);\n    TestMgr.check(\"Hello World\", result);\n\n    // test trace id added\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"X-B3-TraceId\", \"81de2eb7691c2bbb\");\n    HttpEntity<Object> entity = new HttpEntity(headers);\n    ResponseEntity<String> response =\n        template.exchange(Config.GATEWAY_URL + \"/sayHello?name=World\", HttpMethod.GET, entity, String.class);\n    TestMgr.check(1, response.getHeaders().get(\"X-B3-TraceId\").size());\n    TestMgr.check(\"81de2eb7691c2bbb\", response.getHeaders().getFirst(\"X-B3-TraceId\"));\n    TestMgr.check(\"Hello World\", response.getBody());\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/ProviderIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class ProviderIT implements CategorizedTestCase {\n\n  RestOperations template = new RestTemplate();\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProviderIT.class);\n\n  @Override\n  public void testRestTransport() throws Exception {\n\n    User user = getUser(\"Application/json\");\n    TestMgr.check(1L, user.getId());\n    TestMgr.check(\"czd\", user.getName());\n\n    User user2 = getUser(\"application/json\");\n    TestMgr.check(1L, user2.getId());\n    TestMgr.check(\"czd\", user2.getName());\n\n    User user3 = getUser(\"APPLICATION/JSON\");\n    TestMgr.check(1L, user3.getId());\n    TestMgr.check(\"czd\", user3.getName());\n  }\n\n  private User getUser(String contentType) throws IOException {\n    HttpHeaders headers = new HttpHeaders();\n    headers.set(\"Content-Type\", contentType);\n\n    String requestBody = \"\"\"\n        {\n            \"id\": 1,\n            \"name\": \"czd\"\n        }\n        \"\"\";\n\n    HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);\n\n    String url = Config.GATEWAY_URL + \"/testContentType\";\n    ResponseEntity<String> response = template.exchange(\n        url, HttpMethod.POST, entity, String.class);\n\n    User user = JsonUtils.readValue(response.getBody().getBytes(StandardCharsets.UTF_8), User.class);\n    return user;\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/ReactiveStreamIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient.Model;\nimport org.reactivestreams.Publisher;\nimport org.reactivestreams.Subscriber;\nimport org.reactivestreams.Subscription;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ReactiveStreamIT implements CategorizedTestCase {\n  @Autowired\n  @Qualifier(\"reactiveStreamProvider\")\n  ReactiveStreamClient reactiveStreamProvider;\n\n  @Autowired\n  @Qualifier(\"reactiveStreamGateway\")\n  ReactiveStreamClient reactiveStreamGateway;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testSseString(reactiveStreamProvider);\n    testSseModel(reactiveStreamProvider);\n    testSseString(reactiveStreamGateway);\n    testSseModel(reactiveStreamGateway);\n  }\n\n  private void testSseModel(ReactiveStreamClient client) throws Exception {\n    Publisher<Model> result = client.sseModel();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(Model s) {\n        buffer.append(s.getName()).append(s.getAge());\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"jack0jack1jack2jack3jack4\", buffer.toString());\n  }\n\n  private void testSseString(ReactiveStreamClient client) throws Exception {\n    Publisher<String> result = client.sseString();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(String s) {\n        buffer.append(s);\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"abc\", buffer.toString());\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class TestClientApplication {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args);\n\n      run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"consumer\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/ThirdSvcConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.reactivestreams.Publisher;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.WebSocket;\n\n@Configuration\npublic class ThirdSvcConfiguration {\n  @RequestMapping(path = \"/ws\")\n  public interface WebsocketClient {\n    @PostMapping(\"/websocket\")\n    @Transport(name = CoreConst.WEBSOCKET)\n    WebSocket websocket();\n  }\n\n  @RequestMapping(path = \"/\")\n  public interface ReactiveStreamClient {\n    class Model {\n      private String name;\n\n      private int age;\n\n      public Model() {\n\n      }\n\n      public Model(String name, int age) {\n        this.name = name;\n        this.age = age;\n      }\n\n      public int getAge() {\n        return age;\n      }\n\n      public Model setAge(int age) {\n        this.age = age;\n        return this;\n      }\n\n      public String getName() {\n        return name;\n      }\n\n      public Model setName(String name) {\n        this.name = name;\n        return this;\n      }\n    }\n\n    @GetMapping(\"/sseString\")\n    Publisher<String> sseString();\n\n    @GetMapping(\"/sseModel\")\n    Publisher<Model> sseModel();\n  }\n\n  @Bean\n  public RegistryBean providerServiceBean() {\n    return new RegistryBean()\n        .addSchemaInterface(\"ReactiveStreamController\", ReactiveStreamClient.class)\n        .setAppId(\"demo-etcd\")\n        .setServiceName(\"provider\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(\n            new Instance().setEndpoints(List.of(\"rest://localhost:9094\")))));\n  }\n\n  @Bean\n  public RegistryBean gatewayServiceBean() {\n    return new RegistryBean()\n        .addSchemaInterface(\"ReactiveStreamController\", ReactiveStreamClient.class)\n        .addSchemaInterface(\"WebsocketController\", WebsocketClient.class)\n        .setAppId(\"demo-etcd\")\n        .setServiceName(\"gateway\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(\n            new Instance().setEndpoints(List.of(\"rest://localhost:9090?websocketEnabled=true\")))));\n  }\n\n  @Bean(\"reactiveStreamProvider\")\n  public ReactiveStreamClient reactiveStreamProvider() {\n    return Invoker.createProxy(\"provider\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n\n  @Bean(\"reactiveStreamGateway\")\n  public ReactiveStreamClient reactiveStreamGateway() {\n    return Invoker.createProxy(\"gateway\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n\n  @Bean\n  public WebsocketClient gatewayWebsocketClient() {\n    return Invoker.createProxy(\"gateway\", \"WebsocketController\", WebsocketClient.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\npublic class User {\n\n  private Long id;\n\n  private String name;\n\n  public Long getId() {\n    return id;\n  }\n\n  public void setId(Long id) {\n    this.id = id;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.WebsocketClient;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport io.vertx.core.http.WebSocket;\n\n@Component\npublic class WebsocketIT implements CategorizedTestCase {\n  @Autowired\n  private WebsocketClient websocketClient;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    StringBuffer sb = new StringBuffer();\n    AtomicBoolean closed = new AtomicBoolean(false);\n    CountDownLatch latch = new CountDownLatch(1);\n\n    WebSocket webSocket = websocketClient.websocket();\n    webSocket.textMessageHandler(s -> {\n      sb.append(s);\n      sb.append(\" \");\n      webSocket.writeTextMessage(s);\n    });\n    webSocket.closeHandler(v -> {\n      closed.set(true);\n      latch.countDown();\n    });\n    latch.await(30, TimeUnit.SECONDS);\n    TestMgr.check(sb.toString(), \"hello hello 0 hello 1 hello 2 hello 3 hello 4 total 6 \");\n    TestMgr.check(closed.get(), true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-etcd\n    name: test-client\n    version: 0.0.1\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n\n  config:\n    etcd:\n      instance-tag: tag1\n\ntest1: env\ntest2: applition\ntest3: service\ntest4: version\ntest5: tag\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-etcd/test-client/src/test/java/org/apache/servicecomb/samples/EtcdIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = TestClientApplication.class)\npublic class EtcdIT {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EtcdIT.class);\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() {\n    try {\n      TestClientApplication.run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-filter</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>filter-client</artifactId>\n  <name>Java Chassis::Demo::Filter::Client</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.filter.FilterClient</demo.main>\n  </properties>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-filter/filter-client/src/main/java/org/apache/servicecomb/demo/filter/FilterClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.filter;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class FilterClient {\n  private static final Logger LOGGER = LoggerFactory.getLogger(FilterClient.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder(FilterClient.class).web(WebApplicationType.NONE).run(args);\n\n      run();\n    } catch (Throwable e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"com.servicecomb.filterServer\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-client/src/main/java/org/apache/servicecomb/demo/filter/client/ClientExceptionSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.client.RestOperations;\n\n@RestSchema(schemaId = \"ClientExceptionSchema\")\n@RequestMapping(path = \"/exception\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class ClientExceptionSchema {\n  interface IExceptionSchema {\n    boolean blockingException();\n\n    CompletableFuture<Boolean> reactiveException();\n  }\n\n  private IExceptionSchema exceptionSchema;\n\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @RpcReference(microserviceName = \"com.servicecomb.filterServer\", schemaId = \"ExceptionSchema\")\n  public void setExceptionSchema(IExceptionSchema exceptionSchema) {\n    this.exceptionSchema = exceptionSchema;\n  }\n\n  @GetMapping(path = \"/blockingExceptionRestTemplate\")\n  public boolean blockingExceptionRestTemplate() {\n    return restTemplate.getForObject(\n        \"servicecomb://com.servicecomb.filterServer/exception/blockingException\", boolean.class);\n  }\n\n  @GetMapping(path = \"/blockingExceptionReference\")\n  public boolean blockingExceptionReference() {\n    return exceptionSchema.blockingException();\n  }\n\n  @GetMapping(path = \"/blockingExceptionInvoker\")\n  public boolean blockingExceptionInvoker() {\n    return InvokerUtils.syncInvoke(\"com.servicecomb.filterServer\",\n        \"ExceptionSchema\", \"blockingException\", null, boolean.class);\n  }\n\n  @GetMapping(path = \"/reactiveExceptionReference\")\n  public CompletableFuture<Boolean> reactiveExceptionReference() {\n    return exceptionSchema.reactiveException();\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-client/src/main/java/org/apache/servicecomb/demo/filter/client/GovernanceConsumerSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.client;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"GovernanceConsumerSchema\")\n@RequestMapping(path = \"/govern\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class GovernanceConsumerSchema {\n  interface GovernanceProviderSchemaInf {\n    boolean providerFlowControl();\n  }\n\n  @RpcReference(microserviceName = \"com.servicecomb.filterServer\", schemaId = \"GovernanceProviderSchema\")\n  private GovernanceProviderSchemaInf retrySchemaInf;\n\n\n  @GetMapping(path = \"/edgeFlowControl\")\n  public boolean edgeFlowControl() {\n    return true;\n  }\n\n  @GetMapping(path = \"/providerFlowControl\")\n  public boolean providerFlowControl() {\n    return retrySchemaInf.providerFlowControl();\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-client/src/main/java/org/apache/servicecomb/demo/filter/client/RetryClientSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.client;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.core.Response.Status;\n\n@RestSchema(schemaId = \"RetryClientSchema\")\n@RequestMapping(path = \"/retry\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class RetryClientSchema {\n  interface RetrySchemaInf {\n    CompletableFuture<Boolean> successWhenRetryAsync();\n  }\n\n  @RpcReference(microserviceName = \"com.servicecomb.filterServer\", schemaId = \"RetrySchema\")\n  private RetrySchemaInf retrySchemaInf;\n\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private AtomicLong counter = new AtomicLong(0);\n\n  @GetMapping(path = \"/governance/edgeSuccessWhenRetry\")\n  public boolean edgeSuccessWhenRetry() {\n    if (counter.getAndIncrement() % 3 != 0) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR, \"try again later.\");\n    }\n    return true;\n  }\n\n  @GetMapping(path = \"/governance/edgeSuccessWhenRetryAsync\")\n  public CompletableFuture<Boolean> edgeSuccessWhenRetryAsync() {\n    CompletableFuture<Boolean> result = new CompletableFuture<>();\n    if (counter.getAndIncrement() % 2 == 0) {\n      result.completeExceptionally(new InvocationException(Status.INTERNAL_SERVER_ERROR, \"try again later.\"));\n    } else {\n      result.complete(true);\n    }\n    return result;\n  }\n\n  @GetMapping(path = \"/governance/successWhenRetry\")\n  public boolean successWhenRetry() {\n    return restTemplate.getForObject(\"servicecomb://com.servicecomb.filterServer/retry/governance/successWhenRetry\",\n        Boolean.class);\n  }\n\n  @GetMapping(path = \"/governance/successWhenRetryAsync\")\n  public CompletableFuture<Boolean> successWhenRetryAsync() {\n    return retrySchemaInf.successWhenRetryAsync();\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-filter/filter-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: filtertest\n    # test service name with dot\n    name: com.servicecomb.filterClient\n    version: 0.0.1\n\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8082\n    server:\n      compression: true\n  highway:\n    address: 0.0.0.0:7072\n\n  invocation:\n    exception:\n      print-stack-trace: true\n  # test governance retry\n  matchGroup:\n    retry-governance: |\n      matches:\n        - apiPath:\n            prefix: \"/retry/governance/\"\n\n  retry:\n    retry-governance: |\n      maxAttempts: 2\n      retryOnResponseStatus: [500]\n"
  },
  {
    "path": "demo/demo-filter/filter-edge/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-filter</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>filter-edge</artifactId>\n  <name>Java Chassis::Demo::Filter::Edge</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.filter.FilterEdge</demo.main>\n  </properties>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-filter/filter-edge/src/main/java/org/apache/servicecomb/demo/filter/FilterEdge.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.filter;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class FilterEdge {\n  private static final Logger LOGGER = LoggerFactory.getLogger(FilterEdge.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder(FilterEdge.class).web(WebApplicationType.NONE).run(args);\n\n      run();\n    } catch (Throwable e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"filterEdge\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-edge/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-filter/filter-edge/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: filtertest\n    # test service name with dot\n    name: com.servicecomb.filterEdge\n    version: 0.0.1\n\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n\n  rest:\n    address: 0.0.0.0:9090\n    server:\n      compression: true\n\n  edge:\n    filter:\n      addHeader:\n        allowedHeaders: X-B3-TraceId\n\n  invocation:\n    exception:\n      print-stack-trace: true\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: true\n          prefix: service\n          withVersion: false\n          prefixSegmentCount: 2\n        url:\n          enabled: true\n          mappings:\n            filterClient:\n              prefixSegmentCount: 0\n              path: \"/retry/.*\"\n              microserviceName: com.servicecomb.filterClient\n            filterClient2:\n              prefixSegmentCount: 0\n              path: \"/govern/.*\"\n              microserviceName: com.servicecomb.filterClient\n  matchGroup:\n    edgeFlowControl: |\n      matches:\n        - apiPath:\n            exact: \"/govern/edgeFlowControl\"\n    retry-governance: |\n      matches:\n        - apiPath:\n            prefix: \"/retry/governance/\"\n  rateLimiting:\n    edgeFlowControl: |\n      timeoutDuration: 0\n      limitRefreshPeriod: 1000\n      rate: 1\n  retry:\n    retry-governance: |\n      maxAttempts: 2\n      retryOnResponseStatus: [500]\n"
  },
  {
    "path": "demo/demo-filter/filter-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-filter</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>filter-server</artifactId>\n  <name>Java Chassis::Demo::Filter::Server</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.filter.FilterServer</demo.main>\n  </properties>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-filter/filter-server/src/main/java/org/apache/servicecomb/demo/filter/FilterServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.filter;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class FilterServer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(FilterServer.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder(FilterServer.class).web(WebApplicationType.NONE).run(args);\n\n      run();\n    } catch (Throwable e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"filterServer\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-server/src/main/java/org/apache/servicecomb/demo/filter/server/ExceptionSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.server;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"ExceptionSchema\")\n@RequestMapping(path = \"/exception\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class ExceptionSchema {\n  @GetMapping(path = \"/blockingException\")\n  public boolean blockingException() {\n    throw new InvocationException(Status.SERVICE_UNAVAILABLE, new CommonExceptionData(\"Blocking Exception\"));\n  }\n\n  @GetMapping(path = \"/reactiveException\")\n  public CompletableFuture<Boolean> reactiveException() {\n    throw new InvocationException(Status.SERVICE_UNAVAILABLE, new CommonExceptionData(\"Reactive Exception\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-server/src/main/java/org/apache/servicecomb/demo/filter/server/GovernanceProviderSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"GovernanceProviderSchema\")\n@RequestMapping(path = \"/govern\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class GovernanceProviderSchema {\n  @GetMapping(path = \"/providerFlowControl\")\n  public boolean providerFlowControl() {\n    return true;\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-server/src/main/java/org/apache/servicecomb/demo/filter/server/RetrySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.server;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n// test cases for retry\n@RestSchema(schemaId = \"RetrySchema\")\n@RequestMapping(path = \"/retry\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class RetrySchema {\n  private AtomicLong counter = new AtomicLong(0);\n\n  @GetMapping(path = \"/governance/successWhenRetry\")\n  public boolean successWhenRetry() {\n    if (counter.getAndIncrement() % 3 != 0) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR, \"try again later.\");\n    }\n    return true;\n  }\n\n  @GetMapping(path = \"/governance/successWhenRetryAsync\")\n  public CompletableFuture<Boolean> successWhenRetryAsync() {\n    CompletableFuture<Boolean> result = new CompletableFuture<>();\n    if (counter.getAndIncrement() % 2 == 0) {\n      result.completeExceptionally(new InvocationException(Status.INTERNAL_SERVER_ERROR, \"try again later.\"));\n    } else {\n      result.complete(true);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-filter/filter-server/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: filtertest\n    # test service name with dot\n    name: com.servicecomb.filterServer\n    version: 0.0.1\n\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n\n  rest:\n    address: 0.0.0.0:8080\n    server:\n      compression: true\n  highway:\n    address: 0.0.0.0:7070\n\n  matchGroup:\n    providerFlowControl: |\n      matches:\n        - apiPath:\n            exact: \"/govern/providerFlowControl\"\n  rateLimiting:\n    providerFlowControl: |\n      timeoutDuration: 0\n      limitRefreshPeriod: 1000\n      rate: 1\n\n#########SSL options\nssl.protocols: TLSv1.2\nssl.authPeer: true\nssl.checkCN.host: true\n\n#########certificates config\nssl.trustStore: trust.jks\nssl.trustStoreType: JKS\nssl.trustStoreValue: Changeme_123\nssl.keyStore: server.p12\nssl.keyStoreType: PKCS12\nssl.keyStoreValue: Changeme_123\nssl.crl: revoke.crl\nssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom\n\nvertx.disableFileCPResolving: false  # false: create the .vertx directory, true: do not create\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-filter</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>filter-tests</artifactId>\n  <name>Java Chassis::Demo::Filter::Tests</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.filter.FilterTests</demo.main>\n  </properties>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service30100</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>filter-server:${project.version}</name>\n                    <alias>filter-server</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://service30100:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/filter-server-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service30100:service30100</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8080:8080</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>filter-client:${project.version}</name>\n                    <alias>filter-client</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://service30100:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/filter-client-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service30100:service30100</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8082</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8082:8082</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>filter-edge:${project.version}</name>\n                    <alias>filter-edge</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://service30100:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/filter-edge-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service30100:service30100</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9090:9090</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/java/org/apache/servicecomb/demo/filter/FilterTests.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.filter;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class FilterTests {\n  private static final Logger LOGGER = LoggerFactory.getLogger(FilterTests.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder(FilterTests.class).web(WebApplicationType.NONE).run(args);\n\n      run();\n    } catch (Throwable e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"filterTests\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/java/org/apache/servicecomb/demo/filter/tests/TestExceptionSchemaFromClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.tests;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestExceptionSchemaFromClient implements CategorizedTestCase {\n\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private static final String SERVER = \"servicecomb://com.servicecomb.filterClient\";\n\n  @Override\n  public String getMicroserviceName() {\n    return \"filterEdge\";\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testBlockingExceptionRestTemplate();\n    testBlockingExceptionReference();\n    testBlockingExceptionInvoker();\n    testReactiveExceptionReference();\n  }\n\n  private void testBlockingExceptionRestTemplate() {\n    try {\n      restTemplate.getForObject(SERVER + \"/exception/blockingExceptionRestTemplate\",\n          boolean.class);\n    } catch (InvocationException e) {\n      TestMgr.check(503, e.getStatus().getStatusCode());\n      TestMgr.check(\"Blocking Exception\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n\n  private void testBlockingExceptionReference() {\n    try {\n      restTemplate.getForObject(SERVER + \"/exception/blockingExceptionReference\",\n          boolean.class);\n    } catch (InvocationException e) {\n      TestMgr.check(503, e.getStatus().getStatusCode());\n      TestMgr.check(\"Blocking Exception\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n\n  private void testBlockingExceptionInvoker() {\n    try {\n      restTemplate.getForObject(SERVER + \"/exception/blockingExceptionInvoker\",\n          boolean.class);\n    } catch (InvocationException e) {\n      TestMgr.check(503, e.getStatus().getStatusCode());\n      TestMgr.check(\"Blocking Exception\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n\n  private void testReactiveExceptionReference() {\n    try {\n      restTemplate.getForObject(SERVER + \"/exception/reactiveExceptionReference\",\n          boolean.class);\n    } catch (InvocationException e) {\n      TestMgr.check(503, e.getStatus().getStatusCode());\n      TestMgr.check(\"Reactive Exception\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/java/org/apache/servicecomb/demo/filter/tests/TestGovernanceSchemaFromEdge.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.tests;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestGovernanceSchemaFromEdge implements CategorizedTestCase {\n  interface GovernanceEdgeSchemaInf {\n    boolean edgeFlowControl();\n\n    boolean providerFlowControl();\n  }\n\n  @RpcReference(microserviceName = \"com.servicecomb.filterEdge\", schemaId = \"GovernanceConsumerSchema\")\n  private GovernanceEdgeSchemaInf retrySchemaInf;\n\n  @Override\n  public String getMicroserviceName() {\n    return \"com.servicecomb.filterEdge\";\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testEdgeFlowControl();\n    testConsumerFlowControl();\n  }\n\n  private void testConsumerFlowControl() throws Exception {\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              boolean result = retrySchemaInf.providerFlowControl();\n              if (!result) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (!e.getMessage().contains(\"rate limited\")) {\n                notExpectedFailed.set(true);\n              }\n              expectedFailed.set(true);\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(expectedFailed.get(), true);\n    TestMgr.check(notExpectedFailed.get(), false);\n  }\n\n  private void testEdgeFlowControl() throws Exception {\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              boolean result = retrySchemaInf.edgeFlowControl();\n              if (!result) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (!e.getMessage().contains(\"rate limited\")) {\n                notExpectedFailed.set(true);\n              }\n              expectedFailed.set(true);\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(expectedFailed.get(), true);\n    TestMgr.check(notExpectedFailed.get(), false);\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/java/org/apache/servicecomb/demo/filter/tests/TestRetrySchemaFromClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.tests;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestRetrySchemaFromClient implements CategorizedTestCase {\n  interface RetrySchemaInf {\n    boolean successWhenRetry();\n\n    CompletableFuture<Boolean> successWhenRetryAsync();\n  }\n\n  @RpcReference(microserviceName = \"com.servicecomb.filterClient\", schemaId = \"RetryClientSchema\")\n  private RetrySchemaInf retrySchemaInf;\n\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private static final String SERVER = \"servicecomb://com.servicecomb.filterClient\";\n\n  @Override\n  public String getMicroserviceName() {\n    return \"com.servicecomb.filterClient\";\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testRetryGovernanceRestTemplate();\n    testRetryGovernanceRpc();\n  }\n\n  private void testRetryGovernanceRpc() throws Exception {\n    TestMgr.check(retrySchemaInf.successWhenRetry(), true);\n    TestMgr.check(retrySchemaInf.successWhenRetry(), true);\n\n    TestMgr.check(retrySchemaInf.successWhenRetryAsync().get(), true);\n    TestMgr.check(retrySchemaInf.successWhenRetryAsync().get(), true);\n  }\n\n  private void testRetryGovernanceRestTemplate() {\n    TestMgr.check(restTemplate.getForObject(SERVER + \"/retry/governance/successWhenRetry\", boolean.class), true);\n    TestMgr.check(restTemplate.getForObject(SERVER + \"/retry/governance/successWhenRetry\", boolean.class), true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/java/org/apache/servicecomb/demo/filter/tests/TestRetrySchemaFromEdge.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.filter.tests;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class TestRetrySchemaFromEdge implements CategorizedTestCase {\n  interface RetrySchemaInf {\n    boolean edgeSuccessWhenRetry();\n\n    boolean successWhenRetry();\n\n    CompletableFuture<Boolean> edgeSuccessWhenRetryAsync();\n\n    CompletableFuture<Boolean> successWhenRetryAsync();\n  }\n\n  @RpcReference(microserviceName = \"com.servicecomb.filterEdge\", schemaId = \"RetryClientSchema\")\n  private RetrySchemaInf retrySchemaInf;\n\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  RestTemplate springRestTemplate = new RestTemplate();\n\n  private static final String SERVER = \"servicecomb://com.servicecomb.filterEdge\";\n\n  private static final String EDGE_SERVER = \"http://127.0.0.1:9090\";\n\n  @Override\n  public String getMicroserviceName() {\n    return \"com.servicecomb.filterEdge\";\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testRetryGovernanceFromEdgeDefaultDispatcher();\n    testRetryGovernanceRestTemplate();\n    testRetryGovernanceRpc();\n    testEdgeRetryGovernanceRpc();\n  }\n\n  private void testRetryGovernanceRpc() throws Exception {\n    TestMgr.check(retrySchemaInf.successWhenRetry(), true);\n    TestMgr.check(retrySchemaInf.successWhenRetry(), true);\n\n    TestMgr.check(retrySchemaInf.successWhenRetryAsync().get(), true);\n    TestMgr.check(retrySchemaInf.successWhenRetryAsync().get(), true);\n  }\n\n  private void testEdgeRetryGovernanceRpc() throws Exception {\n    TestMgr.check(retrySchemaInf.edgeSuccessWhenRetry(), true);\n    TestMgr.check(retrySchemaInf.edgeSuccessWhenRetry(), true);\n\n    TestMgr.check(retrySchemaInf.edgeSuccessWhenRetryAsync().get(), true);\n    TestMgr.check(retrySchemaInf.edgeSuccessWhenRetryAsync().get(), true);\n  }\n\n  private void testRetryGovernanceRestTemplate() {\n    TestMgr.check(restTemplate.getForObject(\n        SERVER + \"/retry/governance/successWhenRetry\", boolean.class), true);\n    TestMgr.check(restTemplate.getForObject(\n        SERVER + \"/retry/governance/successWhenRetry\", boolean.class), true);\n  }\n\n  private void testRetryGovernanceFromEdgeDefaultDispatcher() {\n    TestMgr.check(springRestTemplate.getForObject(\n        EDGE_SERVER + \"/service/com.servicecomb.filterClient/retry/governance/successWhenRetry\", boolean.class), true);\n    TestMgr.check(springRestTemplate.getForObject(\n        EDGE_SERVER + \"/service/com.servicecomb.filterClient/retry/governance/successWhenRetry\", boolean.class), true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: filtertest\n    # test service name with dot\n    name: com.servicecomb.filterTests\n    version: 0.0.1\n\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n\n  invocation:\n    exception:\n      print-stack-trace: true\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/resources/microservices/com.servicecomb.filterEdge/GovernanceConsumerSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.filter.client.GovernanceConsumerSchema\n  version: 1.0.0\nservers:\n- url: /govern\npaths:\n  /edgeFlowControl:\n    get:\n      operationId: edgeFlowControl\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\n  /providerFlowControl:\n    get:\n      operationId: providerFlowControl\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\ncomponents: {}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/resources/microservices/com.servicecomb.filterEdge/RetryClientSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.filter.client.RetryClientSchema\n  version: 1.0.0\nservers:\n- url: /retry\npaths:\n  /governance/edgeSuccessWhenRetry:\n    get:\n      operationId: edgeSuccessWhenRetry\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\n  /governance/edgeSuccessWhenRetryAsync:\n    get:\n      operationId: edgeSuccessWhenRetryAsync\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\n  /governance/successWhenRetry:\n    get:\n      operationId: successWhenRetry\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\n  /governance/successWhenRetryAsync:\n    get:\n      operationId: successWhenRetryAsync\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\ncomponents: {}\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/main/resources/registry.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\ncom.servicecomb.filterEdge:\n  - id: \"001\"\n    version: \"1.0\"\n    appid: filtertest\n    instances:\n      - endpoints:\n          - rest://127.0.0.1:9090\n"
  },
  {
    "path": "demo/demo-filter/filter-tests/src/test/java/org/apache/servicecomb/demo/filter/retry/FilterTestsIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.filter.retry;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.filter.FilterTests;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = FilterTests.class)\npublic class FilterTestsIT {\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    FilterTests.run();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-filter/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-filter</artifactId>\n  <name>Java Chassis::Demo::Filter</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>filter-server</module>\n    <module>filter-client</module>\n    <module>filter-edge</module>\n    <module>filter-tests</module>\n  </modules>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-jaxrs</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>jaxrs-client</artifactId>\n  <name>Java Chassis::Demo::JAXRS::Client</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.jaxrs.JaxrsClient</demo.main>\n  </properties>\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>jaxrs-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/JaxrsClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.CodeFirstRestTemplate;\nimport org.apache.servicecomb.demo.DemoConst;\nimport org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;\nimport org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.jaxrs.client.CodeFirstRestTemplateJaxrs;\nimport org.apache.servicecomb.demo.jaxrs.client.pojoDefault.DefaultModelServiceClient;\nimport org.apache.servicecomb.demo.jaxrs.client.validation.ValidationServiceClient;\nimport org.apache.servicecomb.demo.validator.Student;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\n@SpringBootApplication\npublic class JaxrsClient {\n  private static final Logger LOGGER = LoggerFactory.getLogger(JaxrsClient.class);\n\n  private static RestOperations templateNew = RestTemplateBuilder.create();\n\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(JaxrsClient.class).web(WebApplicationType.NONE).run(args);\n\n    init();\n\n    try {\n      run();\n    } catch (Exception e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n\n    TestMgr.summary();\n    LOGGER.info(\"-------------- last time updated checks(maybe more/less): 540 -------------\");\n  }\n\n  public static void init() throws Exception {\n    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());\n    RestObjectMapperFactory.setConsumerWriterMapper(new RestObjectMapperWithStringMapperNotWriteNull());\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"jaxrs\");\n\n    CodeFirstRestTemplate codeFirstClient = BeanUtils.getBean(CodeFirstRestTemplateJaxrs.class);\n    codeFirstClient.testCodeFirst(templateNew, \"jaxrs\", \"/codeFirstJaxrs/\");\n    testCompute(templateNew);\n    testValidator(templateNew);\n    testJaxRSDefaultValuesAllTransport(templateNew);\n    testSpringMvcDefaultValuesJavaPrimitiveAllTransport(templateNew);\n\n    DefaultModelServiceClient.run();\n    ValidationServiceClient.run();\n\n    testOnlyRest(templateNew);\n  }\n\n  private static void testOnlyRest(RestOperations template) {\n    String microserviceName = \"jaxrs\";\n    String cseUrlPrefix = \"cse://\" + microserviceName;\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, \"rest\");\n\n    testGetRest(template, cseUrlPrefix);\n    testSpringMvcDefaultValuesJavaPrimitiveRest(templateNew);\n  }\n\n  private static void testCompute(RestOperations template) throws Exception {\n    String microserviceName = \"jaxrs\";\n    for (String transport : DemoConst.transports) {\n      InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n      TestMgr.setMsg(microserviceName, transport);\n\n      String cseUrlPrefix = \"cse://\" + microserviceName;\n\n      testGetAllTransport(template, cseUrlPrefix);\n      testPost(template, cseUrlPrefix);\n      testPut(template, cseUrlPrefix);\n      testDelete(template, cseUrlPrefix);\n      testExchange(template, cseUrlPrefix);\n      testRawJsonParam(template, cseUrlPrefix);\n    }\n  }\n\n  private static void testValidator(RestOperations template) {\n    String microserviceName = \"jaxrs\";\n    for (String transport : DemoConst.transports) {\n      InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n      TestMgr.setMsg(microserviceName, transport);\n\n      String cseUrlPrefix = \"cse://\" + microserviceName + \"/validator/\";\n\n      testValidatorAddSuccess(template, cseUrlPrefix);\n      if (\"rest\".equals(transport)) {\n        testValidatorAddFail(template, cseUrlPrefix);\n        testValidatorSayHiFail(template, cseUrlPrefix);\n        testValidatorExchangeFail(template, cseUrlPrefix);\n        testJaxRSDefaultValuesRest(template);\n      } else if (\"highway\".equals(transport)) {\n        testValidatorAddFail(template, cseUrlPrefix);\n        testValidatorSayHiFail(template, cseUrlPrefix);\n        testValidatorExchangeFail(template, cseUrlPrefix);\n      }\n      testValidatorSayHiSuccess(template, cseUrlPrefix);\n      testValidatorExchangeSuccess(template, cseUrlPrefix);\n    }\n  }\n\n  private static void testJaxRSDefaultValuesRest(RestOperations template) {\n    String result;\n    String microserviceName = \"jaxrs\";\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/JaxRSDefaultValues/\";\n    boolean failed = false;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n\n    failed = false;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2?d=2&e=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(failed, true);\n\n    failed = false;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2?a=&d=2&e=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(failed, true);\n\n    result = template.getForObject(cseUrlPrefix + \"/query2?d=30&e=2\", String.class);\n    TestMgr.check(\"Hello 20bobo40302\", result);\n\n    failed = false;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query3?a=2&b=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(failed, true);\n  }\n\n  private static void testJaxRSDefaultValuesAllTransport(RestOperations template) {\n    String microserviceName = \"jaxrs\";\n    for (String transport : DemoConst.transports) {\n      InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n      TestMgr.setMsg(microserviceName, transport);\n\n      String cseUrlPrefix = \"cse://\" + microserviceName + \"/JaxRSDefaultValues/\";\n\n      //default values\n      HttpHeaders headers = new HttpHeaders();\n      headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);\n      MultiValueMap<String, String> map = new LinkedMultiValueMap<>();\n      HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);\n      String result = template.postForObject(cseUrlPrefix + \"/form\", request, String.class);\n      // TODO: do not support form parameters default value\n      //      TestMgr.check(\"Hello 20bobo\", result);\n      TestMgr.check(\"Hello 0null\", result);\n\n      headers = new HttpHeaders();\n      HttpEntity<String> entity = new HttpEntity<>(null, headers);\n      result = template.postForObject(cseUrlPrefix + \"/header\", entity, String.class);\n      TestMgr.check(\"Hello 20bobo30\", result);\n\n      result = template.getForObject(cseUrlPrefix + \"/query?d=10\", String.class);\n      TestMgr.check(\"Hello 20bobo4010\", result);\n      boolean failed = false;\n      try {\n        result = template.getForObject(cseUrlPrefix + \"/query2\", String.class);\n      } catch (InvocationException e) {\n        failed = true;\n        TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n      }\n\n      failed = false;\n      try {\n        result = template.getForObject(cseUrlPrefix + \"/query2?d=2&e=2\", String.class);\n      } catch (InvocationException e) {\n        failed = true;\n        TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n      }\n      TestMgr.check(failed, true);\n\n      failed = false;\n      try {\n        result = template.getForObject(cseUrlPrefix + \"/query2?a=&d=2&e=2\", String.class);\n      } catch (InvocationException e) {\n        failed = true;\n        TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n      }\n      TestMgr.check(failed, true);\n\n      result = template.getForObject(cseUrlPrefix + \"/query2?d=30&e=2\", String.class);\n      TestMgr.check(\"Hello 20bobo40302\", result);\n\n      failed = false;\n      try {\n        result = template.getForObject(cseUrlPrefix + \"/query3?a=2&b=2\", String.class);\n      } catch (InvocationException e) {\n        failed = true;\n        TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n      }\n      TestMgr.check(failed, true);\n\n      result = template.getForObject(cseUrlPrefix + \"/query3?a=30&b=2\", String.class);\n      TestMgr.check(\"Hello 302\", result);\n\n      result = template.getForObject(cseUrlPrefix + \"/query3?a=30\", String.class);\n      TestMgr.check(\"Hello 30null\", result);\n\n      //input values\n      headers = new HttpHeaders();\n      headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);\n      Map<String, String> params = new HashMap<>();\n      params.put(\"a\", \"30\");\n      params.put(\"b\", \"sam\");\n      HttpEntity<Map<String, String>> requestPara = new HttpEntity<>(params, headers);\n      result = template.postForObject(cseUrlPrefix + \"/form\", requestPara, String.class);\n      TestMgr.check(\"Hello 30sam\", result);\n\n      headers = new HttpHeaders();\n      headers.add(\"a\", \"30\");\n      headers.add(\"b\", \"sam\");\n      headers.add(\"c\", \"40\");\n      entity = new HttpEntity<>(null, headers);\n      result = template.postForObject(cseUrlPrefix + \"/header\", entity, String.class);\n      TestMgr.check(\"Hello 30sam40\", result);\n\n      result = template.getForObject(cseUrlPrefix + \"/query?a=3&b=sam&c=5&d=30\", String.class);\n      TestMgr.check(\"Hello 3sam530\", result);\n\n      result = template.getForObject(cseUrlPrefix + \"/query2?a=3&b=4&c=5&d=30&e=2\", String.class);\n      TestMgr.check(\"Hello 345302\", result);\n    }\n  }\n\n  private static void testGetRest(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"3\");\n    int result =\n        template.getForObject(cseUrlPrefix + \"/compute/reduce?a={a}&b={b}\", Integer.class, params);\n    TestMgr.check(2, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/compute/reduce?a={a}&b={b}\", Integer.class, 5, 4);\n    TestMgr.check(1, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/compute/reduce?a=5&b=6\",\n        Integer.class);\n    TestMgr.check(-1, result);\n  }\n\n  private static void testGetAllTransport(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"3\");\n    int result =\n        template.getForObject(cseUrlPrefix + \"/compute/reduce?a={a}&b={b}\", Integer.class, params);\n    TestMgr.check(2, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/compute/reduce?a={a}&b={b}\", Integer.class, 5, 4);\n    TestMgr.check(1, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/compute/reduce?a=5&b=6\",\n        Integer.class);\n    TestMgr.check(-1, result);\n  }\n\n  private static void testPost(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"3\");\n    int result =\n        template.postForObject(cseUrlPrefix + \"/compute/add\", params, Integer.class);\n    TestMgr.check(8, result);\n\n    Person person = new Person();\n    person.setName(\"world\");\n    Person resultPerson =\n        template.postForObject(cseUrlPrefix + \"/compute/sayhello\", person, Person.class);\n    TestMgr.check(\"hello world\", resultPerson.getName());\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"prefix\", \"haha\");\n    HttpEntity<Person> reqEntity = new HttpEntity<>(person, headers);\n    TestMgr.check(\"haha world\",\n        template.postForObject(cseUrlPrefix + \"/compute/saysomething\", reqEntity, String.class));\n  }\n\n  private static void testPut(RestOperations template, String cseUrlPrefix) {\n    template.put(cseUrlPrefix + \"/compute/sayhi/{name}\", null, \"world\");\n  }\n\n  private static void testDelete(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"name\", \"world\");\n    template.delete(cseUrlPrefix + \"/compute/sayhei/?name={name}\", params);\n  }\n\n  private static void testExchange(RestOperations template, String cseUrlPrefix) {\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"Accept\", MediaType.APPLICATION_JSON);\n    Person person = new Person();\n    person.setName(\"world\");\n    HttpEntity<Person> requestEntity = new HttpEntity<>(person, headers);\n    ResponseEntity<Person> resEntity = template.exchange(cseUrlPrefix + \"/compute/sayhello\",\n        HttpMethod.POST,\n        requestEntity,\n        Person.class);\n    TestMgr.check(\"hello world\", resEntity.getBody());\n\n    ResponseEntity<String> resEntity2 =\n        template.exchange(cseUrlPrefix + \"/compute/addstring?s=abc&s=def\", HttpMethod.DELETE, null, String.class);\n    TestMgr.check(\"abcdef\", resEntity2.getBody());\n  }\n\n  private static void testRawJsonParam(RestOperations template, String cseUrlPrefix) throws Exception {\n    Map<String, String> person = new HashMap<>();\n    person.put(\"name\", \"Tom\");\n    String jsonPerson = RestObjectMapperFactory.getRestObjectMapper().writeValueAsString(person);\n    TestMgr.check(\"hello Tom\",\n        template.postForObject(cseUrlPrefix + \"/compute/testrawjson\", jsonPerson, String.class));\n  }\n\n  @SuppressWarnings({\"rawtypes\"})\n  private static void testValidatorAddFail(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"3\");\n    boolean isExcep = false;\n    try {\n      template.postForObject(cseUrlPrefix + \"add\", params, Integer.class);\n    } catch (InvocationException e) {\n      isExcep = true;\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      // Message depended on locale, so just check the short part.\n      // 'must be greater than or equal to 20', propertyPath=add.arg1, rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator, messageTemplate='{jakarta.validation.constraints.Min.message}'}]]\n      // ignored\n      if (e.getErrorData() instanceof CommonExceptionData) {\n        // highway decode/encode 'Object' with special type information, got runtime type\n        CommonExceptionData data = (CommonExceptionData) e.getErrorData();\n        TestMgr.check(\"invalid parameters.\", data.getMessage());\n        TestMgr.check(\"add.b\",\n            ((Map) ((List<?>) data.getDynamic(\"validateDetail\")).get(0)).get(\"propertyPath\").toString());\n      } else {\n        // rest decode/encode 'Object' using json without type information, got map. Users can got runtime type by adding @JsonTypeInfo to the model.\n        Map data = (Map) e.getErrorData();\n        TestMgr.check(\"invalid parameters.\", data.get(\"message\").toString());\n        TestMgr.check(\"add.b\",\n            ((Map) ((List<?>) data.get(\"validateDetail\")).get(0)).get(\"propertyPath\").toString());\n      }\n    }\n\n    TestMgr.check(true, isExcep);\n  }\n\n  private static void testValidatorAddSuccess(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"20\");\n    int result = template.postForObject(cseUrlPrefix + \"add\", params, Integer.class);\n    TestMgr.check(25, result);\n  }\n\n  @SuppressWarnings({\"rawtypes\"})\n  private static void testValidatorSayHiFail(RestOperations template, String cseUrlPrefix) {\n    boolean isExcep = false;\n    try {\n      template.exchange(cseUrlPrefix + \"sayhi/{name}\", HttpMethod.PUT, null, String.class, \"te\");\n    } catch (InvocationException e) {\n      isExcep = true;\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      // Message depended on locale, so just check the short part.\n      if (e.getErrorData() instanceof CommonExceptionData) {\n        // highway decode/encode 'Object' with special type information, got runtime type\n        CommonExceptionData data = (CommonExceptionData) e.getErrorData();\n        TestMgr.check(\"invalid parameters.\", data.getMessage());\n        TestMgr.check(\"sayHi.name\",\n            ((Map) ((List<?>) data.getDynamic(\"validateDetail\")).get(0)).get(\"propertyPath\").toString());\n      } else {\n        Map data = (Map) e.getErrorData();\n        TestMgr.check(\"invalid parameters.\", data.get(\"message\").toString());\n        TestMgr.check(\"sayHi.name\",\n            ((Map) ((List<?>) data.get(\"validateDetail\")).get(0)).get(\"propertyPath\").toString());\n      }\n    }\n    TestMgr.check(true, isExcep);\n  }\n\n  private static void testValidatorSayHiSuccess(RestOperations template, String cseUrlPrefix) {\n    ResponseEntity<String> responseEntity =\n        template.exchange(cseUrlPrefix + \"sayhi/{name}\", HttpMethod.PUT, null, String.class, \"world\");\n    TestMgr.check(202, responseEntity.getStatusCode().value());\n    TestMgr.check(\"world sayhi\", responseEntity.getBody());\n  }\n\n  @SuppressWarnings({\"rawtypes\"})\n  private static void testValidatorExchangeFail(RestOperations template, String cseUrlPrefix) {\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"Accept\", MediaType.APPLICATION_JSON);\n    Student student = new Student();\n    student.setName(\"\");\n    student.setAge(25);\n    boolean isExcep = false;\n    try {\n      HttpEntity<Student> requestEntity = new HttpEntity<>(student, headers);\n      template.exchange(cseUrlPrefix + \"/sayhello\",\n          HttpMethod.POST,\n          requestEntity,\n          Student.class);\n    } catch (InvocationException e) {\n      isExcep = true;\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      // Message depended on locale, so just check the short part.\n      if (e.getErrorData() instanceof CommonExceptionData) {\n        // highway decode/encode 'Object' with special type information, got runtime type\n        CommonExceptionData data = (CommonExceptionData) e.getErrorData();\n        TestMgr.check(\"invalid parameters.\", data.getMessage());\n        TestMgr.check(\"sayHello.student.age\",\n            ((Map) ((List<?>) data.getDynamic(\"validateDetail\")).get(0)).get(\"propertyPath\").toString());\n      } else {\n        Map data = (Map) e.getErrorData();\n        TestMgr.check(\"invalid parameters.\", data.get(\"message\").toString());\n        TestMgr.check(\"sayHello.student.age\",\n            ((Map) ((List<?>) data.get(\"validateDetail\")).get(0)).get(\"propertyPath\").toString());\n      }\n    }\n    TestMgr.check(true, isExcep);\n  }\n\n  private static void testValidatorExchangeSuccess(RestOperations template, String cseUrlPrefix) {\n    Student student = new Student();\n    student.setName(\"test\");\n    student.setAge(15);\n    Student result = template.postForObject(cseUrlPrefix + \"sayhello\", student, Student.class);\n    TestMgr.check(\"hello test 15\", result);\n  }\n\n  private static void testSpringMvcDefaultValuesJavaPrimitiveRest(RestOperations template) {\n    String microserviceName = \"jaxrs\";\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/JaxRSDefaultValues/\";\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);\n    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();\n    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);\n\n    //default values with primitive\n    String result = template.postForObject(cseUrlPrefix + \"/javaprimitiveint\", request, String.class);\n    // TODO: form default values support\n//    TestMgr.check(\"Hello 0bobo\", result);\n    TestMgr.check(\"Hello 0null\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivenumber\", request, String.class);\n    TestMgr.check(\"Hello 0.0false\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivestr\", request, String.class);\n    TestMgr.check(\"Hello\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivecomb\", request, String.class);\n    TestMgr.check(\"Hello nullnull\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/allprimitivetypes\", null, String.class);\n    TestMgr.check(\"Hello false,\\0,0,0,0,0,0.0,0.0,null\", result);\n  }\n\n  private static void testSpringMvcDefaultValuesJavaPrimitiveAllTransport(RestOperations template) {\n    String microserviceName = \"jaxrs\";\n    for (String transport : DemoConst.transports) {\n      CategorizedTestCaseRunner.changeTransport(microserviceName, transport);\n\n      String cseUrlPrefix = \"cse://\" + microserviceName + \"/JaxRSDefaultValues/\";\n\n      HttpHeaders headers = new HttpHeaders();\n      headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);\n      MultiValueMap<String, String> map = new LinkedMultiValueMap<>();\n      HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);\n\n      //default values with primitive\n      String result = template.postForObject(cseUrlPrefix + \"/javaprimitiveint\", request, String.class);\n      // TODO: form default values support\n//    TestMgr.check(\"Hello 0bobo\", result);\n      TestMgr.check(\"Hello 0null\", result);\n\n      result = template.postForObject(cseUrlPrefix + \"/javaprimitivenumber\", request, String.class);\n      TestMgr.check(\"Hello 0.0false\", result);\n\n      result = template.postForObject(cseUrlPrefix + \"/javaprimitivestr\", request, String.class);\n      TestMgr.check(\"Hello\", result);\n\n      result = template.postForObject(cseUrlPrefix + \"/javaprimitivecomb\", request, String.class);\n      TestMgr.check(\"Hello nullnull\", result);\n\n      result = template.postForObject(cseUrlPrefix + \"/allprimitivetypes\", null, String.class);\n      TestMgr.check(\"Hello false,\\0,0,0,0,0,0.0,0.0,null\", result);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport org.apache.servicecomb.demo.CodeFirstRestTemplate;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.HttpClientErrorException;\nimport org.springframework.web.client.RestClientException;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class CodeFirstRestTemplateJaxrs extends CodeFirstRestTemplate {\n  @Override\n  protected void testAllTransport(String microserviceName, RestOperations template, String cseUrlPrefix) {\n    testDefaultPath(template, cseUrlPrefix);\n    test404(template);\n\n    super.testAllTransport(microserviceName, template, cseUrlPrefix);\n  }\n\n  private void testDefaultPath(RestOperations template, String cseUrlPrefix) {\n    int result =\n        template.getForObject(cseUrlPrefix.substring(0, cseUrlPrefix.length() - 1), Integer.class);\n    TestMgr.check(100, result);\n  }\n\n  @Override\n  protected void testOnlyRest(String microserviceName, RestOperations template, String cseUrlPrefix) {\n    super.testOnlyRest(microserviceName, template, cseUrlPrefix);\n  }\n\n\n  private void test404(RestOperations template) {\n    HttpClientErrorException exception = null;\n    try {\n      template.getForEntity(\"http://127.0.0.1:8080/aPathNotExist\", String.class);\n      TestMgr.check(\"expect throw but not\", \"\");\n    } catch (RestClientException e) {\n      if (e instanceof HttpClientErrorException) {\n        exception = (HttpClientErrorException) e;\n      }\n    }\n    TestMgr.check(404, exception.getStatusCode().value());\n    TestMgr.check(true, exception.getMessage().contains(\"404 Not Found\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport org.apache.servicecomb.loadbalance.Configuration;\nimport org.apache.servicecomb.loadbalance.ExtensionsFactory;\nimport org.apache.servicecomb.loadbalance.RoundRobinRuleExt;\nimport org.apache.servicecomb.loadbalance.RuleExt;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class CustomLoadbalanceExtensionsFactory implements ExtensionsFactory {\n\n  static class MyCustomRule extends RoundRobinRuleExt {\n\n  }\n\n  @Override\n  public boolean isSupport(String key, String value) {\n    return (Configuration.RULE_STRATEGY_NAME.equals(key) &&\n        \"mycustomrule\".equals(value));\n  }\n\n  @Override\n  public RuleExt createLoadBalancerRule(String ruleName) {\n    return new MyCustomRule();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/MultiErrorCodeServiceClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiRequest;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiResponse200;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiResponse400;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiResponse500;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\nimport io.vertx.core.json.Json;\nimport io.vertx.core.json.JsonObject;\nimport jakarta.ws.rs.core.Response.Status;\n\n@Component\npublic class MultiErrorCodeServiceClient implements CategorizedTestCase {\n  private static final String SERVER = \"cse://jaxrs\";\n\n  private static RestOperations template = RestTemplateBuilder.create();\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testErrorCode();\n    testErrorCodeWithHeader();\n    testErrorCodeWithHeaderJAXRS();\n    testErrorCodeWithHeaderJAXRSUsingRowType();\n    testNoClientErrorCode();\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testErrorCodeWrongType();\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n\n  private static void testErrorCodeWrongType() {\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_JSON);\n    String body = \"{\\\"message\\\":\\\"hello\\\",\\\"code\\\":\\\"wrongType\\\"\";\n    HttpEntity<String> entity = new HttpEntity<>(body, headers);\n    try {\n      template\n          .postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", entity, MultiResponse200.class);\n      TestMgr.fail(\"expect failed.\");\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 400);\n    }\n\n    entity = new HttpEntity<>(null, headers);\n    try {\n      template\n          .postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", entity, MultiResponse200.class);\n      TestMgr.fail(\"expect failed.\");\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 400);\n    }\n\n    // wrong type\n    body = \"{\\\"message\\\":\\\"hello\\\",\\\"code\\\":\\\"200\\\"}\";\n    entity = new HttpEntity<>(body, headers);\n    try {\n      template\n          .postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", entity, MultiResponse200.class);\n      TestMgr.fail(\"expect failed.\");\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 400);\n    }\n  }\n\n  private static void testErrorCode() {\n    MultiRequest request = new MultiRequest();\n\n    request.setCode(200);\n    ResponseEntity<MultiResponse200> result = template\n        .postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse200.class);\n    TestMgr.check(result.getStatusCode().value(), 200);\n    TestMgr.check(result.getBody().getMessage(), \"success result\");\n\n    request.setCode(400);\n    MultiResponse400 t400 = null;\n    try {\n      template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse400.class);\n    } catch (InvocationException e) {\n      t400 = (MultiResponse400) e.getErrorData();\n    }\n    TestMgr.check(t400.getCode(), 400);\n    TestMgr.check(t400.getMessage(), \"bad request\");\n\n    request.setCode(500);\n    MultiResponse500 t500 = null;\n    try {\n      template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCode\", request, MultiResponse400.class);\n    } catch (InvocationException e) {\n      t500 = (MultiResponse500) e.getErrorData();\n    }\n    TestMgr.check(t500.getCode(), 500);\n    TestMgr.check(t500.getMessage(), \"internal error\");\n  }\n\n  private static void testErrorCodeWithHeader() {\n    MultiRequest request = new MultiRequest();\n\n    request.setCode(200);\n    ResponseEntity<MultiResponse200> result = template\n        .postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeader\", request, MultiResponse200.class);\n    TestMgr.check(result.getStatusCode().value(), 200);\n    TestMgr.check(result.getBody().getMessage(), \"success result\");\n    TestMgr.check(result.getBody().getCode(), 200);\n    TestMgr.check(result.getHeaders().getFirst(\"x-code\"), 200);\n\n    request.setCode(400);\n    MultiResponse400 t400 = null;\n    try {\n      template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeader\", request, MultiResponse400.class);\n    } catch (InvocationException e) {\n      t400 = (MultiResponse400) e.getErrorData();\n      TestMgr.check(e.getStatus().getStatusCode(), Status.BAD_REQUEST.getStatusCode());\n    }\n    TestMgr.check(t400.getCode(), 400);\n    TestMgr.check(t400.getMessage(), \"bad request\");\n\n    request.setCode(500);\n    MultiResponse500 t500 = null;\n    try {\n      template.postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeader\", request, MultiResponse400.class);\n    } catch (InvocationException e) {\n      t500 = (MultiResponse500) e.getErrorData();\n      TestMgr.check(e.getStatus().getStatusCode(), Status.INTERNAL_SERVER_ERROR.getStatusCode());\n    }\n    TestMgr.check(t500.getCode(), 500);\n    TestMgr.check(t500.getMessage(), \"internal error\");\n  }\n\n  private static void testErrorCodeWithHeaderJAXRS() {\n    MultiRequest request = new MultiRequest();\n\n    request.setCode(200);\n    request.setMessage(\"success result\");\n    ResponseEntity<MultiResponse200> result = template\n        .postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeaderJAXRS\", request, MultiResponse200.class);\n    TestMgr.check(result.getStatusCode().value(), 200);\n    TestMgr.check(result.getBody().getMessage(), \"success result\");\n    TestMgr.check(result.getBody().getCode(), 200);\n    TestMgr.check(result.getHeaders().getFirst(\"x-code\"), 200);\n\n    request.setCode(400);\n    request.setMessage(\"bad request\");\n    MultiResponse400 t400 = null;\n    try {\n      template\n          .postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeaderJAXRS\", request, MultiResponse400.class);\n    } catch (InvocationException e) {\n      t400 = (MultiResponse400) e.getErrorData();\n      TestMgr.check(e.getStatus().getStatusCode(), Status.BAD_REQUEST.getStatusCode());\n    }\n    TestMgr.check(t400.getCode(), 400);\n    TestMgr.check(t400.getMessage(), \"bad request\");\n\n    request.setCode(500);\n    request.setMessage(\"internal error\");\n    MultiResponse500 t500 = null;\n    try {\n      template\n          .postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeaderJAXRS\", request, MultiResponse400.class);\n    } catch (InvocationException e) {\n      t500 = (MultiResponse500) e.getErrorData();\n      TestMgr.check(e.getStatus().getStatusCode(), Status.INTERNAL_SERVER_ERROR.getStatusCode());\n    }\n    TestMgr.check(t500.getCode(), 500);\n    TestMgr.check(t500.getMessage(), \"internal error\");\n  }\n\n  private static void testErrorCodeWithHeaderJAXRSUsingRowType() {\n    JsonObject requestJson = new JsonObject();\n    requestJson.put(\"code\", 200);\n    requestJson.put(\"message\", \"test message\");\n\n    ResponseEntity<MultiResponse200> result = template\n        .postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeaderJAXRS\", requestJson, MultiResponse200.class);\n    TestMgr.check(result.getStatusCode().value(), 200);\n    TestMgr.check(result.getBody().getMessage(), \"test message\");\n    TestMgr.check(result.getBody().getCode(), 200);\n    TestMgr.check(result.getHeaders().getFirst(\"x-code\"), 200);\n\n    MultiRequest request = new MultiRequest();\n    request.setCode(200);\n    request.setMessage(\"test message\");\n    String stringRequest = Json.encode(request);\n    // wrap request to JsonObject\n    result = template\n        .postForEntity(SERVER + \"/MultiErrorCodeService/errorCodeWithHeaderJAXRS\", new JsonObject(stringRequest),\n            MultiResponse200.class);\n    TestMgr.check(result.getStatusCode().value(), 200);\n    TestMgr.check(result.getBody().getMessage(), \"test message\");\n    TestMgr.check(result.getBody().getCode(), 200);\n    TestMgr.check(result.getHeaders().getFirst(\"x-code\"), 200);\n  }\n\n  private static void testNoClientErrorCode() {\n    JsonObject requestJson = new JsonObject();\n    requestJson.put(\"code\", 200);\n    requestJson.put(\"message\", \"test message\");\n\n    @SuppressWarnings(\"rawtypes\")\n    ResponseEntity<List> listResult = template\n        .postForEntity(SERVER + \"/MultiErrorCodeService/noClientErrorCode\", requestJson, List.class);\n    TestMgr.check(listResult.getStatusCode().value(), 200);\n    Map<?, ?> mapResult =\n        RestObjectMapperFactory.getRestObjectMapper().convertValue(listResult.getBody().get(0), Map.class);\n    TestMgr.check(mapResult.get(\"message\"), \"test message\");\n    TestMgr.check(mapResult.get(\"code\"), 200);\n    TestMgr.check(mapResult.get(\"t200\"), 200);\n\n    try {\n      requestJson.put(\"code\", 400);\n      template\n          .postForEntity(SERVER + \"/MultiErrorCodeService/noClientErrorCode\", requestJson, Object.class);\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 400);\n      mapResult = RestObjectMapperFactory.getRestObjectMapper().convertValue(e.getErrorData(), Map.class);\n      TestMgr.check(mapResult.get(\"message\"), \"test message\");\n      TestMgr.check(mapResult.get(\"code\"), 400);\n      TestMgr.check(mapResult.get(\"t400\"), 400);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/SchemeInterfaceJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport org.springframework.data.domain.Page;\n\npublic interface SchemeInterfaceJaxrs {\n  int add(int a, int b);\n\n  int reduce(int a, int b);\n\n  Page<String> interfaceModel(Page<String> model);\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestClientTimeout.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.validator.Student;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestClientTimeout implements CategorizedTestCase {\n  private static RestOperations template = RestTemplateBuilder.create();\n\n  public void testAllTransport() throws Exception {\n    testClientTimeOut(template);\n  }\n\n  private static void testClientTimeOut(RestOperations template) {\n    String microserviceName = \"jaxrs\";\n\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/clientreqtimeout/\";\n\n    testClientTimeoutSayHi(template, cseUrlPrefix);\n    testClientTimeoutAdd(template, cseUrlPrefix);\n  }\n\n  private static void testClientTimeoutSayHi(RestOperations template, String cseUrlPrefix) {\n    Student student = new Student();\n    student.setName(\"timeout\");\n    student.setAge(30);\n    Student result = template.postForObject(cseUrlPrefix + \"sayhello\", student, Student.class);\n    TestMgr.check(\"hello timeout 30\", result);\n  }\n\n  private static void testClientTimeoutAdd(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"20\");\n    boolean failed = false;\n//    long failures = 0;\n//    ServiceCombServerStats serviceCombServerStats = null;\n    try {\n//      serviceCombServerStats = getServiceCombServerStats();\n//      failures = serviceCombServerStats.getContinuousFailureCount();\n      template.postForObject(cseUrlPrefix + \"add\", params, Integer.class);\n    } catch (InvocationException e) {\n      failed = true;\n      // implement timeout with same error code and message for rest and highway\n      TestMgr.check(408, e.getStatus().getStatusCode());\n      // Request Timeout or Invocation Timeout\n      TestMgr.check(true,\n          e.getErrorData().toString().contains(\"Timeout.\"));\n    }\n\n    TestMgr.check(true, failed);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestCodeFirstJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.io.File;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\n\n@Component\npublic class TestCodeFirstJaxrs implements CategorizedTestCase {\n  interface DownloadInf {\n    ReadStreamPart testDeleteAfterFinished(String name, String content);\n  }\n\n  private static final String SERVICE_NAME = \"jaxrs\";\n\n  private static final String SCHEMA_ID = \"codeFirst\";\n\n  @RpcReference(microserviceName = SERVICE_NAME, schemaId = SCHEMA_ID)\n  private DownloadInf downloadInf;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testCodeFirstJaxrs();\n    testResponseLong();\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n    // test only once\n    testInstanceIsolation();\n  }\n\n  private void testInstanceIsolation() {\n    AtomicInteger e503Business = new AtomicInteger(0);\n    AtomicInteger e503CircuitBreaker = new AtomicInteger(0);\n\n    for (int i = 0; i < 30; i++) {\n      try {\n        InvokerUtils.syncInvoke(SERVICE_NAME, SCHEMA_ID, \"instanceIsolationTest\", null,\n            String.class);\n      } catch (InvocationException e) {\n        if (e.getStatusCode() == 503) {\n          if (\"CommonExceptionData [message=business]\".equals(e.getErrorData().toString())) {\n            e503Business.getAndIncrement();\n          } else if (\"CommonExceptionData [message=instance isolation circuitBreaker is open.]\".equals(\n              e.getErrorData().toString())) {\n            e503CircuitBreaker.getAndIncrement();\n          } else {\n            TestMgr.fail(\"not expected message\");\n          }\n        } else {\n          TestMgr.fail(\"not expected code\");\n        }\n      }\n    }\n    TestMgr.check(true, e503Business.get() >= 10);\n    TestMgr.check(true, e503CircuitBreaker.get() >= 10);\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testDeleteAfterFinished();\n  }\n\n  private void testDeleteAfterFinished() throws Exception {\n    ReadStreamPart part = downloadInf.testDeleteAfterFinished(\"hello\", \"hello content\");\n    TestMgr.check(part.saveAsString().get(), \"hello content\");\n    File systemTempFile = new File(System.getProperty(\"java.io.tmpdir\"));\n    File file = new File(systemTempFile, \"hello\");\n    TestMgr.check(file.exists(), false);\n  }\n\n  private void testResponseLong() {\n    Object result = InvokerUtils.syncInvoke(SERVICE_NAME, SCHEMA_ID, \"responseLong\", null,\n        Object.class);\n    TestMgr.check(result, Long.MAX_VALUE);\n  }\n\n  // invoke CodeFirstJaxrs\n  private void testCodeFirstJaxrs() {\n    Map<String, Object> swaggerArguments = new HashMap<>();\n    Map<String, User> userMap = new HashMap<>();\n    User user = new User();\n    user.setName(\"hello\");\n    userMap.put(\"user\", user);\n    swaggerArguments.put(\"userMap\", userMap);\n    TypeReference<Map<String, User>> type = new TypeReference<Map<String, User>>() {\n    };\n    Map<String, User> result = InvokerUtils.syncInvoke(SERVICE_NAME, SCHEMA_ID, \"testUserMap\", swaggerArguments,\n        type.getType());\n    TestMgr.check(result.get(\"user\").getName(), userMap.get(\"user\").getName());\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestCodeFirstJaxrsReactive.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestCodeFirstJaxrsReactive implements CategorizedTestCase {\n  interface AddOperation {\n    CompletableFuture<Integer> add(int a, int b);\n  }\n\n  @RpcReference(microserviceName = \"jaxrs\", schemaId = \"codeFirst\")\n  AddOperation addOperation;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    final int count = 10;\n    CountDownLatch latch = new CountDownLatch(count);\n    AtomicInteger result = new AtomicInteger(0);\n\n    for (int i = 0; i < count; i++) {\n      new Thread(() -> addOperation.add(1, 2)\n          .whenComplete((r, e) -> addOperation.add(r, r).whenComplete((r1, e1) -> {\n            result.addAndGet(r1);\n            latch.countDown();\n          }))).start();\n    }\n\n    latch.await(3, TimeUnit.SECONDS);\n    TestMgr.check(count * 6, result.get());\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestDynamicConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.config.inject.InjectProperties;\nimport org.apache.servicecomb.config.inject.InjectProperty;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestDynamicConfig implements BootListener {\n  @InjectProperties(prefix = \"jaxrstest.jaxrsclient\")\n  public static class Configuration {\n    /*\n     * 方法的 prefix 属性值 \"override\" 会覆盖标注在类定义的 @InjectProperties\n     * 注解的 prefix 属性值。\n     *\n     * keys属性可以为一个字符串数组，下标越小优先级越高。\n     *\n     * 这里会按照如下顺序的属性名称查找配置属性，直到找到已被配置的配置属性，则停止查找：\n     * 1) jaxrstest.jaxrsclient.override.high\n     * 2) jaxrstest.jaxrsclient.override.low\n     *\n     * 测试用例：\n     * jaxrstest.jaxrsclient.override.high: hello high\n     * jaxrstest.jaxrsclient.override.low: hello low\n     * 预期：\n     * hello high\n     */\n    @InjectProperty(prefix = \"jaxrstest.jaxrsclient.override\", keys = {\"high\", \"low\"})\n    public String strValue;\n\n    /**\n     * keys支持通配符，并在可以在将配置属性注入的时候指定通配符的代入对象。\n     *\n     * 测试用例：\n     * jaxrstest.jaxrsclient.k.value: 3\n     * 预期：\n     * 3\n     */\n    @InjectProperty(keys = \"${key}.value\")\n    public int intValue;\n\n    /**\n     * 通配符的代入对象可以是一个字符串List，优先级遵循数组元素下标越小优先级越高策略。\n     *\n     * 测试用例：\n     * jaxrstest.jaxrsclient.l1-1: 3.0\n     * jaxrstest.jaxrsclient.l1-2: 2.0\n     *\n     * 预期：\n     * 3.0\n     */\n    @InjectProperty(keys = \"${full-list}\")\n    public float floatValue;\n\n    /**\n     * keys属性也支持多个通配符，优先级如下：首先通配符的优先级从左到右递减，\n     * 然后如果通配符被代入List，遵循List中元素index越小优先级越高策略。\n     *\n     * 测试用例：\n     * jaxrstest.jaxrsclient.low-1.a.high-1.b: 1\n     * jaxrstest.jaxrsclient.low-1.a.high-2.b: 2\n     * jaxrstest.jaxrsclient.low-2.a.high-1.b: 3\n     * jaxrstest.jaxrsclient.low-2.a.high-2.b: 4\n     * 预期：\n     * 1\n     */\n    @InjectProperty(keys = \"${low-list}.a.${high-list}.b\")\n    public long longValue;\n\n    /**\n     * 可以通过注解的defaultValue属性指定默认值。如果字段未关联任何配置属性，\n     * 定义的默认值会生效，否则默认值会被覆盖。\n     *\n     * 测试用例：\n     * 预期：\n     * abc\n     */\n    @InjectProperty(defaultValue = \"abc\")\n    public String strDef;\n  }\n\n  @Override\n  public void onAfterRegistry(BootEvent event) {\n    Configuration configuration = SCBEngine.getInstance().getPriorityPropertyManager()\n        .createConfigObject(Configuration.class,\n            \"key\", \"k\",\n            \"low-list\", Arrays.asList(\"low-1\", \"low-2\"),\n            \"high-list\", Arrays.asList(\"high-1\", \"high-2\"),\n            \"full-list\", Arrays.asList(\"l1-1\", \"l1-2\")\n        );\n    TestMgr.check(configuration.strValue, \"hello high\");\n    TestMgr.check(configuration.intValue, 3);\n    TestMgr.check(configuration.floatValue, 3.0);\n    TestMgr.check(configuration.longValue, 1);\n    TestMgr.check(configuration.strDef, \"abc\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestFileUploadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.core.io.FileSystemResource;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@Component\npublic class TestFileUploadSchema implements CategorizedTestCase {\n  @Override\n  public void testRestTransport() throws Exception {\n    testUpload(RestTemplateBuilder.create(), \"servicecomb://jaxrs/fileUpload\");\n  }\n\n  private void testUpload(RestOperations template, String cseUrlPrefix) throws IOException {\n    String file1Content = \"Hello World\";\n    File file1 = File.createTempFile(\"jaxrstest1\", \".txt\");\n    FileUtils.writeStringToFile(file1, file1Content, StandardCharsets.UTF_8, false);\n\n    testFileUpload(template, cseUrlPrefix, file1, file1Content);\n    testFileAndStringUpload(template, cseUrlPrefix, file1, file1Content);\n  }\n\n  private void testFileUpload(RestOperations template, String cseUrlPrefix, File file1, String file1Content)\n      throws IOException {\n    String result1 = template.postForObject(cseUrlPrefix + \"/upload1\", new HttpEntity<>(new HashMap<>()), String.class);\n    TestMgr.check(\"null file\", result1);\n\n    Map<String, Object> map = new HashMap<>();\n    map.put(\"file1\", new FileSystemResource(file1));\n    String file2Content = \"Hello EveryOne\";\n    File file2 = File.createTempFile(\"测试2\", \".txt\");\n    FileUtils.writeStringToFile(file2, file2Content, StandardCharsets.UTF_8, false);\n    map.put(\"file2\", new FileSystemResource(file2));\n    String expect = String.format(\"%s:%s:%s\\n\" + \"%s:%s:%s\",\n        file1.getName(),\n        MediaType.TEXT_PLAIN,\n        file1Content,\n        file2.getName(),\n        MediaType.TEXT_PLAIN,\n        file2Content);\n    String result2 = template.postForObject(cseUrlPrefix + \"/upload1\", new HttpEntity<>(map), String.class);\n    TestMgr.check(expect, result2);\n  }\n\n  private void testFileAndStringUpload(RestOperations template, String cseUrlPrefix, File file1, String file1Content) {\n    Map<String, Object> map = new HashMap<>();\n    String message = \"hi\";\n    map.put(\"file1\", new FileSystemResource(file1));\n    map.put(\"message\", message);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);\n    String expect = String.format(\"%s:%s:%s:%s\",\n        file1.getName(),\n        MediaType.TEXT_PLAIN,\n        file1Content,\n        message);\n    String result = template.postForObject(cseUrlPrefix + \"/upload2\", new HttpEntity<>(map, headers), String.class);\n    TestMgr.check(expect, result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestFormRequestSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\n\n\n@Component\npublic class TestFormRequestSchema implements CategorizedTestCase {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestFormRequestSchema.class);\n\n  private final RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testFormRequestFail();\n    // testFormRequestFail会关闭连接，防止下个测试用例失败，睡眠2s\n    Thread.sleep(2000);\n    testFormRequestSuccess();\n    testFormRequestBufferSize();\n  }\n\n  // formSize is less than default maxFormAttributeSize , success\n  private void testFormRequestSuccess() {\n    try {\n      HttpHeaders headers = new HttpHeaders();\n      headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n      MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();\n      formData.add(\"formData\", \"a\".repeat(512));\n      HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);\n      ResponseEntity<String> responseEntity = restTemplate\n          .postForEntity(\"cse://jaxrs/form/formRequest\", requestEntity, String.class);\n      TestMgr.check(responseEntity.getBody(), \"formRequest success : 512\");\n    } catch (Throwable e) {\n      LOGGER.error(\"testFormRequestSuccess-->\", e);\n      TestMgr.failed(\"\", e);\n    }\n  }\n\n  // formSize is greater than default maxFormAttributeSize , throw exception\n  private void testFormRequestFail() {\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();\n    formData.add(\"formData\", \"a\".repeat(1688));\n    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);\n    try {\n      restTemplate.postForEntity(\"cse://jaxrs/form/formRequest\", requestEntity, String.class);\n      TestMgr.fail(\"Size exceed allowed maximum capacity\");\n    } catch (Throwable e) {\n      TestMgr.check(e.getMessage().contains(\"Internal Server Error\"), true);\n    }\n  }\n\n  private void testFormRequestBufferSize() {\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();\n    // we can not test a situation for form exceed max buffer size, because the netty buffer is very\n    // big and the trunc can always be decoded and cached buffer size is always 0.\n    formData.add(\"F0123456789001234567890012345678900123456789001234567890\"\n            + \"0123456789001234567890012345678900123456789001234567890\", \"a\".repeat(1020)\n        // we can not test a situation for form exceed max buffer size, because the netty buffer is very\n        // big and the trunc can always be decoded and cached buffer size is always 0.\n    );\n    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);\n    try {\n      ResponseEntity<String> responseEntity =\n          restTemplate.postForEntity(\"cse://jaxrs/form/formLongName\", requestEntity, String.class);\n      TestMgr.check(responseEntity.getBody(), \"formRequest success : 1020\");\n    } catch (Throwable e) {\n      LOGGER.error(\"testFormRequestBufferSize-->\", e);\n      TestMgr.failed(\"\", e);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestQueryParamSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestQueryParamSchema implements CategorizedTestCase {\n  public interface QueryParamService {\n    String testQueryEncode(String param);\n  }\n\n  private final RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @RpcReference(microserviceName = \"jaxrs\", schemaId = \"QueryParamSchema\")\n  private QueryParamService queryParamService;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testQueryParamEncodingPlus();\n  }\n\n  private void testQueryParamEncodingPlus() {\n    // should encode +\n    TestMgr.check(\"a+b\",\n        restTemplate.getForObject(\"servicecomb://jaxrs/queryParam/testQueryEncode?param={1}\", String.class, \"a+b\"));\n    // if not encoded, + should be blank\n    TestMgr.check(\"a b\",\n        restTemplate.getForObject(\"servicecomb://jaxrs/queryParam/testQueryEncode?param=a+b\", String.class));\n\n    // rpc should encode\n    TestMgr.check(\"a+b\", queryParamService.testQueryEncode(\"a+b\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestQueryParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestQueryParamWithListSchema implements CategorizedTestCase {\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testMulti();\n    testCSV();\n    testSSV();\n    testPipes();\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testMultiRest();\n    testCSVRest();\n    testSSVRest();\n    testPipesRest();\n  }\n\n  @Override\n  // highway do not handle empty/default/null\n  public void testHighwayTransport() throws Exception {\n    testMultiHighway();\n    testCSVHighway();\n    testSSVHighway();\n    testPipesHighway();\n  }\n\n  private void testCSVHighway() {\n    TestMgr.check(\"null\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListCSV?\", String.class));\n  }\n\n  private void testCSVRest() {\n    TestMgr.check(\"0:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListCSV?\", String.class));\n  }\n\n  private void testSSV() {\n    TestMgr.check(\"1:[1%202]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?queryList=1%202\", String.class));\n    TestMgr.check(\"1:[%20]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?queryList=%20\", String.class));\n    TestMgr.check(\"1:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?queryList=\", String.class));\n\n    TestMgr.check(\"2:[1, 2]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?queryList={1}\", String.class, \"1 2\"));\n    TestMgr.check(\"2:[, ]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?queryList={1}\", String.class, \" \"));\n    TestMgr.check(\"1:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?queryList=\", String.class));\n  }\n\n  private void testPipesHighway() {\n    TestMgr.check(\"null\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListPIPES?\", String.class));\n  }\n\n  private void testPipesRest() {\n    TestMgr.check(\"0:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListPIPES?\", String.class));\n  }\n\n  private void testPipes() {\n    TestMgr.check(\"2:[1, 2]\",\n        restTemplate\n            .getForObject(\"cse://jaxrs/queryList/queryListPIPES?queryList={1}\", String.class, \"1|2\"));\n    TestMgr.check(\"2:[, ]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListPIPES?queryList={1}\", String.class, \"|\"));\n    TestMgr.check(\"1:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListPIPES?queryList=\", String.class));\n  }\n\n  private void testSSVHighway() {\n    TestMgr.check(\"null\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?\", String.class));\n  }\n\n  private void testSSVRest() {\n    TestMgr.check(\"0:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListSSV?\", String.class));\n  }\n\n  private void testCSV() {\n    TestMgr.check(\"2:[1, 2]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListCSV?queryList=1,2\", String.class));\n    TestMgr.check(\"2:[, ]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListCSV?queryList=,\", String.class));\n    TestMgr.check(\"1:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListCSV?queryList=\", String.class));\n  }\n\n  private void testMultiHighway() {\n    TestMgr.check(\"null\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListMULTI?\", String.class));\n  }\n\n  private void testMultiRest() {\n    TestMgr.check(\"0:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListMULTI?\", String.class));\n  }\n\n  private void testMulti() {\n    TestMgr.check(\"2:[1, 2]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListMULTI?queryList=1&queryList=2\", String.class));\n    TestMgr.check(\"2:[, ]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListMULTI?queryList=&queryList=\", String.class));\n    TestMgr.check(\"1:[]\",\n        restTemplate.getForObject(\"cse://jaxrs/queryList/queryListMULTI?queryList=\", String.class));\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestReactiveSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestReactiveSchema implements CategorizedTestCase {\n  @SuppressWarnings(\"rawtypes\")\n  public void testRestTransport() throws Exception {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    try {\n      restTemplate.getForObject(\"cse://jaxrs/reactive/testSyncInvokeInEventLoop?a=1&b=2\", int.class);\n      TestMgr.check(true, false);\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 500);\n      TestMgr.check(((Map) e.getErrorData()).get(\"message\"),\n          \"Unexpected exception when processing jaxrs.ReactiveSchema.testSyncInvokeInEventLoop. \"\n              + \"Can not execute sync logic in event loop.\");\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestSchemeInterfaceJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.PageImpl;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestSchemeInterfaceJaxrs implements CategorizedTestCase {\n  @RpcReference(schemaId = \"SchemeInterfaceJaxrs\", microserviceName = \"jaxrs\")\n  private SchemeInterfaceJaxrs jaxrs;\n\n  public void testRestTransport() throws Exception {\n    List<String> contents = new ArrayList<>();\n    contents.add(\"hello\");\n    Sort sort = Sort.by(new String[0]);\n    Pageable pageable = PageRequest.of(1, 10, sort);\n    Page<String> pages = new PageImpl<>(contents, pageable, 1);\n    Page<String> result = jaxrs.interfaceModel(pages);\n    TestMgr.check(\"hello\", result.stream().findFirst().get());\n  }\n\n  public void testAllTransport() throws Exception {\n    TestMgr.check(3, jaxrs.add(1, 2));\n    TestMgr.check(0, jaxrs.add(-1, 1));\n\n    try {\n      jaxrs.reduce(1, 3);\n      TestMgr.failed(\"should throw exception\", new Exception());\n    } catch (InvocationException e) {\n      TestMgr.check(\n          \"Consumer method org.apache.servicecomb.demo.jaxrs.client.SchemeInterfaceJaxrs:reduce \"\n              + \"not exist in contract, microserviceName=jaxrs, schemaId=SchemeInterfaceJaxrs.\",\n          ((CommonExceptionData) e.getError()).getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamPojoClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.beanParam;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayInputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class BeanParamPojoClient implements CategorizedTestCase {\n  private BeanParamTestServiceIntf beanParamTestServiceIntf;\n\n  public BeanParamPojoClient() {\n    beanParamTestServiceIntf = Invoker.createProxy(\"jaxrs\", \"beanParamTest\", BeanParamTestServiceIntf.class);\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testBeanParam();\n    testUpload();\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testBeanParam();\n  }\n\n  private void testBeanParam() {\n    String result = beanParamTestServiceIntf.beanParameterTest(\"querySwaggerValue\", 2, \"pathSwaggerValue\", 10, \"extra\");\n    TestMgr.check(\n        \"invocationContextConsistency=true|testBeanParameter=TestBeanParameter{queryStr='querySwaggerValue', headerInt=2, \"\n            + \"pathStr='pathSwaggerValue', cookieLong=10}|extraQuery=extra\",\n        result);\n  }\n\n  private void testUpload() {\n    BufferedInputStream bufferedInputStream0 = new BufferedInputStream(new ByteArrayInputStream(\"up0\".getBytes(StandardCharsets.UTF_8)));\n    BufferedInputStream bufferedInputStream1 = new BufferedInputStream(new ByteArrayInputStream(\"up1\".getBytes(StandardCharsets.UTF_8)));\n    BufferedInputStream bufferedInputStream2 = new BufferedInputStream(new ByteArrayInputStream(\"up2\".getBytes(StandardCharsets.UTF_8)));\n\n    String result = beanParamTestServiceIntf.beanParameterTestUpload(\n        bufferedInputStream0, \"queryTest\", bufferedInputStream1, bufferedInputStream2, \"ex\");\n    TestMgr.check(\n        \"testBeanParameter=TestBeanParameterWithUpload{queryStr='queryTest'}|extraQuery=ex|up0=up0|up1=up1|up2=up2\",\n        result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamRestTemplateClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.beanParam;\n\nimport java.io.BufferedInputStream;\nimport java.io.ByteArrayInputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.CseHttpEntity;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class BeanParamRestTemplateClient implements CategorizedTestCase {\n  RestOperations restTemplate;\n\n  public BeanParamRestTemplateClient() {\n    restTemplate = RestTemplateBuilder.create();\n  }\n\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testBeanParam();\n    testUpload();\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testBeanParam();\n  }\n\n  private void testBeanParam() {\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"Cookie\", \"cookieSwaggerLong=11\");\n    headers.add(\"headerSwaggerInt\", \"2\");\n    HttpEntity<Object> requestEntity1 = new CseHttpEntity<>(headers);\n    ResponseEntity<String> result = restTemplate.exchange(\n        \"cse://jaxrs/beanParamTest/pathSwaggerValue/simple?querySwaggerStr=querySwaggerValue&extraQuery=extra\",\n        HttpMethod.GET,\n        requestEntity1,\n        String.class);\n    TestMgr.check(\n        \"invocationContextConsistency=true|testBeanParameter=TestBeanParameter{queryStr='querySwaggerValue', headerInt=2, \"\n            + \"pathStr='pathSwaggerValue', cookieLong=11}|extraQuery=extra\",\n        result.getBody());\n  }\n\n  private void testUpload() {\n    BufferedInputStream bufferedInputStream0 = new BufferedInputStream(\n        new ByteArrayInputStream(\"up0\".getBytes(StandardCharsets.UTF_8)));\n    BufferedInputStream bufferedInputStream1 = new BufferedInputStream(\n        new ByteArrayInputStream(\"up1\".getBytes(StandardCharsets.UTF_8)));\n    BufferedInputStream bufferedInputStream2 = new BufferedInputStream(\n        new ByteArrayInputStream(\"up2\".getBytes(StandardCharsets.UTF_8)));\n\n    HashMap<String, Object> formData = new HashMap<>();\n    formData.put(\"up0\", bufferedInputStream0);\n    formData.put(\"up1\", bufferedInputStream1);\n    formData.put(\"up2\", bufferedInputStream2);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.MULTIPART_FORM_DATA);\n    HttpEntity<Map<String, Object>> entity = new HttpEntity<>(formData, headers);\n\n    String result = restTemplate.postForObject(\"cse://jaxrs/beanParamTest/upload?query=fromTemplate&extraQuery=ex\",\n        entity,\n        String.class);\n    TestMgr.check(\n        \"testBeanParameter=TestBeanParameterWithUpload{queryStr='fromTemplate'}|extraQuery=ex|up0=up0|up1=up1|up2=up2\",\n        result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamTestServiceIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.beanParam;\n\nimport java.io.InputStream;\n\npublic interface BeanParamTestServiceIntf {\n  String beanParameterTest(String querySwaggerStr, Integer headerSwaggerInt, String pathSwaggerStr,\n      long cookieSwaggerLong, String extraQuery);\n\n  String beanParameterTestUpload(InputStream up0, String query, InputStream up1, InputStream up2, String extraQuery);\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/injectBean/TestInjectBeanSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.injectBean;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestInjectBeanSchema implements CategorizedTestCase {\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @Override\n  public void testAllTransport() throws Exception {\n    boolean result = restTemplate.getForObject(\"cse://jaxrs/injectSet\", boolean.class);\n    TestMgr.check(true, result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.pojoDefault;\n\npublic class DefaultModel {\n  private int index;\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.pojoDefault;\n\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.jaxrs.server.pojoDefault.DefaultResponseModel;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.web.client.RestOperations;\n\npublic class DefaultModelServiceClient {\n  private static RestOperations template = RestTemplateBuilder.create();\n\n  private static String urlPrefix = \"cse://jaxrs/DefaultModelService\";\n\n  public static void run() {\n    // highway do not support this feature\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.jaxrs\", \"rest\");\n    testDefaultModelService();\n  }\n\n  private static void testDefaultModelService() {\n    DefaultModel model = new DefaultModel();\n    model.setIndex(400);\n    DefaultResponseModel result = template.postForObject(urlPrefix + \"/model\", model, DefaultResponseModel.class);\n    TestMgr.check(result.getAge(), 200);\n    TestMgr.check(result.getIndex(), 400);\n    TestMgr.check(result.getName(), \"World\");\n    TestMgr.check(result.getDesc(), null);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.client.validation;\n\nimport java.util.ArrayList;\n\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.jaxrs.server.validation.ValidationModel;\nimport org.apache.servicecomb.demo.validator.Teacher;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ValidationServiceClient {\n  private static RestOperations template = RestTemplateBuilder.create();\n\n  private static String urlPrefix = \"cse://jaxrs/ValidationService\";\n\n  public static void run() {\n    // highway do not support this feature\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.jaxrs\", \"rest\");\n    testValidation();\n  }\n\n  private static void testValidation() {\n    ValidationModel model = new ValidationModel();\n    model.setAge(20);\n    model.setMembers(new ArrayList<>());\n    model.setName(\"name\");\n    ValidationModel result = template.postForObject(urlPrefix + \"/validate\", model, ValidationModel.class);\n    TestMgr.check(result.getAge(), 20);\n    TestMgr.check(result.getName(), \"name\");\n    TestMgr.check(result.getMembers().size(), 0);\n\n    try {\n      model.setAge(null);\n      template.postForObject(urlPrefix + \"/validate\", model, ValidationModel.class);\n      TestMgr.check(false, true);\n    } catch (InvocationException e) {\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      TestMgr.check(e.getErrorData().toString().contains(\"propertyPath=errorCode.request.age\"), true);\n    }\n\n    try {\n      model.setAge(20);\n      model.setMembers(null);\n      template.postForObject(urlPrefix + \"/validate\", model, ValidationModel.class);\n      TestMgr.check(false, true);\n    } catch (InvocationException e) {\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      TestMgr.check(e.getErrorData().toString().contains(\"propertyPath=errorCode.request.members\"), true);\n    }\n\n    try {\n      template.postForObject(urlPrefix + \"/validate\", null, ValidationModel.class);\n      TestMgr.check(false, true);\n    } catch (InvocationException e) {\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      TestMgr.check(e.getErrorData().toString().contains(\"propertyPath=errorCode.request\"), true);\n    }\n\n    String strResult = template.getForObject(urlPrefix + \"/validateQuery?name=a\", String.class);\n    TestMgr.check(strResult, \"a\");\n\n    try {\n      template.getForObject(urlPrefix + \"/validateQuery\", String.class);\n      TestMgr.check(false, true);\n    } catch (InvocationException e) {\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());\n      TestMgr.check(((CommonExceptionData) e.getErrorData()).getMessage().contains(\"Parameter is not valid\"), true);\n    }\n\n    Teacher teacher = new Teacher();\n    teacher.setName(\"teacher\");\n    teacher.setAge(\"20\");\n    Teacher response = template.postForObject(urlPrefix + \"/sayTeacherInfo\", teacher, Teacher.class);\n    TestMgr.check(response.getName(), \"teacher\");\n\n    try {\n      teacher = new Teacher();\n      teacher.setAge(\"20\");\n      template.postForObject(urlPrefix + \"/sayTeacherInfo\", teacher, Teacher.class);\n      TestMgr.fail(\"Name should not empty\");\n    } catch (InvocationException e) {\n      TestMgr.check(400, e.getStatus().getStatusCode());\n      TestMgr.check(e.getErrorData().toString().contains(\"must not be blank\"), true);\n    }\n\n    // jax-rs body default required = false\n    response = template.postForObject(urlPrefix + \"/sayTeacherInfo\", null, Teacher.class);\n    TestMgr.check(null, response);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.pojoDefault;\n\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\nimport jakarta.validation.constraints.Null;\n\npublic class DefaultResponseModel {\n  @Min(20)\n  @Max(2000)\n  @Null\n  private Integer age = 200;\n\n  @Min(2)\n  @Max(30)\n  @Null\n  private String name = \"World\";\n\n  private int index;\n\n  private String desc = \"Hello\";\n\n  public Integer getAge() {\n    return age;\n  }\n\n  public void setAge(Integer age) {\n    this.age = age;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  public String getDesc() {\n    return desc;\n  }\n\n  public void setDesc(String desc) {\n    this.desc = desc;\n  }\n\n  @Override\n  public String toString() {\n    return \"index=\" + index + \";name=\" + name + \";age=\" + age;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/main/resources/microservice.yaml",
    "content": "﻿## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: jaxrstest\n    name: jaxrsClient\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n      enableSwaggerRegistration: true\n\n  matchGroup:\n    instanceIsolationTest: |\n      matches:\n        - apiPath:\n            prefix: \"/codeFirstJaxrs/instanceIsolationTest\"\n  instanceIsolation:\n    instanceIsolationTest: |\n      minimumNumberOfCalls: 10\n      slidingWindowSize: 20\n      slidingWindowType: COUNT_BASED\n      failureRateThreshold: 50\n      slowCallRateThreshold: 100\n      slowCallDurationThreshold: 3000\n      waitDurationInOpenState: 200\n      permittedNumberOfCallsInHalfOpenState: 10\n\n  request:\n    timeout: 30000\n    jaxrs:\n      timeout: 30000\n      clientreqtimeout:\n        timeout: 30000\n        sayHello:\n          timeout: 30000\n        add:\n          timeout: 1000\n\n  invocation:\n    timeout:\n      check:\n        enabled: false\n\n  # use service center to find schema info\n  openAPI:\n    registry:\n      # enable service center OpenAPI registry, and need set enableSwaggerRegistration: true\n      registry:\n        enabled: true\n      # disable instance OpenAPI registry\n      instance:\n        enabled: false\n\n  # test configurations. you can choose any implementation. default using local.\n\n  # using nacos configuration\n  #  nacos:\n  #    serverAddr: http://127.0.0.1:8848\n  #    group: jaxrstest\n  #    dataId: jaxrsclient\n  #    namespace: public\n  #    contentType: properties # can be properties, yaml, raw. If using raw, property [group].[dataId]=value.\n  #    addPrefix: false # if true [group].[dataId] will added as properties/yaml items prefix. Will not influence raw.\n\n  # for integration test not install any config server\njaxrstest:\n  jaxrsclient:\n    override.high: hello high\n    override.low: hello low\n    k.value: 3\n    l1-1: 3.0\n    l1-2: 2.0\n    low-1.a.high-1.b: 1\n    low-1.a.high-2.b: 2\n    low-2.a.high-1.b: 3\n    low-2.a.high-2.b: 4\n\n# test configurations.\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-client/src/test/java/org/apache/servicecomb/demo/jaxrs/JaxrsIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = JaxrsClient.class)\npublic class JaxrsIT {\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    JaxrsClient.run();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-jaxrs</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>jaxrs-server</artifactId>\n  <name>Java Chassis::Demo::JAXRS::Server</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <!-- This is a demo, user can choose any implementation you want -->\n    <dependency>\n      <groupId>org.glassfish.jersey.core</groupId>\n      <artifactId>jersey-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.glassfish.jersey.core</groupId>\n      <artifactId>jersey-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-validator</artifactId>\n    </dependency>\n  </dependencies>\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.jaxrs.JaxrsServer</demo.main>\n  </properties>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/JaxrsServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;\nimport org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class JaxrsServer {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(JaxrsServer.class).web(WebApplicationType.NONE).run(args);\n\n    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());\n    RestObjectMapperFactory.setConsumerWriterMapper(new RestObjectMapperWithStringMapperNotWriteNull());\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;\nimport org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.Parameters;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.vertx.core.json.JsonObject;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.Consumes;\nimport jakarta.ws.rs.CookieParam;\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\n@RestSchema(schemaId = \"codeFirst\")\n@Path(\"/codeFirstJaxrs\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class CodeFirstJaxrs {\n  @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = User.class)), description = \"\",\n      headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n          @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n  @Path(\"/cseResponse\")\n  @GET\n  public Response cseResponse(InvocationContext c1) {\n    Response response = Response.createSuccess(Status.ACCEPTED, new User());\n    response.setHeader(\"h1\", \"h1v \" + c1.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    InvocationContext c2 = ContextUtils.getInvocationContext();\n    response.setHeader(\"h2\", \"h2v \" + c2.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    return response;\n  }\n\n  @Path(\"/testUserMap\")\n  @POST\n  public Map<String, User> testUserMap(Map<String, User> userMap) {\n    return userMap;\n  }\n\n  @Path(\"/textPlain\")\n  @POST\n  @Consumes(MediaType.TEXT_PLAIN)\n  public String textPlain(String body) {\n    return body;\n  }\n\n  @Path(\"/bytes\")\n  @POST\n  public byte[] bytes(byte[] input) {\n    input[0] = (byte) (input[0] + 1);\n    return input;\n  }\n\n  @Path(\"/addDate\")\n  @POST\n  public Date addDate(@FormParam(\"date\") Date date, @QueryParam(\"seconds\") long seconds) {\n    return new Date(date.getTime() + seconds * 1000);\n  }\n\n  @GET\n  public int defaultPath() {\n    return 100;\n  }\n\n  @Path(\"/add\")\n  @POST\n  public int add(@FormParam(\"a\") int a, @FormParam(\"b\") int b) {\n    return a + b;\n  }\n\n  @Path(\"/reduce\")\n  @GET\n  @Parameters({@Parameter(name = \"a\", schema = @Schema(implementation = int.class), in = ParameterIn.QUERY)})\n  public int reduce(HttpServletRequest request, @CookieParam(\"b\") int b) {\n    int a = Integer.parseInt(request.getParameter(\"a\"));\n    return a - b;\n  }\n\n  @Path(\"/sayhello\")\n  @POST\n  public Person sayHello(Person user) {\n    user.setName(\"hello \" + user.getName());\n    return user;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Path(\"/testrawjson\")\n  @POST\n  public String testRawJsonString(String jsonInput) {\n    Map<String, String> person;\n    try {\n      person = RestObjectMapperFactory.getRestObjectMapper()\n          .readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);\n    } catch (Exception e) {\n      e.printStackTrace();\n      return null;\n    }\n    return \"hello \" + person.get(\"name\");\n  }\n\n  @Path(\"/saysomething\")\n  @POST\n  public String saySomething(@HeaderParam(\"prefix\") String prefix, Person user) {\n    return prefix + \" \" + user.getName();\n  }\n\n  @Path(\"/sayhi/{name}\")\n  @PUT\n  public String sayHi(@PathParam(\"name\") String name) {\n    ContextUtils.getInvocationContext().setStatus(202);\n    return name + \" sayhi\";\n  }\n\n  @Path(\"/sayhi/{name}/v2\")\n  @PUT\n  public String sayHi2(@PathParam(\"name\") String name) {\n    return name + \" sayhi 2\";\n  }\n\n  @Path(\"/istrue\")\n  @GET\n  public boolean isTrue() {\n    return true;\n  }\n\n  @Path(\"/addstring\")\n  @DELETE\n  @Produces(MediaType.TEXT_PLAIN)\n  public String addString(@QueryParam(\"s\") List<String> s) {\n    StringBuilder result = new StringBuilder();\n    for (String x : s) {\n      result.append(x);\n    }\n    return result.toString();\n  }\n\n  @Path(\"/ignore\")\n  @POST\n  public OutputModelForTestIgnore testModelWithIgnoreField(InputModelForTestIgnore input) {\n    return new OutputModelForTestIgnore(\"output_id\", input.getInputId(), input.getContent(), input.getInputObject(),\n        input.getInputJsonObject(), input.getInputIgnoreInterface(),\n        new Person(\"outputSomeone\"), new JsonObject(\"{\\\"OutputJsonKey\\\" : \\\"OutputJsonValue\\\"}\"), () -> {\n    });\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Path(\"/rawJsonAnnotation\")\n  @POST\n  public String testRawJsonAnnotation(@RawJsonRequestBody String jsonInput) {\n    Map<String, String> person;\n    try {\n      person = RestObjectMapperFactory.getRestObjectMapper()\n          .readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);\n    } catch (Exception e) {\n      e.printStackTrace();\n      return null;\n    }\n    return \"hello \" + person.get(\"name\");\n  }\n\n  @Path(\"/traceId\")\n  @GET\n  public String getTraceId() {\n    return ContextUtils.getInvocationContext().getContext(CoreConst.TRACE_ID_NAME);\n  }\n\n  @GET\n  @Path(\"/responseLong\")\n  @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = Object.class)), description = \"\")\n  public Response responseLong() {\n    return Response.createSuccess(Long.MAX_VALUE);\n  }\n\n  @Path(\"/download/testDeleteAfterFinished\")\n  @GET\n  public Part testDeleteAfterFinished(@QueryParam(\"name\") String name, @QueryParam(\"content\") String content)\n      throws IOException {\n    File file = createTempFile(name, content);\n\n    return new FilePart(null, file)\n        .setDeleteAfterFinished(true)\n        .setSubmittedFileName(name);\n  }\n\n  @Path(\"/instanceIsolationTest\")\n  @GET\n  public String instanceIsolationTest() {\n    throw new InvocationException(503, \"\", \"business\");\n  }\n\n  private File createTempFile(String name, String content) throws IOException {\n    File systemTempFile = new File(System.getProperty(\"java.io.tmpdir\"));\n    File file = new File(systemTempFile, name);\n    FileUtils.write(file, content, StandardCharsets.UTF_8, false);\n    return file;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/ComputeImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.Parameters;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.DELETE;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.Context;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"compute\")\n@Path(\"/compute\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class ComputeImpl {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ComputeImpl.class);\n\n  @Path(\"/add\")\n  @POST\n  public int add(@FormParam(\"a\") int a, @FormParam(\"b\") int b) {\n    return a + b;\n  }\n\n  @Path(\"/reduce\")\n  @GET\n  @Parameters(value = {@Parameter(in = ParameterIn.QUERY, name = \"a\", schema = @Schema(implementation = int.class)),\n      @Parameter(in = ParameterIn.QUERY, name = \"b\", schema = @Schema(implementation = int.class))})\n  public int reduce(@Context HttpServletRequest request) {\n    int a = Integer.parseInt(request.getParameter(\"a\"));\n    int b = Integer.parseInt(request.getParameter(\"b\"));\n    return a - b;\n  }\n\n  @Path(\"/sayhello\")\n  @POST\n  public Person sayHello(Person user) {\n    user.setName(\"hello \" + user.getName());\n    return user;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Path(\"/testrawjson\")\n  @POST\n  public String testRawJsonString(String jsonInput) {\n    Map<String, String> person;\n    try {\n      person = RestObjectMapperFactory.getRestObjectMapper()\n          .readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);\n    } catch (Exception e) {\n      e.printStackTrace();\n      return null;\n    }\n    return \"hello \" + person.get(\"name\");\n  }\n\n  @Path(\"/saysomething\")\n  @POST\n  public String saySomething(@HeaderParam(\"prefix\") String prefix, Person user) {\n    return prefix + \" \" + user.getName();\n  }\n\n  @Path(\"/sayhi/{name}\")\n  @PUT\n  public void sayHi(@PathParam(\"name\") String name) {\n    LOGGER.info(name + \" sayhi\");\n    ContextUtils.getInvocationContext().setStatus(202);\n  }\n\n  @Path(\"/sayhi/{name}/v2\")\n  @PUT\n  public void sayHi2(@PathParam(\"name\") String name) {\n    LOGGER.info(name + \" sayhi 2\");\n  }\n\n  @Path(\"/sayhei\")\n  @DELETE\n  public void sayHei(@QueryParam(\"name\") String name) {\n    LOGGER.info(name + \" sayhei\");\n  }\n\n  @Path(\"/istrue\")\n  @GET\n  public boolean isTrue() {\n    return true;\n  }\n\n  @Path(\"/addstring\")\n  @DELETE\n  @Produces(MediaType.TEXT_PLAIN)\n  public String addString(@QueryParam(\"s\") String[] s) {\n    StringBuilder result = new StringBuilder();\n    for (String x : s) {\n      result.append(x);\n    }\n    return result.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FileUploadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\n/**\n * Test and illustrate JaxRS uploads.\n *\n * Use @FormParam to annotate a multipart/form-data item.\n */\n@RestSchema(schemaId = \"FileUploadSchema\")\n@Path(\"/fileUpload\")\npublic class FileUploadSchema {\n  @Path(\"/upload1\")\n  @POST\n  @Produces(MediaType.TEXT_PLAIN)\n  public String fileUpload1(@FormParam(\"file1\") Part file1, @FormParam(\"file2\") Part file2) throws IOException {\n    if (file1 == null || file2 == null) {\n      return \"null file\";\n    }\n    try (InputStream is1 = file1.getInputStream(); InputStream is2 = file2.getInputStream()) {\n      String content1 = IOUtils.toString(is1, StandardCharsets.UTF_8);\n      String content2 = IOUtils.toString(is2, StandardCharsets.UTF_8);\n      return String.format(\"%s:%s:%s\\n\" + \"%s:%s:%s\",\n          file1.getSubmittedFileName(),\n          file1.getContentType(),\n          content1,\n          file2.getSubmittedFileName(),\n          file2.getContentType(),\n          content2);\n    }\n  }\n\n  @Path(\"/upload2\")\n  @POST\n  @Produces(MediaType.TEXT_PLAIN)\n  public String fileUpload2(@FormParam(\"file1\") Part file1, @FormParam(\"message\") String message) throws IOException {\n    try (InputStream is1 = file1.getInputStream()) {\n      String content1 = IOUtils.toString(is1, StandardCharsets.UTF_8);\n      return String.format(\"%s:%s:%s:%s\",\n          file1.getSubmittedFileName(),\n          file1.getContentType(),\n          content1,\n          message);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequestSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\nimport jakarta.ws.rs.Consumes;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"FormRequestSchema\")\n@Path(\"/form\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class FormRequestSchema {\n\n  @Path(\"/formRequest\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String formRequestSuccess(@FormParam(\"formData\") String formData) throws Exception {\n    return \"formRequest success : \" + formData.length();\n  }\n\n  @Path(\"/formLongName\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String formLongName(@FormParam(\"F0123456789001234567890012345678900123456789001234567890\"\n      + \"0123456789001234567890012345678900123456789001234567890\") String formData) throws Exception {\n    return \"formRequest success : \" + formData.length();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\nimport jakarta.validation.constraints.NotNull;\nimport jakarta.validation.constraints.Size;\nimport jakarta.ws.rs.Consumes;\nimport jakarta.ws.rs.DefaultValue;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"JaxRSDefaultValues\")\n@Path(\"/JaxRSDefaultValues\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class JaxRSDefaultValues {\n\n  @Path(\"/form\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String form(@DefaultValue(\"20\") @FormParam(\"a\") int a, @DefaultValue(\"bobo\") @FormParam(\"b\") String b) {\n    return \"Hello \" + a + b;\n  }\n\n  @Path(\"/header\")\n  @POST\n  public String header(@DefaultValue(\"20\") @HeaderParam(\"a\") int a, @DefaultValue(\"bobo\") @HeaderParam(\"b\") String b,\n      @DefaultValue(\"30\") @HeaderParam(\"c\") Integer c) {\n    return \"Hello \" + a + b + c;\n  }\n\n  @Path(\"/query\")\n  @GET\n  public String query(@DefaultValue(\"20\") @QueryParam(\"a\") int a, @DefaultValue(\"bobo\") @QueryParam(\"b\") String b,\n      @DefaultValue(\"40\") @QueryParam(\"c\") Integer c, @QueryParam(\"d\") int d) {\n    return \"Hello \" + a + b + c + d;\n  }\n\n  @Path(\"/query2\")\n  @GET\n  public String query2(@QueryParam(\"e\") int e, @DefaultValue(\"20\") @QueryParam(\"a\") int a,\n      @DefaultValue(\"bobo\") @QueryParam(\"b\") String b,\n      @DefaultValue(\"40\") @QueryParam(\"c\") Integer c, @Min(value = 20) @Max(value = 30) @QueryParam(\"d\") int d) {\n    return \"Hello \" + a + b + c + d + e;\n  }\n\n  @Path(\"/query3\")\n  @GET\n  public String query3(@QueryParam(\"a\") @Min(value = 20) int a, @QueryParam(\"b\") String b) {\n    return \"Hello \" + a + b;\n  }\n\n  @Path(\"/packages\")\n  @GET\n  public String queryPackages(HttpServletRequest httpRequest,\n      @Max(value = 2147483647L) @Min(value = -1L) @NotNull @QueryParam(\"pageNo\") Integer pageNo,\n      @Max(value = 2147483647L) @Min(value = -1L) @NotNull @QueryParam(\"pageSize\") Integer pageSize,\n      @Size(max = 64, min = 0) @QueryParam(\"packageName\") String packageName,\n      @Max(value = 127L) @Min(value = 0L) @QueryParam(\"packageType\") Integer packageType,\n      @Max(value = 2147483647L) @Min(value = 1L) @QueryParam(\"roleID\") Integer roleID,\n      @Max(value = 2147483647L) @Min(value = 1L) @QueryParam(\"categoryID\") Integer categoryID,\n      @Max(value = 127L) @Min(value = 0L) @QueryParam(\"appType\") @DefaultValue(\"1\") Integer appType,\n      @Max(value = 2L) @Min(value = 1L) @QueryParam(\"packageScope\") Integer packageScope) {\n    return \"\" + appType;\n  }\n\n  @Path(\"/javaprimitiveint\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String jaxRsJavaPrimitiveInt(@FormParam(\"a\") int a, @DefaultValue(\"bobo\") @FormParam(\"b\") String b) {\n    return \"Hello \" + a + b;\n  }\n\n  @Path(\"/javaprimitivenumber\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String jaxRsJavaPrimitiveNumber(@QueryParam(\"a\") float a, @QueryParam(\"b\") boolean b) {\n    return \"Hello \" + a + b;\n  }\n\n  @Path(\"/javaprimitivestr\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String jaxRsJavaPrimitiveStr(@FormParam(\"b\") int b, @FormParam(\"a\") String a) {\n    if (a == null || a.equals(\"\")) {\n      return \"Hello\";\n    }\n    return \"Hello \" + b + a;\n  }\n\n  @Path(\"/javaprimitivecomb\")\n  @POST\n  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)\n  public String jaxRsJavaPrimitiveCombnation(@QueryParam(\"a\") Integer a, @QueryParam(\"b\") Float b) {\n    return \"Hello \" + a + b;\n  }\n\n  @Path(\"/allprimitivetypes\")\n  @POST\n  public String allprimitivetypes(@QueryParam(\"pBoolean\") boolean pBoolean,\n      @QueryParam(\"pChar\") char pChar,\n      @QueryParam(\"pByte\") byte pByte,\n      @QueryParam(\"pShort\") short pShort,\n      @QueryParam(\"pInt\") int pInt,\n      @QueryParam(\"pLong\") long pLong,\n      @QueryParam(\"pFloat\") float pFloat,\n      @QueryParam(\"pDouble\") double pDouble,\n      @QueryParam(\"pDoubleWrap\") Double pDoubleWrap) {\n    return \"Hello \" + pBoolean + \",\"\n        + pChar + \",\"\n        + pByte + \",\"\n        + pShort + \",\"\n        + pInt + \",\"\n        + pLong + \",\"\n        + pFloat + \",\"\n        + pDouble + \",\"\n        + pDoubleWrap;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/QueryParamSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"QueryParamSchema\")\n@Path(\"/queryParam\")\npublic class QueryParamSchema {\n  @Path(\"testQueryEncode\")\n  @GET\n  public String testQueryEncode(@QueryParam(\"param\") String param) {\n    return param;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/QueryParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.enums.Explode;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.enums.ParameterStyle;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\n@RestSchema(schemaId = \"QueryParamWithListSchema\")\n@Path(\"/queryList\")\npublic class QueryParamWithListSchema {\n  @Path(\"queryListCSV\")\n  @GET\n  public String queryListCSV(\n      @Parameter(name = \"queryList\", in = ParameterIn.QUERY, style = ParameterStyle.FORM, explode = Explode.FALSE)\n      @QueryParam(\"queryList\") List<String> queryList) {\n    return queryList == null ? \"null\" : queryList.size() + \":\" + queryList;\n  }\n\n  @Path(\"queryListSSV\")\n  @GET\n  public String queryListSSV(\n      @Parameter(name = \"queryList\", in = ParameterIn.QUERY, style = ParameterStyle.SPACEDELIMITED, explode = Explode.FALSE)\n      @QueryParam(\"queryList\") List<String> queryList) {\n    return queryList == null ? \"null\" : queryList.size() + \":\" + queryList;\n  }\n\n  @Path(\"queryListPIPES\")\n  @GET\n  public String queryListPIPES(\n      @Parameter(name = \"queryList\", in = ParameterIn.QUERY, style = ParameterStyle.PIPEDELIMITED, explode = Explode.FALSE)\n      @QueryParam(\"queryList\") List<String> queryList) {\n    return queryList == null ? \"null\" : queryList.size() + \":\" + queryList;\n  }\n\n  @Path(\"queryListMULTI\")\n  @GET\n  public String queryListMULTI(\n      @Parameter(name = \"queryList\", in = ParameterIn.QUERY, style = ParameterStyle.FORM, explode = Explode.TRUE)\n      @QueryParam(\"queryList\") List<String> queryList) {\n    return queryList == null ? \"null\" : queryList.size() + \":\" + queryList;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/ReactiveSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ReactiveSchema\")\n@Path(\"/reactive\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class ReactiveSchema {\n  // reactive is configured to run in event-loop thread pool\n  @Path(\"/testSyncInvokeInEventLoop\")\n  @GET\n  public int testSyncInvokeInEventLoop(@QueryParam(\"a\") int a, @QueryParam(\"b\") int b) {\n    RestOperations client = RestTemplateBuilder.create();\n    return client.getForObject(\"cse://jaxrs/compute/reduce?a=1&b=2\", int.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/RequestClientTimeOut.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.demo.validator.Student;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n\n@RestSchema(schemaId = \"clientreqtimeout\")\n@Path(\"/clientreqtimeout\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class RequestClientTimeOut {\n\n  @Path(\"/add\")\n  @POST\n  public int add(@FormParam(\"a\") int a, @FormParam(\"b\") int b) throws InterruptedException {\n    Thread.sleep(2000);\n    return a + b;\n  }\n\n  @Path(\"/sayhello\")\n  @POST\n  public Student sayHello(Student student) throws InterruptedException {\n    student.setName(\"hello \" + student.getName());\n    student.setAge(student.getAge());\n    return student;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/SchemeInterfaceJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport jakarta.validation.constraints.Min;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.springframework.data.domain.Page;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@Path(\"/jaxrs/schemaInterface\")\n@Produces(MediaType.APPLICATION_JSON)\npublic interface SchemeInterfaceJaxrs {\n  @Path(\"/add\")\n  @GET\n  int add(@Min(-100) @RequestParam(\"a\") int a, @Min(1) @RequestParam(\"b\") int b);\n\n  @Path(\"/interfaceModel\")\n  @GET\n  Page<String> interfaceModel(Page<String> model);\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/SchemeInterfaceJaxrsImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.data.domain.Page;\n\n@RestSchema(schemaId = \"SchemeInterfaceJaxrs\", schemaInterface = SchemeInterfaceJaxrs.class)\npublic class SchemeInterfaceJaxrsImpl implements SchemeInterfaceJaxrs {\n  @Override\n  public int add(int a, int b) {\n    return a + b;\n  }\n\n  public int reduce(int a, int b) {\n    return a - b;\n  }\n\n  public int add(String a, String b) {\n    return Integer.parseInt(a) + Integer.parseInt(b);\n  }\n\n  @Override\n  public Page<String> interfaceModel(Page<String> model) {\n    return model;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/Validator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server;\n\nimport jakarta.validation.Valid;\nimport jakarta.validation.constraints.Min;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.PUT;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.demo.validator.Student;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.hibernate.validator.constraints.Length;\n\n@RestSchema(schemaId = \"validator\")\n@Path(\"/validator\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class Validator {\n\n  @Path(\"/add\")\n  @POST\n  public int add(@FormParam(\"a\") int a, @Min(20) @FormParam(\"b\") int b) {\n    return a + b;\n  }\n\n  @Path(\"/sayhi/{name}\")\n  @PUT\n  public String sayHi(@Length(min = 3) @PathParam(\"name\") String name) {\n    ContextUtils.getInvocationContext().setStatus(202);\n    return name + \" sayhi\";\n  }\n\n  @Path(\"/sayhello\")\n  @POST\n  public Student sayHello(@Valid Student student) {\n    student.setName(\"hello \" + student.getName());\n    student.setAge(student.getAge());\n    return student;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/beanParam/BeanParamTestService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.beanParam;\n\nimport java.io.IOException;\nimport java.util.Scanner;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.BeanParam;\nimport jakarta.ws.rs.Consumes;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\n@RestSchema(schemaId = \"beanParamTest\")\n@Path(\"/beanParamTest\")\npublic class BeanParamTestService {\n  @Path(\"/{pathSwaggerStr}/simple\")\n  @GET\n  public String beanParameterTest(InvocationContext invocationContext, @BeanParam TestBeanParameter testBeanParameter,\n      @QueryParam(\"extraQuery\") String extraQuery) {\n    return String.format(\"invocationContextConsistency=%b|testBeanParameter=%s|extraQuery=%s\",\n        ContextUtils.getInvocationContext() == invocationContext,\n        testBeanParameter.toString(),\n        extraQuery);\n  }\n\n  @Path(\"/upload\")\n  @Consumes(MediaType.MULTIPART_FORM_DATA)\n  @POST\n  public String beanParameterTestUpload(@FormParam(\"up0\") Part up0,\n      @BeanParam TestBeanParameterWithUpload testBeanParameter,\n      @QueryParam(\"extraQuery\") String extraQuery) throws IOException {\n    return String.format(\"testBeanParameter=%s|extraQuery=%s|up0=%s|up1=%s|up2=%s\",\n        testBeanParameter.toString(),\n        extraQuery,\n        getUploadContent(up0),\n        getUploadContent(testBeanParameter.getUp1()),\n        getUploadContent(testBeanParameter.getUp2()));\n  }\n\n  public String getUploadContent(Part upload) throws IOException {\n    StringBuilder result = new StringBuilder();\n    try (Scanner scanner = new Scanner(upload.getInputStream())) {\n      while (scanner.hasNext()) {\n        result.append(scanner.next());\n      }\n    }\n    return result.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/beanParam/TestBeanParameter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.beanParam;\n\nimport jakarta.ws.rs.CookieParam;\nimport jakarta.ws.rs.DefaultValue;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.QueryParam;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\npublic class TestBeanParameter {\n  @DefaultValue(\"defaultQueryValue\")\n  @QueryParam(\"querySwaggerStr\")\n  private String queryStr;\n\n  private Integer headerInt;\n\n  private String pathStr;\n\n  @CookieParam(\"cookieSwaggerLong\")\n  private long cookieLong;\n\n  @JsonIgnore\n  private String ignoredField;\n\n  public String getQueryStr() {\n    return queryStr;\n  }\n\n  public void setQueryStr(String queryStr) {\n    this.queryStr = queryStr;\n  }\n\n  public Integer getHeaderInt() {\n    return headerInt;\n  }\n\n  @DefaultValue(\"12\")\n  @HeaderParam(\"headerSwaggerInt\")\n  public void setHeaderInt(Integer headerInt) {\n    this.headerInt = headerInt;\n  }\n\n  public String getPathStr() {\n    return pathStr;\n  }\n\n  @PathParam(\"pathSwaggerStr\")\n  public void setPathStr(String pathStr) {\n    this.pathStr = pathStr;\n  }\n\n  public long getCookieLong() {\n    return cookieLong;\n  }\n\n  public void\n  setCookieLong(long cookieLong) {\n    this.cookieLong = cookieLong;\n  }\n\n  public String getIgnoredField() {\n    return ignoredField;\n  }\n\n  public void setIgnoredField(String ignoredField) {\n    this.ignoredField = ignoredField;\n  }\n\n  @Override\n  public String toString() {\n    final StringBuilder sb = new StringBuilder(\"TestBeanParameter{\");\n    sb.append(\"queryStr='\").append(queryStr).append('\\'');\n    sb.append(\", headerInt=\").append(headerInt);\n    sb.append(\", pathStr='\").append(pathStr).append('\\'');\n    sb.append(\", cookieLong=\").append(cookieLong);\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/beanParam/TestBeanParameterWithUpload.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.beanParam;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.QueryParam;\n\npublic class TestBeanParameterWithUpload {\n  @QueryParam(\"query\")\n  private String queryStr;\n\n  @FormParam(\"up1\")\n  private Part up1;\n\n  private Part up2;\n\n  public String getQueryStr() {\n    return queryStr;\n  }\n\n  public void setQueryStr(String queryStr) {\n    this.queryStr = queryStr;\n  }\n\n  public Part getUp1() {\n    return up1;\n  }\n\n  public void setUp1(Part up1) {\n    this.up1 = up1;\n  }\n\n  public Part getUp2() {\n    return up2;\n  }\n\n  @FormParam(\"up2\")\n  public void setUp2(Part up2) {\n    this.up2 = up2;\n  }\n\n  @Override\n  public String toString() {\n    final StringBuilder sb = new StringBuilder(\"TestBeanParameterWithUpload{\");\n    sb.append(\"queryStr='\").append(queryStr).append('\\'');\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/injectBean/InjectBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.injectBean;\n\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class InjectBean {\n  private boolean set = true;\n\n  public boolean isSet() {\n    return set;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/injectBean/InjectBeanSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.injectBean;\n\nimport java.util.List;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher;\n\n@RestSchema(schemaId = \"InjectBeanSchema\")\n@Path(\"/\")\npublic class InjectBeanSchema {\n  @Path(\"/injectSet\")\n  @GET\n  public boolean injectSet() {\n    List<VertxHttpDispatcher> services = SPIServiceUtils.getOrLoadSortedService(VertxHttpDispatcher.class);\n    for (VertxHttpDispatcher service : services) {\n      if (service instanceof InjectBeanVertxHttpDispatcher) {\n        return ((InjectBeanVertxHttpDispatcher) service).isSet();\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/injectBean/InjectBeanVertxHttpDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.injectBean;\n\nimport org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.vertx.ext.web.Router;\n\npublic class InjectBeanVertxHttpDispatcher implements VertxHttpDispatcher {\n  private InjectBean injectBean;\n\n  @Autowired\n  public void setInjectBean(InjectBean injectBean) {\n    this.injectBean = injectBean;\n  }\n\n  @Override\n  public void init(Router router) {\n\n  }\n\n  public boolean isSet() {\n    return injectBean.isSet();\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/multiErrorCode/MultiErrorCodeService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.multiErrorCode;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.multiErrorCode.MultiRequest;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiResponse200;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiResponse400;\nimport org.apache.servicecomb.demo.multiErrorCode.MultiResponse500;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.core.Response.Status;\n\n@RestSchema(schemaId = \"MultiErrorCodeService\")\n@Path(\"MultiErrorCodeService\")\npublic class MultiErrorCodeService {\n  @Path(\"/errorCode\")\n  @POST\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = MultiResponse200.class)), description = \"\"),\n      @ApiResponse(responseCode = \"400\", content = @Content(schema = @Schema(implementation = MultiResponse400.class)), description = \"\"),\n      @ApiResponse(responseCode = \"500\", content = @Content(schema = @Schema(implementation = MultiResponse500.class)), description = \"\")})\n  public MultiResponse200 errorCode(MultiRequest request) {\n    if (request.getCode() == 400) {\n      MultiResponse400 r = new MultiResponse400();\n      r.setCode(400);\n      r.setMessage(\"bad request\");\n      throw new InvocationException(jakarta.ws.rs.core.Response.Status.BAD_REQUEST, r);\n    } else if (request.getCode() == 500) {\n      MultiResponse500 r = new MultiResponse500();\n      r.setCode(500);\n      r.setMessage(\"internal error\");\n      throw new InvocationException(jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR, r);\n    } else {\n      MultiResponse200 r = new MultiResponse200();\n      r.setCode(200);\n      r.setMessage(\"success result\");\n      return r;\n    }\n  }\n\n  @Path(\"/errorCodeWithHeader\")\n  @POST\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", headers = {\n          @Header(name = \"x-code\", schema = @Schema(implementation = String.class))},\n          content = @Content(schema = @Schema(implementation = MultiResponse200.class)), description = \"\"),\n      @ApiResponse(responseCode = \"400\", headers = {\n          @Header(name = \"x-code\", schema = @Schema(implementation = String.class))},\n          content = @Content(schema = @Schema(implementation = MultiResponse400.class)), description = \"\"),\n      @ApiResponse(responseCode = \"500\", headers = {\n          @Header(name = \"x-code\", schema = @Schema(implementation = String.class))},\n          content = @Content(schema = @Schema(implementation = MultiResponse500.class)), description = \"\")})\n  public Response errorCodeWithHeader(MultiRequest request) {\n    Response response = new Response();\n    if (request.getCode() == 400) {\n      MultiResponse400 r = new MultiResponse400();\n      r.setCode(400);\n      r.setMessage(\"bad request\");\n      response.setStatus(Status.BAD_REQUEST);\n      // If got many types for different status code, we can only using InvocationException for failed error code like 400-500.\n      // The result for Failed Family(e.g. 400-500), can not set return value as target type directly or will give exception.\n      response.setResult(new InvocationException(Status.BAD_REQUEST, r));\n      response.setHeader(\"x-code\", \"400\");\n    } else if (request.getCode() == 500) {\n      MultiResponse500 r = new MultiResponse500();\n      r.setCode(500);\n      r.setMessage(\"internal error\");\n      response.setStatus(Status.INTERNAL_SERVER_ERROR);\n      response.setResult(new InvocationException(Status.INTERNAL_SERVER_ERROR, r));\n      response.setHeader(\"x-code\", \"500\");\n    } else {\n      MultiResponse200 r = new MultiResponse200();\n      r.setCode(200);\n      r.setMessage(\"success result\");\n      response.setStatus(Status.OK);\n      // If error code is OK family(like 200), we can use the target type.\n      response.setResult(r);\n      response.setHeader(\"x-code\", \"200\");\n    }\n    return response;\n  }\n\n  // using JAX-RS providers, users need to add dependencies for implementations, see pom for an example.\n  @Path(\"/errorCodeWithHeaderJAXRS\")\n  @POST\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", headers = {\n          @Header(name = \"x-code\", schema = @Schema(implementation = String.class))},\n          content = @Content(schema = @Schema(implementation = MultiResponse200.class)), description = \"\"),\n      @ApiResponse(responseCode = \"400\", headers = {\n          @Header(name = \"x-code\", schema = @Schema(implementation = String.class))},\n          content = @Content(schema = @Schema(implementation = MultiResponse400.class)), description = \"\"),\n      @ApiResponse(responseCode = \"500\", headers = {\n          @Header(name = \"x-code\", schema = @Schema(implementation = String.class))},\n          content = @Content(schema = @Schema(implementation = MultiResponse500.class)), description = \"\")})\n  public jakarta.ws.rs.core.Response errorCodeWithHeaderJAXRS(MultiRequest request) {\n    jakarta.ws.rs.core.Response response;\n    if (request.getCode() == 400) {\n      MultiResponse400 r = new MultiResponse400();\n      r.setCode(request.getCode());\n      r.setMessage(request.getMessage());\n      // If got many types for different status code, we can only using InvocationException for failed error code like 400-500.\n      // The result for Failed Family(e.g. 400-500), can not set return value as target type directly or will give exception.\n      response = jakarta.ws.rs.core.Response.status(Status.BAD_REQUEST)\n          .entity(new InvocationException(Status.BAD_REQUEST, r))\n          .header(\"x-code\", \"400\")\n          .build();\n    } else if (request.getCode() == 500) {\n      MultiResponse500 r = new MultiResponse500();\n      r.setCode(request.getCode());\n      r.setMessage(request.getMessage());\n      response = jakarta.ws.rs.core.Response.status(Status.INTERNAL_SERVER_ERROR)\n          .entity(new InvocationException(Status.INTERNAL_SERVER_ERROR, r))\n          .header(\"x-code\", \"500\")\n          .build();\n    } else {\n      MultiResponse200 r = new MultiResponse200();\n      r.setCode(request.getCode());\n      r.setMessage(request.getMessage());\n      // If error code is OK family(like 200), we can use the target type.\n      response = jakarta.ws.rs.core.Response.status(Status.OK)\n          .entity(r)\n          .header(\"x-code\", \"200\")\n          .build();\n    }\n    return response;\n  }\n\n  @Path(\"/noClientErrorCode\")\n  @POST\n  @ApiResponses({\n      @ApiResponse(responseCode = \"400\", content = @Content(schema = @Schema(implementation = NoClientErrorCode400.class)), description = \"\")})\n  public List<NoClientErrorCode200> noClientErrorCode(MultiRequest request) {\n    if (request.getCode() == 400) {\n      NoClientErrorCode400 r = new NoClientErrorCode400();\n      r.setCode(request.getCode());\n      r.setMessage(request.getMessage());\n      r.setT400(400);\n      throw new InvocationException(Status.BAD_REQUEST, r);\n    } else {\n      NoClientErrorCode200 r = new NoClientErrorCode200();\n      r.setCode(request.getCode());\n      r.setMessage(request.getMessage());\n      r.setT200(200);\n      List<NoClientErrorCode200> result = new ArrayList<>();\n      result.add(r);\n      return result;\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/multiErrorCode/NoClientErrorCode200.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.multiErrorCode;\n\npublic class NoClientErrorCode200 {\n  private String message;\n\n  private int code;\n\n  private long t200;\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n\n  public long getT200() {\n    return t200;\n  }\n\n  public void setT200(long t200) {\n    this.t200 = t200;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/multiErrorCode/NoClientErrorCode400.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.multiErrorCode;\n\npublic class NoClientErrorCode400 {\n  private String message;\n\n  private int code;\n\n  private long t400;\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n\n  public long getT400() {\n    return t400;\n  }\n\n  public void setT400(long t400) {\n    this.t400 = t400;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.pojoDefault;\n\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"DefaultModelService\")\n@Path(\"DefaultModelService\")\npublic class DefaultModelService {\n  @Path(\"/model\")\n  @POST\n  public DefaultResponseModel errorCode(DefaultRequestModel request) {\n    DefaultResponseModel model = new DefaultResponseModel();\n    model.setIndex(request.getIndex());\n    model.setAge(request.getAge());\n    model.setName(request.getName());\n    model.setDesc(null);\n    return model;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.pojoDefault;\n\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\nimport jakarta.validation.constraints.Null;\n\npublic class DefaultRequestModel {\n  @Min(20)\n  @Max(2000)\n  @Null\n  private Integer age = 200;\n\n  @Min(2)\n  @Max(30)\n  @Null\n  private String name = \"World\";\n\n  private int index;\n\n  private String desc;\n\n  public Integer getAge() {\n    return age;\n  }\n\n  public void setAge(Integer age) {\n    this.age = age;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  public String getDesc() {\n    return desc;\n  }\n\n  public void setDesc(String desc) {\n    this.desc = desc;\n  }\n\n  @Override\n  public String toString() {\n    return \"index=\" + index + \";name=\" + name + \";age=\" + age;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.pojoDefault;\n\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\nimport jakarta.validation.constraints.Null;\n\npublic class DefaultResponseModel {\n  @Min(20)\n  @Max(2000)\n  @Null\n  private Integer age = 200;\n\n  @Min(2)\n  @Max(30)\n  @Null\n  private String name = \"World\";\n\n  private int index;\n\n  private String desc;\n\n  public Integer getAge() {\n    return age;\n  }\n\n  public void setAge(Integer age) {\n    this.age = age;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  public String getDesc() {\n    return desc;\n  }\n\n  public void setDesc(String desc) {\n    this.desc = desc;\n  }\n\n  @Override\n  public String toString() {\n    return \"index=\" + index + \";name=\" + name + \";age=\" + age;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.validation;\n\nimport jakarta.validation.Valid;\nimport jakarta.validation.constraints.NotEmpty;\nimport jakarta.validation.constraints.NotNull;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\nimport org.apache.servicecomb.demo.validator.Teacher;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"ValidationService\")\n@Path(\"ValidationService\")\npublic class ValidationService {\n  @Path(\"/validate\")\n  @POST\n  public ValidationModel errorCode(@NotNull @Valid ValidationModel request) {\n    return request;\n  }\n\n  @Path(\"/validateQuery\")\n  @GET\n  public String queryValidate(@NotEmpty @QueryParam(\"name\") String name) {\n    return name;\n  }\n\n  @Path(\"/sayTeacherInfo\")\n  @POST\n  public Teacher sayTeacherInfo(@Valid Teacher teacher) {\n    return teacher;\n  }\n}\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.jaxrs.server.injectBean.InjectBeanVertxHttpDispatcher\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml",
    "content": "﻿## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: jaxrstest\n    name: jaxrs\n    version: 0.0.2\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n      enableSwaggerRegistration: true\n  rest:\n    address: 0.0.0.0:8080\n    server:\n      maxFormAttributeSize: 1024 # for testing, and bigger than netty buffer allocator\n      maxFormBufferedBytes: 100\n  highway:\n    address: 0.0.0.0:7070\n  uploads:\n    directory: target\n\n  codec:\n    printErrorMessage: true\n\n  executors.Provider.ReactiveSchema: servicecomb.executor.reactive\n\n  invocation:\n    timeout:\n      check:\n        enabled: false\n\n  # use service center to find schema info\n  openAPI:\n    registry:\n      # enable service center OpenAPI registry, and need set enableSwaggerRegistration: true\n      registry:\n        enabled: true\n      # disable instance OpenAPI registry\n      instance:\n        enabled: false\n"
  },
  {
    "path": "demo/demo-jaxrs/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-jaxrs</artifactId>\n  <name>Java Chassis::Demo::JAXRS</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>jaxrs-server</module>\n    <module>jaxrs-client</module>\n  </modules>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-spring-data</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.data</groupId>\n      <artifactId>spring-data-commons</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-local-registry/README.md",
    "content": "This demo is an integration test for testing local registration an discovery.\n\n\nLocal registration and discovery is a mechanism that do not using Service Center,\n`Microservice` and `MicroserviceInstance` are constructed from configuration file.\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-local-registry-client</artifactId>\n  <name>Java Chassis::Demo::Local Registry client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-local-registry</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.localRegistryClient.LocalRegistryClientApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>demo-local-registry-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8080:8080</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/java/org/apache/servicecomb/demo/localRegistryClient/CodeFirstService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryClient;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\n\n@Path(\"/register/url/codeFirst\")\n@Produces(\"application/json\")\npublic interface CodeFirstService {\n  @GET\n  @Path(\"getName\")\n  String getName(@QueryParam(\"name\") String name);\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/java/org/apache/servicecomb/demo/localRegistryClient/LocalRegistryClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryClient;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class LocalRegistryClientApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(LocalRegistryClientApplication.class)\n        .web(WebApplicationType.SERVLET).build()\n        .run(args);\n\n    registerSchema();\n\n    runTest();\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      throw new IllegalStateException(\"tests failed\");\n    }\n  }\n\n  private static void registerSchema() {\n    SCBEngine.getInstance().getOpenAPIRegistryManager().registerOpenAPI(\"demo-local-registry\",\n        \"demo-local-registry-server\",\n        \"CodeFirstEndpoint\", CodeFirstService.class);\n    SCBEngine.getInstance().getOpenAPIRegistryManager().registerOpenAPI(\"demo-local-registry\",\n        \"demo-local-registry-server-bean\",\n        \"CodeFirstEndpoint\", CodeFirstService.class);\n  }\n\n  private static void runTest() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"demo-local-registry-server\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/java/org/apache/servicecomb/demo/localRegistryClient/LocalRegistryServerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryClient;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class LocalRegistryServerTest implements CategorizedTestCase {\n  // demo-local-registry-server-bean use yaml to register service, and register schema by\n  // local file loading\n  @RpcReference(microserviceName = \"demo-local-registry-server\", schemaId = \"CodeFirstEndpoint\")\n  private CodeFirstService codeFirstService;\n\n  @RpcReference(microserviceName = \"demo-local-registry-server\", schemaId = \"ServerEndpoint\")\n  private ServerService serverService;\n\n  // demo-local-registry-server-bean use bean to register service, and register schema part by\n  // local file loading, part by bean class\n  @RpcReference(microserviceName = \"demo-local-registry-server-bean\", schemaId = \"CodeFirstEndpoint\")\n  private CodeFirstService codeFirstServiceBean;\n\n  @RpcReference(microserviceName = \"demo-local-registry-server-bean\", schemaId = \"ServerEndpoint\")\n  private ServerService serverServiceBean;\n\n  // demo-local-registry-server-bean2 use bean to register service and schema\n  @RpcReference(microserviceName = \"demo-local-registry-server-bean2\", schemaId = \"CodeFirstEndpoint2\")\n  private CodeFirstService codeFirstServiceBean2;\n\n  @RpcReference(microserviceName = \"demo-local-registry-server-bean2\", schemaId = \"ServerEndpoint\")\n  private ServerService serverServiceBean2;\n\n  private DiscoveryManager discoveryManager;\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testServerGetName();\n    testCodeFirstGetName();\n    testGetAllMicroservice();\n  }\n\n  private void testGetAllMicroservice() {\n    List<? extends DiscoveryInstance> microserviceList = discoveryManager\n        .findServiceInstances(\"demo-local-registry\", \"demo-local-registry-client\");\n    TestMgr.check(1, microserviceList.size());\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-local-registry\", \"demo-local-registry-server\");\n    TestMgr.check(1, microserviceList.size());\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-local-registry\", \"demo-local-registry-server-bean\");\n    TestMgr.check(1, microserviceList.size());\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-local-registry\", \"demo-local-registry-server-bean2\");\n    TestMgr.check(1, microserviceList.size());\n  }\n\n  private void testCodeFirstGetName() {\n    TestMgr.check(\"2\", codeFirstService.getName(\"2\"));\n    TestMgr.check(\"2\", codeFirstServiceBean.getName(\"2\"));\n    TestMgr.check(\"2\", codeFirstServiceBean2.getName(\"2\"));\n  }\n\n  private void testServerGetName() {\n    RestOperations template = RestTemplateBuilder.create();\n    TestMgr.check(\"2\", template\n        .getForObject(\"cse://demo-local-registry-server/register/url/prefix/getName?name=2\",\n            String.class));\n    TestMgr.check(\"2\", template\n        .getForObject(\"cse://demo-local-registry-server-bean/register/url/prefix/getName?name=2\",\n            String.class));\n    TestMgr.check(\"2\", template\n        .getForObject(\"cse://demo-local-registry-server-bean2/register/url/prefix/getName?name=2\",\n            String.class));\n    TestMgr.check(\"2\", serverService.getName(\"2\"));\n    TestMgr.check(\"2\", serverServiceBean.getName(\"2\"));\n    TestMgr.check(\"2\", serverServiceBean2.getName(\"2\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/java/org/apache/servicecomb/demo/localRegistryClient/RegistryBeansConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryClient;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@SuppressWarnings(\"unused\")\npublic class RegistryBeansConfiguration {\n  @Bean\n  public RegistryBean demoLocalRegistryServerBean() {\n    List<String> endpoints = new ArrayList<>();\n    endpoints.add(\"rest://localhost:8080\");\n    List<Instance> instances = new ArrayList<>();\n    instances.add(new Instance().setEndpoints(endpoints));\n\n    return new RegistryBean()\n        .setServiceName(\"demo-local-registry-server-bean\")\n        .setId(\"002\")\n        .setVersion(\"0.0.3\")\n        .setAppId(\"demo-local-registry\")\n        .addSchemaId(\"ServerEndpoint\")\n        .addSchemaInterface(\"CodeFirstEndpoint\", CodeFirstService.class)\n        .setInstances(new Instances().setInstances(instances));\n  }\n\n  @Bean\n  public RegistryBean demoLocalRegistryServerBean2() {\n    List<String> endpoints = new ArrayList<>();\n    endpoints.add(\"rest://localhost:8080\");\n    List<Instance> instances = new ArrayList<>();\n    instances.add(new Instance().setEndpoints(endpoints));\n\n    return new RegistryBean()\n        .setServiceName(\"demo-local-registry-server-bean2\")\n        .setId(\"003\")\n        .setVersion(\"0.0.3\")\n        .setAppId(\"demo-local-registry\")\n        .addSchemaId(\"ServerEndpoint\")\n        .addSchemaInterface(\"CodeFirstEndpoint2\", CodeFirstService.class)\n        .setInstances(new Instances().setInstances(instances));\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/java/org/apache/servicecomb/demo/localRegistryClient/ServerService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.localRegistryClient;\n\npublic interface ServerService {\n  String getName(String name);\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8082\n\nservicecomb:\n  service:\n    application: demo-local-registry\n    name: demo-local-registry-client\n    version: 0.0.1\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/resources/microservices/demo-local-registry-server/ServerEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.localRegistryServer.ServerEndpoint\n  version: 1.0.0\nservers:\n- url: /register/url/prefix\npaths:\n  /getName:\n    get:\n      operationId: getName\n      parameters:\n      - name: name\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/resources/microservices/demo-local-registry-server-bean/ServerEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.localRegistryServer.ServerEndpoint\n  version: 1.0.0\nservers:\n- url: /register/url/prefix\npaths:\n  /getName:\n    get:\n      operationId: getName\n      parameters:\n      - name: name\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/resources/microservices/demo-local-registry-server-bean2/ServerEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.localRegistryServer.ServerEndpoint\n  version: 1.0.0\nservers:\n- url: /register/url/prefix\npaths:\n  /getName:\n    get:\n      operationId: getName\n      parameters:\n      - name: name\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/main/resources/registry.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\ndemo-local-registry-server:\n  - id: \"001\"\n    version: \"1.0\"\n    appid: demo-local-registry\n    schemaIds:\n      - ServerEndpoint\n      - CodeFirstEndpoint\n    instances:\n      - endpoints:\n          - rest://localhost:8080\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-client/src/test/java/org/apache/servicecomb/demo/localRegistryClient/LocalRegistryIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryClient;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class LocalRegistryIT {\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    LocalRegistryClientApplication.main(new String[0]);\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-local-registry-server</artifactId>\n  <name>Java Chassis::Demo::Local Registry Server</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-local-registry</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.localRegistryServer.LocalRegistryServerApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/src/main/java/org/apache/servicecomb/demo/localRegistryServer/CodeFirstEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryServer;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"CodeFirstEndpoint\")\n@RequestMapping(path = \"/register/url/codeFirst\", produces = MediaType.APPLICATION_JSON)\npublic class CodeFirstEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/src/main/java/org/apache/servicecomb/demo/localRegistryServer/LocalRegistryServerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryServer;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class LocalRegistryServerApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(LocalRegistryServerApplication.class).web(WebApplicationType.SERVLET).build()\n        .run(args);\n\n    SelfServiceInvoker invoker = BeanUtils.getBean(\"SelfServiceInvoker\");\n    invoker.latch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(invoker.result, \"hello\");\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      System.exit(1);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/src/main/java/org/apache/servicecomb/demo/localRegistryServer/SelfServiceInvoker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryServer;\n\nimport java.util.concurrent.CountDownLatch;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component(\"SelfServiceInvoker\")\npublic class SelfServiceInvoker implements BootListener {\n  interface IServerEndpoint {\n    String getName(String name);\n  }\n\n  @RpcReference(microserviceName = \"demo-local-registry-server\", schemaId = \"ServerEndpoint\")\n  IServerEndpoint endpoint;\n\n  public CountDownLatch latch = new CountDownLatch(1);\n\n  public String result = \"\";\n\n  public void onAfterRegistry(BootEvent event) {\n    result = endpoint.getName(\"hello\");\n    latch.countDown();\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/src/main/java/org/apache/servicecomb/demo/localRegistryServer/ServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.localRegistryServer;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ServerEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ServerEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8080\n\n# java-chassis configurations\nservicecomb:\n  service:\n    application: demo-local-registry\n    name: demo-local-registry-server\n    version: 0.0.1\n  rest:\n    address: 0.0.0.0:8080\n"
  },
  {
    "path": "demo/demo-local-registry/demo-local-registry-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-local-registry/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-local-registry</artifactId>\n  <name>Java Chassis::Demo::Local Registry</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-local-registry-server</module>\n    <module>demo-local-registry-client</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-registries/README.md",
    "content": "# About\n\n* This demo enables both local-registry and sc-registry.\n* This demo using local-registry to call service center api.\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-multi-registries-client</artifactId>\n  <name>Java Chassis::Demo::Multi Registries client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multi-registries</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.registry.MultiRegistriesClientApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>demo-multi-registries-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/IServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\npublic interface IServerEndpoint {\n  String getName(String name);\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/IServiceCenterEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestParam;\n\npublic interface IServiceCenterEndpoint {\n  // java name can not be `x-domain-name`, so interfaces define all parameters.\n  @GetMapping(path = \"/instances\")\n  Object getInstances(@RequestParam(name = \"appId\") String appId,\n      @RequestParam(name = \"serviceName\") String serviceName,\n      @RequestParam(name = \"global\") String global,\n      @RequestParam(name = \"version\") String version,\n      @RequestHeader(name = \"x-domain-name\") String domain);\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/MultiRegistriesClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.stereotype.Component;\n\n@SpringBootApplication\n@Component\npublic class MultiRegistriesClientApplication {\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(MultiRegistriesClientApplication.class)\n        .web(WebApplicationType.SERVLET).build().run(args);\n\n    runTest();\n  }\n\n  public static void runTest() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"demo-multi-registries-server\");\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      throw new IllegalStateException(\"tests failed\");\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/MultiRegistriesServerTestCase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class MultiRegistriesServerTestCase implements CategorizedTestCase {\n  RestOperations template = RestTemplateBuilder.create();\n\n  private DiscoveryManager discoveryManager;\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testServerGetName();\n    testGetAllMicroservice();\n  }\n\n  private void testGetAllMicroservice() {\n    List<? extends DiscoveryInstance> microserviceList = discoveryManager\n        .findServiceInstances(\"demo-multi-registries\", \"demo-multi-registries-client\");\n    TestMgr.check(2, microserviceList.size()); // both local and sc has one.\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-multi-registries\", \"demo-multi-registries-server\");\n    TestMgr.check(1, microserviceList.size());\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-multi-registries\", \"thirdParty-service-center\");\n    TestMgr.check(1, microserviceList.size());\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-multi-registries\", \"thirdParty-no-schema-server\");\n    TestMgr.check(1, microserviceList.size());\n  }\n\n  private void testServerGetName() {\n    // invoke demo-multi-registries-server\n    TestMgr.check(\"2\", template\n        .getForObject(\"cse://demo-multi-registries-server/register/url/prefix/getName?name=2\",\n            String.class));\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/SchemaDiscoveryTestCase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class SchemaDiscoveryTestCase implements CategorizedTestCase {\n  // Do not support this feature any more since 3.0.0\n//  @RpcReference(microserviceName = \"thirdParty-no-schema-server\", schemaId = \"ServerEndpoint\")\n//  IServerEndpoint serverEndpoint;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    // invoke thirdParty-no-schema-server(mocked by demo-multi-registries-server)\n    //    TestMgr.check(\"hello\", serverEndpoint.getName(\"hello\"));\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n\n  }\n\n  @Override\n  public String getMicroserviceName() {\n    return \"thirdParty-service-center\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/ServiceCenterEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n// do not know how to write schemas? code first and generate it.\n@RestSchema(schemaId = \"ServiceCenterEndpoint\")\n@RequestMapping(path = \"/v4/default/registry\", produces = MediaType.APPLICATION_JSON)\npublic class ServiceCenterEndpoint implements IServiceCenterEndpoint {\n  @GetMapping(path = \"/instances\")\n  public Object getInstances(@RequestParam(name = \"appId\") String appId,\n      @RequestParam(name = \"serviceName\") String serviceName,\n      @RequestParam(name = \"global\") String global,\n      @RequestParam(name = \"version\") String version,\n      @RequestHeader(name = \"x-domain-name\") String domain) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/java/org/apache/servicecomb/demo/registry/ServiceCenterTestCase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ServiceCenterTestCase implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"thirdParty-service-center\", schemaId = \"ServiceCenterEndpoint\")\n  IServiceCenterEndpoint serviceCenterEndpoint;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    // invoke service-center(3rd-parties)\n    @SuppressWarnings(\"unchecked\")\n    Map<String, List<?>> result = (Map<String, List<?>>) serviceCenterEndpoint.getInstances(\n        \"demo-multi-registries\",\n        \"demo-multi-registries-server\",\n        \"true\",\n        \"0.0.2\",\n        \"default\");\n    TestMgr.check(result.get(\"instances\").size(), 1);\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n\n  }\n\n  @Override\n  public String getMicroserviceName() {\n    return \"thirdParty-service-center\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8082\n\nservicecomb:\n  service:\n    application: demo-multi-registries\n    name: demo-multi-registries-client\n    version:  0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n      demo-multi-registries:\n        thirdParty-service-center:\n          enabled: false\n    local:\n      demo-multi-registries:\n        demo-multi-registries-server:\n          enabled: false\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/resources/microservices/thirdParty-service-center/ServiceCenterEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the License); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an AS IS BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.localRegistryServer.ServerEndpoint\n  version: 1.0.0\nservers:\n  - url: /v4/default/registry\npaths:\n  /instances:\n    get:\n      operationId: getInstances\n      parameters:\n        - name: appId\n          in: query\n          required: true\n          schema:\n            type: string\n        - name: serviceName\n          in: query\n          required: true\n          schema:\n            type: string\n        - name: global\n          in: query\n          required: true\n          schema:\n            type: string\n        - name: version\n          in: query\n          required: true\n          schema:\n            type: string\n        - name: x-domain-name\n          in: header\n          required: true\n          schema:\n            type: string\n      responses:\n        200:\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: object\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/main/resources/registry.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nthirdParty-service-center:\n  - id: \"001\"\n    version: \"4.0.0\"\n    appid: demo-multi-registries\n    schemaIds:\n      - ServiceCenterEndpoint\n    instances:\n      - endpoints:\n          - rest://localhost:30100\nthirdParty-no-schema-server:\n  - id: \"002\"\n    version: \"4.0.0\"\n    appid: demo-multi-registries\n    schemaIds:\n      - ServerEndpoint # not in local , discovery from demo-multi-registries-server. Not supported since 3.0.0\n    instances:\n      - endpoints:\n          - rest://localhost:8080 # actually will invoke to demo-multi-registries-server\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-client/src/test/java/org/apache/servicecomb/demo/registry/MultiRegistriesIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class MultiRegistriesIT {\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    MultiRegistriesClientApplication.main(new String[0]);\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-multi-registries-server</artifactId>\n  <name>Java Chassis::Demo::Multi Registries Server</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multi-registries</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.registry.MultiRegistriesServerApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-server/src/main/java/org/apache/servicecomb/demo/registry/MultiRegistriesServerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class MultiRegistriesServerApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(MultiRegistriesServerApplication.class)\n        .web(WebApplicationType.SERVLET).build().run(args);\n\n    SelfServiceInvoker invoker = BeanUtils.getBean(\"SelfServiceInvoker\");\n    invoker.latch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(invoker.result, \"hello\");\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      System.exit(1);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-server/src/main/java/org/apache/servicecomb/demo/registry/SelfServiceInvoker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport java.util.concurrent.CountDownLatch;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component(\"SelfServiceInvoker\")\npublic class SelfServiceInvoker implements BootListener {\n  interface IServerEndpoint {\n    String getName(String name);\n  }\n\n  @RpcReference(microserviceName = \"demo-multi-registries-server\", schemaId = \"ServerEndpoint\")\n  IServerEndpoint endpoint;\n\n  public CountDownLatch latch = new CountDownLatch(1);\n\n  public String result = \"\";\n\n  public void onAfterRegistry(BootEvent event) {\n    result = endpoint.getName(\"hello\");\n    latch.countDown();\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-server/src/main/java/org/apache/servicecomb/demo/registry/ServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.registry;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ServerEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ServerEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-server/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8080\n\nservicecomb:\n  service:\n    application: demo-multi-registries\n    name: demo-multi-registries-server\n    version: 0.0.2\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n"
  },
  {
    "path": "demo/demo-multi-registries/demo-multi-registries-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multi-registries/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-multi-registries</artifactId>\n  <name>Java Chassis::Demo::Multi Registry</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-multi-registries-server</module>\n    <module>demo-multi-registries-client</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-multi-service-center-client</artifactId>\n  <name>Java Chassis::Demo::Multi Service Centers::Client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multi-service-center</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiServiceCenterClient.Application</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>service-center-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>demo-multi-registries-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service30100</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service40100</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>40100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>demo-multi-service-center-servera:${project.version}</name>\n                    <alias>demo-multi-service-center-servera</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://service30100:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/demo-multi-service-center-servera-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service30100:service30100</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8080:8080</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>demo-multi-service-center-serverb:${project.version}</name>\n                    <alias>demo-multi-service-center-serverb</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://service40100:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/demo-multi-service-center-serverb-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service40100:service40100</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8082</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8082:8082</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/Application.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.stereotype.Component;\n\n@SpringBootApplication\n@Component\npublic class Application {\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(Application.class)\n        .web(WebApplicationType.NONE).build().run(args);\n\n    runTest();\n  }\n\n  public static void runTest() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"demo-multi-service-center-serverA\");\n    testTransportThreads();\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      throw new IllegalStateException(\"tests failed\");\n    }\n  }\n\n  private static void testTransportThreads() throws Exception {\n    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();\n    List<String> expectedThread = new ArrayList<>();\n    threadSet.forEach(thread -> {\n      if (thread.getName().startsWith(\"transport-vert.x-eventloop-thread\")) {\n        expectedThread.add(thread.getName());\n      }\n    });\n    // After SSL improvements https://github.com/eclipse-vertx/vert.x/pull/4468 introduced in 4.3.4\n    // SSL helper will use `internal-blocking` thread init ssl engine\n    // transport-vert.x-eventloop-thread-0\n    // transport-vert.x-eventloop-thread-1\n    // transport-vert.x-eventloop-thread-2\n    // transport-vert.x-eventloop-thread-3\n    // transport-vert.x-eventloop-thread-4\n    // transport-vert.x-eventloop-thread-5\n    // transport-vert.x-internal-blocking-0\n    // transport-vert.x-internal-blocking-1\n    TestMgr.check(6, expectedThread.size());\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/IConfigurationEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport java.util.List;\n\npublic interface IConfigurationEndpoint {\n  String getValue(String key, int type);\n\n  List<String> getValueList(String key, int type);\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/IServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\npublic interface IServerEndpoint {\n  String getName(String name);\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.event.SimpleEventBus;\nimport org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.apache.servicecomb.service.center.client.ServiceCenterAddressManager;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.HeartBeatEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.MicroserviceInstanceRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.MicroserviceRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.SchemaRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterDiscovery;\nimport org.apache.servicecomb.service.center.client.ServiceCenterDiscovery.SubscriptionKey;\nimport org.apache.servicecomb.service.center.client.ServiceCenterRegistration;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\nimport org.apache.servicecomb.service.center.client.model.ServiceCenterConfiguration;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.stereotype.Component;\n\nimport com.google.common.base.Charsets;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\nimport com.google.common.hash.Hashing;\n\n@Component\npublic class RegistryClientTest implements CategorizedTestCase {\n  private List<RegistrationEvents> events = new ArrayList<>();\n\n  private CountDownLatch registrationCounter = new CountDownLatch(1);\n\n  // auto test only tests 'hasRegistered=false', can run this client many times to test 'hasRegistered=true'\n  private boolean hasRegistered = true;\n\n  private final Environment environment;\n\n  @Autowired\n  public RegistryClientTest(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(\"default\",\n        Arrays.asList(\"http://127.0.0.1:30100\"), new EventBus(), \"\", \"\");\n    SSLProperties sslProperties = new SSLProperties();\n    sslProperties.setEnabled(false);\n    ServiceCenterClient serviceCenterClient = new ServiceCenterClient(addressManager, sslProperties,\n        new DefaultRequestAuthHeaderProvider(), \"default\", null, environment);\n    EventBus eventBus = new SimpleEventBus();\n    ServiceCenterConfiguration serviceCenterConfiguration = new ServiceCenterConfiguration();\n    ServiceCenterRegistration serviceCenterRegistration = new ServiceCenterRegistration(serviceCenterClient,\n        serviceCenterConfiguration, eventBus);\n    Microservice microservice = new Microservice();\n    microservice.setAppId(\"app_registry\");\n    microservice.setServiceName(\"name_registry\");\n    microservice.setVersion(\"1.0.0\");\n    microservice.setEnvironment(\"development\");\n    List<String> schemas = new ArrayList<>();\n    schemas.add(\"SchemaA\");\n    schemas.add(\"SchemaB\");\n    microservice.setSchemas(schemas);\n    MicroserviceInstance microserviceInstance = new MicroserviceInstance();\n    microserviceInstance.setHostName(\"host_registry\");\n    List<String> endpoints = new ArrayList<>();\n    endpoints.add(\"rest://127.0.0.1/\");\n    microserviceInstance.setEndpoints(endpoints);\n    List<SchemaInfo> schemaInfos = new ArrayList<>();\n    SchemaInfo schemaA = new SchemaInfo();\n    schemaA.setSchemaId(\"SchemaA\");\n    schemaA.setSchema(\"schema contents in any format\");\n    schemaA.setSummary(\n        Hashing.sha256().newHasher().putString(\"schema contents in any format\".toString(), Charsets.UTF_8).hash()\n            .toString());\n    schemaInfos.add(schemaA);\n    SchemaInfo schemaB = new SchemaInfo();\n    schemaB.setSchemaId(\"SchemaA\");\n    schemaB.setSchema(\"schema contents in any format\");\n    schemaB.setSummary(\n        Hashing.sha256().newHasher().putString(\"schema contents in any format\".toString(), Charsets.UTF_8).hash()\n            .toString());\n    schemaInfos.add(schemaB);\n    serviceCenterRegistration.setMicroservice(microservice);\n    serviceCenterRegistration.setMicroserviceInstance(microserviceInstance);\n    serviceCenterRegistration.setSchemaInfos(schemaInfos);\n    eventBus.register(this);\n\n    serviceCenterRegistration.startRegistration();\n    registrationCounter.await(30000, TimeUnit.MILLISECONDS);\n    if (hasRegistered) {\n      TestMgr.check(events.size() >= 3, true);\n      TestMgr.check(events.get(0).isSuccess(), true);\n      TestMgr.check(events.get(0) instanceof MicroserviceRegistrationEvent, true);\n      TestMgr.check(events.get(1).isSuccess(), true);\n      TestMgr.check(events.get(1) instanceof MicroserviceInstanceRegistrationEvent, true);\n      TestMgr.check(events.get(2).isSuccess(), true);\n      TestMgr.check(events.get(2) instanceof HeartBeatEvent, true);\n    } else {\n      TestMgr.check(events.size() >= 4, true);\n      TestMgr.check(events.get(0).isSuccess(), true);\n      TestMgr.check(events.get(0) instanceof MicroserviceRegistrationEvent, true);\n      TestMgr.check(events.get(1).isSuccess(), true);\n      TestMgr.check(events.get(1) instanceof SchemaRegistrationEvent, true);\n      TestMgr.check(events.get(2).isSuccess(), true);\n      TestMgr.check(events.get(2) instanceof MicroserviceInstanceRegistrationEvent, true);\n      TestMgr.check(events.get(3).isSuccess(), true);\n      TestMgr.check(events.get(3) instanceof HeartBeatEvent, true);\n    }\n\n    ServiceCenterDiscovery discovery = new ServiceCenterDiscovery(serviceCenterClient, eventBus);\n    discovery.updateMyselfServiceId(microservice.getServiceId());\n    discovery.startDiscovery();\n    SubscriptionKey subscriptionKey = new SubscriptionKey(microservice.getAppId(), microservice.getServiceName());\n    discovery.registerIfNotPresent(subscriptionKey);\n    List<MicroserviceInstance> instances = discovery.getInstanceCache(subscriptionKey);\n    TestMgr.check(instances != null, true);\n    TestMgr.check(instances.size(), 1);\n    discovery.stop();\n    serviceCenterRegistration.stop();\n    serviceCenterClient.deleteMicroserviceInstance(microservice.getServiceId(), microserviceInstance.getInstanceId());\n  }\n\n  @Subscribe\n  public void onMicroserviceRegistrationEvent(MicroserviceRegistrationEvent event) {\n    events.add(event);\n  }\n\n  @Subscribe\n  public void onSchemaRegistrationEvent(SchemaRegistrationEvent event) {\n    events.add(event);\n    hasRegistered = false;\n  }\n\n  @Subscribe\n  public void onMicroserviceInstanceRegistrationEvent(MicroserviceInstanceRegistrationEvent event) {\n    events.add(event);\n  }\n\n  @Subscribe\n  public void onHeartBeatEvent(HeartBeatEvent event) {\n    events.add(event);\n    registrationCounter.countDown();\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/SC2Configuration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.registry.sc.SCClientUtils;\nimport org.apache.servicecomb.registry.sc.SCConfigurationProperties;\nimport org.apache.servicecomb.registry.sc.SCConst;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterWatch;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\npublic class SC2Configuration {\n  @Bean\n  @ConfigurationProperties(prefix = SCConst.SC_REGISTRY_PREFIX + \"2\")\n  public SCConfigurationProperties scConfigurationProperties2() {\n    return new SCConfigurationProperties();\n  }\n\n  @Bean\n  public ServiceCenterWatch serviceCenterWatch2(\n      @Qualifier(\"scConfigurationProperties2\") SCConfigurationProperties scConfigurationProperties2,\n      List<AuthHeaderProvider> authHeaderProviders, Environment environment) {\n    return SCClientUtils.serviceCenterWatch(scConfigurationProperties2, authHeaderProviders, environment);\n  }\n\n  @Bean\n  public ServiceCenterClient serviceCenterClient2(\n      @Qualifier(\"scConfigurationProperties2\") SCConfigurationProperties scConfigurationProperties2,\n      Environment environment) {\n    return SCClientUtils.serviceCenterClient(scConfigurationProperties2, environment);\n  }\n\n  @Bean\n  public SC2Discovery sc2Discovery(\n      @Qualifier(\"scConfigurationProperties2\") SCConfigurationProperties scConfigurationProperties2,\n      @Qualifier(\"serviceCenterClient2\") ServiceCenterClient serviceCenterClient2) {\n    return new SC2Discovery(scConfigurationProperties2, serviceCenterClient2);\n  }\n\n  @Bean\n  public SC2Registration sc2Registration(\n      @Qualifier(\"scConfigurationProperties2\") SCConfigurationProperties scConfigurationProperties2,\n      @Qualifier(\"serviceCenterClient2\") ServiceCenterClient serviceCenterClient2,\n      @Qualifier(\"serviceCenterWatch2\") ServiceCenterWatch serviceCenterWatch2) {\n    return new SC2Registration(scConfigurationProperties2, serviceCenterClient2, serviceCenterWatch2);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/SC2Discovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport org.apache.servicecomb.registry.sc.SCConfigurationProperties;\nimport org.apache.servicecomb.registry.sc.SCConst;\nimport org.apache.servicecomb.registry.sc.SCDiscovery;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\n\npublic class SC2Discovery extends SCDiscovery {\n  public SC2Discovery(SCConfigurationProperties configurationProperties,\n      ServiceCenterClient serviceCenterClient) {\n    super(configurationProperties, serviceCenterClient);\n  }\n\n  @Override\n  public String name() {\n    return SCConst.SC_REGISTRY_NAME + \"2\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/SC2Registration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport org.apache.servicecomb.registry.sc.SCConfigurationProperties;\nimport org.apache.servicecomb.registry.sc.SCConst;\nimport org.apache.servicecomb.registry.sc.SCRegistration;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterWatch;\n\npublic class SC2Registration extends SCRegistration {\n  public SC2Registration(SCConfigurationProperties configurationProperties,\n      ServiceCenterClient serviceCenterClient, ServiceCenterWatch serviceCenterWatch) {\n    super(configurationProperties, serviceCenterClient, serviceCenterWatch);\n  }\n\n  @Override\n  public String name() {\n    return SCConst.SC_REGISTRY_NAME + 2;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/ServerATest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ServerATest implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"demo-multi-service-center-serverA\", schemaId = \"ServerEndpoint\")\n  private IServerEndpoint serverEndpoint;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    TestMgr.check(\"hello\", serverEndpoint.getName(\"hello\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/ServerBTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ServerBTest implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"demo-multi-service-center-serverB\", schemaId = \"ServerEndpoint\")\n  private IServerEndpoint serverEndpoint;\n\n  @RpcReference(microserviceName = \"demo-multi-service-center-serverB\", schemaId = \"ConfigurationEndpoint\")\n  private IConfigurationEndpoint configurationEndpoint;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    TestMgr.check(\"hello\", serverEndpoint.getName(\"hello\"));\n\n    TestMgr.check(\"key1-boot\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key1\", 1));\n    TestMgr.check(\"key1-boot\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key1\", 2));\n    TestMgr.check(\"key1-boot\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key1\", 3));\n    TestMgr.check(\"key2-override\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key2\", 1));\n    TestMgr.check(\"key2-override\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key2\", 2));\n    TestMgr.check(\"key2-override\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key2\", 3));\n    TestMgr.check(\"key3\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key3\", 1));\n    TestMgr.check(\"key3\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key3\", 2));\n    TestMgr.check(\"key3\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key3\", 3));\n    TestMgr.check(\"key4-boot\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key4\", 1));\n    TestMgr.check(\"key4-boot\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key4\", 2));\n    TestMgr.check(\"key4-boot\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key4\", 3));\n    TestMgr.check(\"key5-high\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key5\", 1));\n    TestMgr.check(\"key5-high\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key5\", 2));\n    TestMgr.check(\"key5-high\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key5\", 3));\n    TestMgr.check(\"key6\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key6\", 1));\n    TestMgr.check(\"key6\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key6\", 2));\n    TestMgr.check(\"key6\", configurationEndpoint.getValue(\"demo.multi.service.center.serverB.key6\", 3));\n    TestMgr.check(Arrays.asList(\"key71\", \"key72\"),\n        configurationEndpoint.getValueList(\"demo.multi.service.center.serverB.key7\", 1));\n    TestMgr.check(Arrays.asList(\"key71\", \"key72\"),\n        configurationEndpoint.getValueList(\"demo.multi.service.center.serverB.key7\", 2));\n  }\n\n  @Override\n  public String getMicroserviceName() {\n    return \"demo-multi-service-center-serverB\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: demo-multi-service-center\n    name: demo-multi-service-center-client\n    version: 0.0.2\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n    sc2:\n      address: http://127.0.0.1:40100\n\n  transport:\n    eventloop:\n      size: 6\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-client/src/test/java/org/apache/servicecomb/demo/multiServiceCenterClient/MultiServiceCenterIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterClient;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class MultiServiceCenterIT {\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    Application.main(new String[0]);\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverA/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-multi-service-center-servera</artifactId>\n  <name>Java Chassis::Demo::Multi Service Centers::ServerA</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multi-service-center</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiServiceCenter.ServerApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverA/src/main/java/org/apache/servicecomb/demo/multiServiceCenter/ServerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenter;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ServerApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(ServerApplication.class)\n        .web(WebApplicationType.SERVLET).build().run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverA/src/main/java/org/apache/servicecomb/demo/multiServiceCenter/ServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenter;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ServerEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ServerEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverA/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8080\n\nservicecomb:\n  service:\n    application: demo-multi-service-center\n    name: demo-multi-service-center-serverA\n    version: 0.0.2\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverA/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-multi-service-center-serverb</artifactId>\n  <name>Java Chassis::Demo::Multi Service Centers::ServerB</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multi-service-center</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiServiceCenterServerB.ServerApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/java/org/apache/servicecomb/demo/multiServiceCenterServerB/ConfigurationEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterServerB;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ConfigurationEndpoint\")\n@RequestMapping(path = \"/register/url/config\", produces = MediaType.APPLICATION_JSON)\npublic class ConfigurationEndpoint {\n  private static final Logger LOGGER\n      = LoggerFactory.getLogger(ServerEndpoint.class);\n\n  private Environment environment;\n\n  @Autowired\n  public ConfigurationEndpoint(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Value(\"${demo.multi.service.center.serverB.key1}\")\n  private String key1;\n\n  @Value(\"${demo.multi.service.center.serverB.key2}\")\n  private String key2;\n\n  @Value(\"${demo.multi.service.center.serverB.key3}\")\n  private String key3;\n\n  @Value(\"${demo.multi.service.center.serverB.key4}\")\n  private String key4;\n\n  @Value(\"${demo.multi.service.center.serverB.key5}\")\n  private String key5;\n\n  @Value(\"${demo.multi.service.center.serverB.key6}\")\n  private String key6;\n\n  @Value(\"${demo.multi.service.center.serverB.key7}\")\n  private List<String> key7;\n\n  @GetMapping(path = \"/config\")\n  public String getValue(@RequestParam(name = \"key\") String key, @RequestParam(name = \"type\") int type) {\n    if (type == 1) {\n      return environment.getProperty(key);\n    } else if (type == 2) {\n      return environment.getProperty(key);\n    } else {\n      switch (key) {\n        case \"demo.multi.service.center.serverB.key1\":\n          return key1;\n        case \"demo.multi.service.center.serverB.key2\":\n          return key2;\n        case \"demo.multi.service.center.serverB.key3\":\n          return key3;\n        case \"demo.multi.service.center.serverB.key4\":\n          return key4;\n        case \"demo.multi.service.center.serverB.key5\":\n          return key5;\n        case \"demo.multi.service.center.serverB.key6\":\n          return key6;\n        default:\n          return null;\n      }\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @GetMapping(path = \"/configList\")\n  public List<String> getValueList(@RequestParam(name = \"key\") String key, @RequestParam(name = \"type\") int type) {\n    if (type == 1) {\n      return environment.getProperty(key, List.class);\n    } else {\n      switch (key) {\n        case \"demo.multi.service.center.serverB.key7\":\n          return key7;\n        default:\n          return null;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/java/org/apache/servicecomb/demo/multiServiceCenterServerB/ServerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterServerB;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ServerApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(ServerApplication.class)\n        .web(WebApplicationType.SERVLET).build().run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/java/org/apache/servicecomb/demo/multiServiceCenterServerB/ServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiServiceCenterServerB;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ServerEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ServerEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/application.properties",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\ndemo.multi.service.center.serverB.actual.key6=key6\ndemo.multi.service.center.serverB.actual.key7.1=key71\ndemo.multi.service.center.serverB.actual.key7.2=key72\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8082\n\nservicecomb:\n  service:\n    application: demo-multi-service-center\n    name: demo-multi-service-center-serverB\n    version: 0.0.2\n  registry:\n    sc:\n      address: http://127.0.0.1:40100\n  rest:\n    address: 0.0.0.0:8082\n\ndemo.multi.service.center.serverB:\n  key1: key1-boot\n  key4: key4-boot\n  key5: key5\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/mapping.yaml",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n\ndemo.multi.service.center.serverB.actual.key5:\n  - demo.multi.service.center.serverB.key5\n"
  },
  {
    "path": "demo/demo-multi-service-center/demo-multi-service-center-serverB/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: 1\n\ndemo.multi.service.center.serverB:\n  key1: key1-override\n  key2: key2-override\n  key5: key5\n  actual:\n    key5: key5-high\n  key6: ${demo.multi.service.center.serverB.actual.key6}\n  key7:\n    - ${demo.multi.service.center.serverB.actual.key7.1}\n    - ${demo.multi.service.center.serverB.actual.key7.2}\n"
  },
  {
    "path": "demo/demo-multi-service-center/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-multi-service-center</artifactId>\n  <name>Java Chassis::Demo::Multi Service Centers</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-multi-service-center-serverA</module>\n    <module>demo-multi-service-center-serverB</module>\n    <module>demo-multi-service-center-client</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/a-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multiple</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>a-client</artifactId>\n  <name>Java Chassis::Demo::Multiple::A client</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiple.a.client.AClientMain</demo.main>\n  </properties>\n\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/a-client/src/main/java/org/apache/servicecomb/demo/multiple/a/client/AClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.a.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class AClient {\n  @RpcReference(microserviceName = \"${a-server.name}\", schemaId = \"a-hello\")\n  private AIntf intf;\n\n  public void run() {\n    String result = intf.hello(\"serviceComb\");\n    TestMgr.check(\"a hello serviceComb\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/a-client/src/main/java/org/apache/servicecomb/demo/multiple/a/client/AClientMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.a.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\npublic class AClientMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(AClientMain.class).web(WebApplicationType.NONE).run(args);\n\n    AClient client = BeanUtils.getContext().getBean(AClient.class);\n    client.run();\n\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/a-client/src/main/java/org/apache/servicecomb/demo/multiple/a/client/AIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.a.client;\n\npublic interface AIntf {\n  String hello(String name);\n}\n"
  },
  {
    "path": "demo/demo-multiple/a-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multiple/a-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\na-server.name: a-server\n\nservicecomb:\n  service:\n    application: multiple\n    name: a-client\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n"
  },
  {
    "path": "demo/demo-multiple/a-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multiple</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>a-server</artifactId>\n  <name>Java Chassis::Demo::Multiple::A server</name>\n\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiple.a.server.AServerMain</demo.main>\n  </properties>\n\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/a-server/src/main/java/org/apache/servicecomb/demo/multiple/a/server/AImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.a.server;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"a-hello\")\npublic class AImpl {\n  public String hello(String name) {\n    return \"a hello \" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/a-server/src/main/java/org/apache/servicecomb/demo/multiple/a/server/AServerMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.a.server;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\npublic class AServerMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(AServerMain.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/a-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multiple/a-server/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: multiple\n    name: a-server\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n  highway:\n    address: 0.0.0.0:7070\n"
  },
  {
    "path": "demo/demo-multiple/b-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multiple</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>b-client</artifactId>\n  <name>Java Chassis::Demo::Multiple::B client</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiple.b.client.BClientMain</demo.main>\n  </properties>\n\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/b-client/src/main/java/org/apache/servicecomb/demo/multiple/b/client/BClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.b.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class BClient {\n  @RpcReference(microserviceName = \"${b-server.name}\", schemaId = \"b-hello\")\n  private BIntf intf;\n\n  public void run() {\n    String result = intf.hello(\"serviceComb\");\n    TestMgr.check(\"b hello serviceComb\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/b-client/src/main/java/org/apache/servicecomb/demo/multiple/b/client/BClientMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.b.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\npublic class BClientMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(BClientMain.class).web(WebApplicationType.NONE).run(args);\n\n    BClient client = BeanUtils.getContext().getBean(BClient.class);\n    client.run();\n\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/b-client/src/main/java/org/apache/servicecomb/demo/multiple/b/client/BIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.b.client;\n\npublic interface BIntf {\n  String hello(String name);\n}\n"
  },
  {
    "path": "demo/demo-multiple/b-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multiple/b-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nb-server.name: b-server\n\nservicecomb:\n  service:\n    application: multiple\n    name: b-client\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n"
  },
  {
    "path": "demo/demo-multiple/b-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multiple</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>b-server</artifactId>\n  <name>Java Chassis::Demo::Multiple::B server</name>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiple.b.server.BServerMain</demo.main>\n  </properties>\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/b-server/src/main/java/org/apache/servicecomb/demo/multiple/b/server/BImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.b.server;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"b-hello\")\npublic class BImpl {\n  public String hello(String name) {\n    return \"b hello \" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/b-server/src/main/java/org/apache/servicecomb/demo/multiple/b/server/BServerMain.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.b.server;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\npublic class BServerMain {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(BServerMain.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/b-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multiple/b-server/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: multiple\n    name: b-server\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n  highway:\n    address: 0.0.0.0:7070\n"
  },
  {
    "path": "demo/demo-multiple/multiple-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multiple</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>multiple-client</artifactId>\n  <name>Java Chassis::Demo::Multiple::Client</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>a-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>b-client</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiple.client.MultipleClient</demo.main>\n  </properties>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>multiple-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/multiple-client/src/main/java/org/apache/servicecomb/demo/multiple/client/MultipleClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.multiple.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.multiple.a.client.AClient;\nimport org.apache.servicecomb.demo.multiple.b.client.BClient;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(basePackages = {\"org.apache.servicecomb.demo.multiple.a.client\",\n    \"org.apache.servicecomb.demo.multiple.b.client\"})\npublic class MultipleClient {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(MultipleClient.class).web(WebApplicationType.NONE).run(args);\n\n    runTest();\n  }\n\n  public static void runTest() {\n    AClient aClient = BeanUtils.getContext().getBean(AClient.class);\n    BClient bClient = BeanUtils.getContext().getBean(BClient.class);\n\n    aClient.run();\n    bClient.run();\n\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/multiple-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multiple/multiple-client/src/main/resources/microservice.yaml",
    "content": "﻿## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: 1000\na-server.name: merged-server\nb-server.name: merged-server\n\nservicecomb:\n  service:\n    application: multiple\n    name: merged-client\n    version: 0.0.1\n"
  },
  {
    "path": "demo/demo-multiple/multiple-client/src/test/java/org/apache/servicecomb/demo/multiple/client/MultipleIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiple.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = MultipleClient.class)\npublic class MultipleIT {\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    MultipleClient.runTest();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/multiple-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-multiple</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>multiple-server</artifactId>\n  <name>Java Chassis::Demo::Multiple::Server</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>a-server</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>b-server</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.multiple.server.MultipleServer</demo.main>\n  </properties>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-multiple/multiple-server/src/main/java/org/apache/servicecomb/demo/multiple/server/MultipleServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.multiple.server;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(basePackages = {\"org.apache.servicecomb.demo.multiple.a.server\",\n    \"org.apache.servicecomb.demo.multiple.b.server\"})\npublic class MultipleServer {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(MultipleServer.class).web(WebApplicationType.NONE).run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-multiple/multiple-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-multiple/multiple-server/src/main/resources/microservice.yaml",
    "content": "﻿## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: 1000\n\nservicecomb:\n  service:\n    application: multiple\n    name: merged-server\n    version: 0.0.1\n"
  },
  {
    "path": "demo/demo-multiple/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-multiple</artifactId>\n  <name>Java Chassis::Demo::Multiple</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>a-server</module>\n    <module>a-client</module>\n    <module>b-server</module>\n    <module>b-client</module>\n    <module>multiple-server</module>\n    <module>multiple-client</module>\n  </modules>\n\n  <dependencyManagement>\n    <dependencies>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>a-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>a-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>b-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>b-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "demo/demo-nacos/README.md",
    "content": "# Notice\n\nThis integration tests is designed for Nacos registry and configuration. And extra test cases include:\n\n* Test cases related to JAX-RS annotations that demo-jaxrs can not cover.\n"
  },
  {
    "path": "demo/demo-nacos/consumer/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-nacos</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>nacos-consumer</artifactId>\n  <name>Java Chassis::Demo::NACOS::CONSUMER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-nacos</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsumerApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsumerApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ConsumerController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerController {\n  @RpcReference(schemaId = \"ProviderController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  // consumer service which delegate the implementation to provider service.\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return providerService.sayHello(name);\n  }\n\n  @GetMapping(\"/authIncludePath\")\n  public String authIncludePath() {\n    return providerService.authIncludePath();\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchema;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"ConsumerHeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchema.class)\npublic class ConsumerHeaderParamWithListSchema implements IHeaderParamWithListSchema {\n  @RpcReference(microserviceName = \"provider\", schemaId = \"HeaderParamWithListSchema\")\n  private IHeaderParamWithListSchema provider;\n\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return provider.headerListDefault(headerList);\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return provider.headerListCSV(headerList);\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return provider.headerListMULTI(headerList);\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return provider.headerListSSV(headerList);\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return provider.headerListPIPES(headerList);\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface ProviderService {\n  String sayHello(String name);\n\n  String authIncludePath();\n}\n"
  },
  {
    "path": "demo/demo-nacos/consumer/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-nacos\n    version: 0.0.1\n    name: consumer\n  registry:\n    nacos:\n      serverAddr: ${PAAS_CSE_NACOS_ENDPOINT:http://127.0.0.1:8848}\n      metadata:\n        group: red\n\n  rest:\n    address: 0.0.0.0:9092\n\n  publicKey:\n    accessControl:\n      enabled: true\n      excludePathPatterns: '/*'\n"
  },
  {
    "path": "demo/demo-nacos/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-nacos/gateway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-nacos</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>nacos-gateway</artifactId>\n  <name>Java Chassis::Demo::NACOS::GATEWAY</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-nacos</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-nacos/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class GatewayApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/gateway/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-nacos\n    version: 0.0.1\n    name: gateway\n  registry:\n    nacos:\n      enabled: true\n      serverAddr: ${PAAS_CSE_NACOS_ENDPOINT:http://127.0.0.1:8848}\n\n  rest:\n    address: 0.0.0.0:9090?sslEnabled=false\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n"
  },
  {
    "path": "demo/demo-nacos/gateway/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-nacos/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-nacos</artifactId>\n  <name>Java Chassis::Demo::NACOS</name>\n  <packaging>pom</packaging>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>provider</module>\n    <module>consumer</module>\n    <module>gateway</module>\n    <module>test-client</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "demo/demo-nacos/provider/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-nacos</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>nacos-provider</artifactId>\n  <name>Java Chassis::Demo::NACOS::PROVIDER</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-nacos</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchema;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"HeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchema.class)\npublic class HeaderParamWithListSchema implements IHeaderParamWithListSchema {\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/ProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController {\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return \"Hello \" + name;\n  }\n\n  @GetMapping(\"/authIncludePath\")\n  public String authIncludePath() {\n    return \"success.\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/provider/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# spring boot configurations\nservicecomb:\n  service:\n    application: demo-nacos\n    version: 0.0.1\n    name: provider\n  registry:\n    nacos:\n      enabled: true\n      serverAddr: ${PAAS_CSE_NACOS_ENDPOINT:http://127.0.0.1:8848}\n      metadata:\n        group: green\n\n  rest:\n    address: 0.0.0.0:9094\n\n  publicKey:\n    accessControl:\n      enabled: true\n      includePathPatterns: '/authIncludePath'\n      black:\n        authPath:\n          category: property\n          propertyName: serviceName\n          rule: consumer*\n"
  },
  {
    "path": "demo/demo-nacos/provider/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-nacos/test-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-nacos</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>nacos-test-client</artifactId>\n  <name>Java Chassis::Demo::NACOS::TEST-CLIENT</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>nacos/nacos-server:v2.1.2-slim</name>\n                    <alias>nacos-server</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <MODE>standalone</MODE>\n                        <PREFER_HOST_MODE>hostname</PREFER_HOST_MODE>\n                      </env>\n                      <wait>\n                        <log>Tomcat started on port</log>\n                        <tcp>\n                          <ports>\n                            <port>8848</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>nacos-server.port:8848</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>nacos-provider:${project.version}</name>\n                    <alias>nacos-provider</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.nacos.serverAddr=http://nacos-server:8848\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/nacos-provider-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>nacos-server:nacos-server</link>\n                      </links>\n                      <wait>\n                        <log>Nacos is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9094</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9094:9094</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>nacos-consumer:${project.version}</name>\n                    <alias>nacos-consumer</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.nacos.serverAddr=http://nacos-server:8848\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/nacos-consumer-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>nacos-server:nacos-server</link>\n                      </links>\n                      <wait>\n                        <log>Nacos is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9092</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9092:9092</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>nacos-gateway:${project.version}</name>\n                    <alias>nacos-gateway</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.nacos.serverAddr=http://nacos-server:8848\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/nacos-gateway-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>nacos-server:nacos-server</link>\n                      </links>\n                      <wait>\n                        <log>Nacos is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9090:9090</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface Config {\n  String GATEWAY_URL = \"http://localhost:9090\";\n}\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HeaderParamWithListSchemaIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHeaderListDefault();\n    testHeaderListMulti();\n    testHeaderListCSV();\n    testHeaderListSSV();\n    testHeaderListPipes();\n  }\n\n  // default to multi\n  private void testHeaderListDefault() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListDefault\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListPipes() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a|b|c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListPIPES\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListSSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a b c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListSSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListCSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a,b,c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n\n    headers.add(\"headerList\", \"a, b, c\");\n    entity = new HttpEntity<>(headers);\n    result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListMulti() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListMULTI\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HelloWorldIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHelloWorld();\n    testAuthIncludePath();\n  }\n\n  private void testHelloWorld() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/sayHello?name=World\", String.class);\n    TestMgr.check(\"Hello World\", result);\n  }\n\n  private void testAuthIncludePath() {\n    String result = \"\";\n    try {\n      result = template.getForObject(Config.GATEWAY_URL + \"/authIncludePath\", String.class);\n    } catch (Exception e) {\n      result = \"failed\";\n    }\n    TestMgr.check(\"failed\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class TestClientApplication {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args);\n\n      run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"consumer\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-nacos\n    name: test-client\n    version: 0.0.1\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-nacos/test-client/src/test/java/org/apache/servicecomb/samples/NocasIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = TestClientApplication.class)\npublic class NocasIT {\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    TestClientApplication.run();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-pojo</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>pojo-client</artifactId>\n  <name>Java Chassis::Demo::POJO::Client</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.pojo.client.PojoClient</demo.main>\n  </properties>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>pojo-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/BeanRpcTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport org.apache.servicecomb.demo.server.Test;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\n\npublic class BeanRpcTest {\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"server\")\n  private Test test;\n\n  public BeanRpcTest() {\n    System.out.println(\"init\");\n  }\n\n  public void init() {\n    new Thread(() -> {\n      while (true) {\n        try {\n          System.out.println(\"XXXXXXXXXXXXXXXXXXXXXXXX\" + test.getTestString(null));\n          break;\n        } catch (Exception e) {\n          e.printStackTrace();\n          try {\n            Thread.sleep(1000);\n          } catch (InterruptedException e1) {\n            e1.printStackTrace();\n          }\n          continue;\n        } catch (Throwable e) {\n          System.out.println(\"XXXXXXXXXXXXXXXXXXXXXXXX: teset case error\");\n          e.printStackTrace();\n          System.exit(0);\n        }\n      }\n    }).start();\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/ClientInterfaceForServerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport org.apache.servicecomb.demo.server.TestRequest;\nimport org.apache.servicecomb.demo.server.User;\n\npublic interface ClientInterfaceForServerTest {\n    User splitParam(int nameNotIndex, User user);\n\n    User wrapParam(TestRequest nameNotRequest);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.CountDownLatch;\n\nimport javax.inject.Inject;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.CodeFirstPojoIntf;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.mapnull.ParseRequest;\nimport org.apache.servicecomb.demo.mapnull.ParseResponse;\nimport org.apache.servicecomb.demo.server.MapModel;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.stereotype.Component;\n\nimport io.vertx.core.Vertx;\n\n@Component\npublic class CodeFirstPojoClient implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"org.apache.servicecomb.demo.CodeFirstPojoIntf\")\n  public CodeFirstPojoClientIntf codeFirstAnnotation;\n\n  @RpcReference(microserviceName = \"pojo\")\n  public CodeFirstPojoIntf codeFirstAnnotationEmptySchemaId;\n\n  @Inject\n  private CodeFirstPojoIntf codeFirstFromXml;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testOnlyRest(codeFirstAnnotation);\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testAll(codeFirstAnnotation);\n    testAll(codeFirstAnnotationEmptySchemaId);\n    testAll(codeFirstFromXml);\n  }\n\n  private void testOnlyRest(CodeFirstPojoIntf codeFirst) {\n    testCodeFirstStrings(codeFirst);\n  }\n\n  private void testAll(CodeFirstPojoIntf codeFirst) {\n    remoteCodeFirstPojo_testParseResponse(codeFirst);\n    remoteCodeFirstPojo_testMapModel(codeFirst);\n    remoteCodeFirstPojo_testMap(codeFirst);\n    testCodeFirstUserMap(codeFirst);\n    testCodeFirstUserArray(codeFirst);\n    testCodeFirstStrings(codeFirst);\n    testCodeFirstBytes(codeFirst);\n    testCodeFirstAddDate(codeFirst);\n    testCodeFirstAddString(codeFirst);\n    testCodeFirstIsTrue(codeFirst);\n    testCodeFirstSayHi2(codeFirst);\n    testCodeFirstSayHi(codeFirst);\n    testCodeFirstSaySomething(codeFirst);\n    //            testCodeFirstRawJsonString(template, cseUrlPrefix);\n    testCodeFirstSayHello(codeFirst);\n    testCodeFirstReduce(codeFirst);\n    testCodeFirstCompletableFuture(codeFirst);\n  }\n\n  private void testCodeFirstCompletableFuture(CodeFirstPojoIntf codeFirst) {\n    if (!CodeFirstPojoClientIntf.class.isInstance(codeFirst)) {\n      return;\n    }\n\n    Vertx vertx = VertxUtils.getOrCreateVertxByName(\"transport\", null, null);\n    CountDownLatch latch = new CountDownLatch(1);\n    // vertx.runOnContext in normal thread is not a good practice\n    // here just a test, not care for this.\n    vertx.runOnContext(V -> {\n      InvocationContext context = new InvocationContext();\n      context.addContext(\"k\", \"v\");\n      ContextUtils.setInvocationContext(context);\n\n      ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync(\"someone\")\n          .thenCompose(result -> {\n            TestMgr.check(\"someone sayhi, context k: v\", result);\n\n            // new call need set invocation context implicitly or will not\n            // inherit parent context\n            ContextUtils.setInvocationContext(context);\n\n            return ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync(\"someone 1\");\n          })\n          .whenComplete((r, e) -> {\n            TestMgr.check(\"someone 1 sayhi, context k: v\", r);\n            latch.countDown();\n          });\n\n      ContextUtils.removeInvocationContext();\n    });\n\n    try {\n      latch.await();\n    } catch (InterruptedException e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  private void remoteCodeFirstPojo_testParseResponse(CodeFirstPojoIntf codeFirst) {\n    ParseResponse r = codeFirst.parse(new ParseRequest());\n    TestMgr.check(\"\", r.getMsgHeader().get(\"K16\"));\n    TestMgr.check(\"CMT\", r.getMsgHeader().get(\"K14\"));\n  }\n\n  private void remoteCodeFirstPojo_testMapModel(CodeFirstPojoIntf codeFirst) {\n    MapModel model = new MapModel();\n    model.setName(\"hello\");\n    Map<String, String> userMap = new HashMap<>();\n    userMap.put(\"u1\", \"u1\");\n    userMap.put(\"u2\", null);\n    model.setNames(userMap);\n    MapModel result = codeFirst.testMapModel(model);\n\n    TestMgr.check(result.getName(), \"hello\");\n    TestMgr.check(result.getNames().get(\"u1\"), \"u1\");\n    TestMgr.check(result.getNames().get(\"u2\"), null);\n\n    model = new MapModel();\n    model.setName(null);\n    userMap = new HashMap<>();\n    userMap.put(\"u1\", \"u1\");\n    userMap.put(\"u2\", null);\n    model.setNames(userMap);\n    result = codeFirst.testMapModel(model);\n\n    TestMgr.check(result.getName(), null);\n    TestMgr.check(result.getNames().get(\"u1\"), \"u1\");\n    TestMgr.check(result.getNames().get(\"u2\"), null);\n\n    model = new MapModel();\n    model.setName(null);\n    userMap = new HashMap<>();\n    userMap.put(\"u1\", \"u1\");\n    userMap.put(\"u2\", \"\");\n    model.setNames(userMap);\n    result = codeFirst.testMapModel(model);\n\n    TestMgr.check(result.getName(), null);\n    TestMgr.check(result.getNames().get(\"u1\"), \"u1\");\n    TestMgr.check(result.getNames().get(\"u2\"), \"\");\n  }\n\n  private void remoteCodeFirstPojo_testMap(CodeFirstPojoIntf codeFirst) {\n    Map<String, String> userMap = new HashMap<>();\n    userMap.put(\"u1\", \"u1\");\n    userMap.put(\"u2\", null);\n    Map<String, String> result = codeFirst.testMap(userMap);\n\n    TestMgr.check(result.get(\"u1\"), \"u1\");\n    TestMgr.check(result.get(\"u2\"), null);\n\n    userMap = new HashMap<>();\n    userMap.put(\"u1\", \"u1\");\n    userMap.put(\"u2\", \"u2\");\n    result = codeFirst.testMap(userMap);\n\n    TestMgr.check(result.get(\"u1\"), \"u1\");\n    TestMgr.check(result.get(\"u2\"), \"u2\");\n\n    // test large data more than 20M\n    // can not run the test case in CI , because will cause heap size limit\n//    char[] data = new char[30 * 1024 * 1024];\n//    Arrays.fill(data, 'h');\n//    userMap = new HashMap<>();\n//    userMap.put(\"u1\", \"u1\");\n//    userMap.put(\"u2\", \"u2\");\n//    userMap.put(\"u3\", new String(data));\n//    result = codeFirst.testMap(userMap);\n//\n//    TestMgr.check(result.get(\"u1\"), \"u1\");\n//    TestMgr.check(result.get(\"u2\"), \"u2\");\n//    TestMgr.check(result.get(\"u3\"), new String(data));\n  }\n\n  private void testCodeFirstUserMap(CodeFirstPojoIntf codeFirst) {\n    User user1 = new User();\n    user1.setNames(new String[] {\"u1\", \"u2\"});\n\n    User user2 = new User();\n    user2.setNames(new String[] {\"u3\", \"u4\"});\n\n    Map<String, User> userMap = new HashMap<>();\n    userMap.put(\"u1\", user1);\n    userMap.put(\"u2\", user2);\n    Map<String, User> result = codeFirst.testUserMap(userMap);\n\n    TestMgr.check(\"u1\", result.get(\"u1\").getNames()[0]);\n    TestMgr.check(\"u2\", result.get(\"u1\").getNames()[1]);\n    TestMgr.check(\"u3\", result.get(\"u2\").getNames()[0]);\n    TestMgr.check(\"u4\", result.get(\"u2\").getNames()[1]);\n\n    userMap = new HashMap<>();\n    userMap.put(\"u1\", user1);\n    userMap.put(\"u2\", null);\n    result = codeFirst.testUserMap(userMap);\n\n    TestMgr.check(result.get(\"u1\").getNames()[0], \"u1\");\n    TestMgr.check(result.get(\"u1\").getNames()[1], \"u2\");\n    TestMgr.check(result.get(\"u2\"), null);\n  }\n\n  private void testCodeFirstUserArray(CodeFirstPojoIntf codeFirst) {\n    User user1 = new User();\n    user1.setNames(new String[] {\"u1\", \"u2\"});\n\n    User user2 = new User();\n    user2.setNames(new String[] {\"u3\", \"u4\"});\n\n    User[] users = new User[] {user1, user2};\n    List<User> result = codeFirst.testUserArray(Arrays.asList(users));\n    TestMgr.check(\"u1\", result.get(0).getNames()[0]);\n    TestMgr.check(\"u2\", result.get(0).getNames()[1]);\n    TestMgr.check(\"u3\", result.get(1).getNames()[0]);\n    TestMgr.check(\"u4\", result.get(1).getNames()[1]);\n  }\n\n  private void testCodeFirstStrings(CodeFirstPojoIntf codeFirst) {\n    String[] result = codeFirst.testStrings(new String[] {\"a\", \"b\"});\n    TestMgr.check(\"aa0\", result[0]);\n    TestMgr.check(\"b\", result[1]);\n\n    result = codeFirst.testStrings(new String[] {\"a\", \"\"});\n    TestMgr.check(\"aa0\", result[0]);\n    TestMgr.check(\"\", result[1]);\n  }\n\n  private void testCodeFirstBytes(CodeFirstPojoIntf codeFirst) {\n    byte[] input = new byte[] {0, 1, 2};\n    byte[] result = codeFirst.testBytes(input);\n    TestMgr.check(3, result.length);\n    TestMgr.check(1, result[0]);\n    TestMgr.check(1, result[1]);\n    TestMgr.check(2, result[2]);\n  }\n\n  private void testCodeFirstAddDate(CodeFirstPojoIntf codeFirst) {\n    Date date = new Date();\n    int seconds = 1;\n    Date result = codeFirst.addDate(date, seconds);\n    TestMgr.check(new Date(date.getTime() + seconds * 1000), result);\n  }\n\n  private void testCodeFirstAddString(CodeFirstPojoIntf codeFirst) {\n    String result = codeFirst.addString(Arrays.asList(\"a\", \"b\"));\n    TestMgr.check(\"ab\", result);\n  }\n\n  private void testCodeFirstIsTrue(CodeFirstPojoIntf codeFirst) {\n    boolean result = codeFirst.isTrue();\n    TestMgr.check(true, result);\n  }\n\n  private void testCodeFirstSayHi2(CodeFirstPojoIntf codeFirst) {\n    if (!CodeFirstPojoClientIntf.class.isInstance(codeFirst)) {\n      return;\n    }\n\n    String result = ((CodeFirstPojoClientIntf) codeFirst).sayHi2(\"world\");\n    TestMgr.check(\"world sayhi 2\", result);\n  }\n\n  private void testCodeFirstSayHi(CodeFirstPojoIntf codeFirst) {\n    String result = codeFirst.sayHi(\"world\");\n    TestMgr.check(\"world sayhi, context k: null\", result);\n    //        TestMgr.check(202, responseEntity.getStatusCode());\n  }\n\n  private void testCodeFirstSaySomething(CodeFirstPojoIntf codeFirst) {\n    Person person = new Person();\n    person.setName(\"person name\");\n\n    String result = codeFirst.saySomething(\"prefix  prefix\", person);\n    TestMgr.check(\"prefix  prefix person name\", result);\n  }\n\n  private void testCodeFirstSayHello(CodeFirstPojoIntf codeFirst) {\n    Person input = new Person();\n    input.setName(\"person name\");\n\n    Person result = codeFirst.sayHello(input);\n    TestMgr.check(\"hello person name\", result.getName());\n\n    input.setName(\"\");\n\n    result = codeFirst.sayHello(input);\n    TestMgr.check(\"hello \", result.getName());\n  }\n\n  private void testCodeFirstReduce(CodeFirstPojoIntf codeFirst) {\n    int result = codeFirst.reduce(5, 3);\n    TestMgr.check(2, result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClientIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.demo.CodeFirstPojoIntf;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\npublic interface CodeFirstPojoClientIntf extends CodeFirstPojoIntf {\n  @Operation(operationId = \"sayHi\", summary = \"\")\n  CompletableFuture<String> sayHiAsync(String name);\n\n  String sayHi2(String name);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.stream.IntStream;\n\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.DemoConst;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.Test;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.demo.smartcare.Application;\nimport org.apache.servicecomb.demo.smartcare.Group;\nimport org.apache.servicecomb.demo.smartcare.SmartCare;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.context.annotation.ImportResource;\n\n@SpringBootApplication\n@ImportResource(value = \"classpath*:META-INF/spring/*.bean.xml\")\npublic class PojoClient {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PojoClient.class);\n\n  // reference a not exist a microservice, and never use it\n  // this should not cause problems\n  @RpcReference(microserviceName = \"notExist\")\n  public static Test notExist;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"server\")\n  public static Test test;\n\n  public static Test testFromXml;\n\n  private static SmartCare smartcare;\n\n  public static void setTestFromXml(Test testFromXml) {\n    PojoClient.testFromXml = testFromXml;\n  }\n\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(PojoClient.class).web(WebApplicationType.NONE).run(args);\n\n    try {\n      run();\n    } catch (Throwable e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n    LOGGER.info(\"-------------- last time updated checks(maybe more/less): 785 -------------\");\n  }\n\n  private static void testContextClassLoaderIsNull() throws Exception {\n    ForkJoinPool pool = new ForkJoinPool(4);\n    pool.submit(() ->\n        IntStream.range(0, 20).parallel().forEach(item -> {\n          if (Thread.currentThread().getName().equals(\"main\")) {\n            return;\n          }\n          // in web environment, this could be null, here we just mock a null class loader.\n          Thread.currentThread().setContextClassLoader(null);\n          TestMgr.check(null, test.postTestStatic(2));\n        })).get();\n  }\n\n  public static void run() throws Exception {\n    testHttpClientsIsOk();\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"pojo\");\n\n    smartcare = BeanUtils.getBean(\"smartcare\");\n    String microserviceName = \"pojo\";\n\n    for (String transport : DemoConst.transports) {\n      InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n      TestMgr.setMsg(microserviceName, transport);\n      LOGGER.info(\"test {}, transport {}\", microserviceName, transport);\n\n      testContextClassLoaderIsNull();\n      testNull(testFromXml);\n\n      boolean checkerDestroyed = true;\n      // Timer cancel may not destroy thread very fast so check for 3 times.\n      for (int i = 0; i < 3; i++) {\n        checkerDestroyed = true;\n        Set<Thread> allThreads = Thread.getAllStackTraces().keySet();\n        for (Thread t : allThreads) {\n          if (t.getName().equals(\"NFLoadBalancer-serverWeightTimer-unknown\")) {\n            checkerDestroyed = false;\n            Thread.sleep(1000);\n          }\n        }\n      }\n      TestMgr.check(checkerDestroyed, true);\n\n      testSmartCare(smartcare);\n\n      testCommonInvoke(transport);\n\n      if (\"rest\".equals(transport)) {\n        testTraceIdOnNotSetBefore();\n      }\n      testTraceIdOnContextContainsTraceId();\n    }\n  }\n\n  private static void testHttpClientsIsOk() {\n    TestMgr.check(HttpClients.getClient(\"config-center\") != null, false);\n    TestMgr.check(HttpClients.getClient(\"http-transport-client\") != null, false);\n    TestMgr.check(HttpClients.getClient(\"http2-transport-client\") != null, true);\n\n    TestMgr.check(HttpClients.getClient(\"config-center\", false) != null, false);\n    TestMgr.check(HttpClients.getClient(\"http-transport-client\", false) != null, false);\n    TestMgr.check(HttpClients.getClient(\"http2-transport-client\", false) != null, true);\n  }\n\n  /**\n   * Only in http transport, traceId will be set to invocation if null.\n   * But in highway, nothing done.\n   */\n  private static void testTraceIdOnNotSetBefore() {\n    String traceId = test.testTraceId();\n    TestMgr.checkNotEmpty(traceId);\n  }\n\n  private static void testTraceIdOnContextContainsTraceId() {\n    InvocationContext context = new InvocationContext();\n    context.addContext(CoreConst.TRACE_ID_NAME, String.valueOf(Long.MIN_VALUE));\n    ContextUtils.setInvocationContext(context);\n    String traceId = test.testTraceId();\n    TestMgr.check(String.valueOf(Long.MIN_VALUE), traceId);\n    ContextUtils.removeInvocationContext();\n  }\n\n  private static void testSmartCare(SmartCare smartCare) {\n    Group group = new Group();\n    group.setName(\"group0\");\n\n    Application application = new Application();\n    application.setName(\"app0\");\n    application.setDefaultGroup(\"group0\");\n    application.setVersion(\"v1\");\n    application.setDynamicFlag(true);\n    List<Group> groups = new ArrayList<>();\n    groups.add(group);\n    application.setGroups(groups);\n\n    TestMgr.check(\"resultCode: 0\\nresultMessage: add application app0 success\",\n        smartCare.addApplication(application));\n    TestMgr.check(\"resultCode: 1\\nresultMessage: delete application app0 failed\",\n        smartCare.delApplication(\"app0\"));\n  }\n\n  @SuppressWarnings(\"rawtypes\")\n  private static void testCommonInvoke(String transport) {\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"index\", 2);\n    arguments.put(\"user\", new User());\n    Map<String, Object> warpArguments = new HashMap<>();\n    warpArguments.put(\"splitParamBody\", arguments);\n    User result = InvokerUtils.syncInvoke(\"pojo\", \"server\",\n        \"splitParam\", warpArguments, User.class);\n    TestMgr.check(\"User [name=nameA,  users count:0, age=100, index=2]\", result);\n\n    arguments = new HashMap<>();\n    arguments.put(\"index\", 3);\n    arguments.put(\"user\", new User());\n    warpArguments = new HashMap<>();\n    warpArguments.put(\"splitParamBody\", arguments);\n    result =\n        InvokerUtils.syncInvoke(\"pojo\",\n            transport,\n            \"server\",\n            \"splitParam\",\n            warpArguments, User.class);\n    TestMgr.check(\"User [name=nameA,  users count:0, age=100, index=3]\", result);\n  }\n\n  private static void testNull(Test test) {\n    TestMgr.check(\"code is 'null'\", test.getTestString(null));\n    TestMgr.check(null, test.postTestStatic(2));\n    TestMgr.check(null, test.patchTestStatic(2));\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/SchemaInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\npublic interface SchemaInterface {\n  String echo(String content);\n\n  String echoError(String content);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/SchemeInterfacePojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\npublic interface SchemeInterfacePojo {\n  int reduce(int a, int b);\n\n  int add(int a, int b);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestFlowControl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.function.Function;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestFlowControl implements CategorizedTestCase {\n  interface Client {\n    int foo(int num);\n\n    int bar(int num);\n  }\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"FlowControlSchema\")\n  Client client1;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"FlowControlClientSchema\")\n  Client client2;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testFlowControl((num) -> client1.foo(num), \"provider\", true);\n    testFlowControl((num) -> client1.bar(num), \"provider\", false);\n    testFlowControl((num) -> client2.foo(num), \"consumer\", true);\n    testFlowControl((num) -> client2.bar(num), \"consumer\", false);\n  }\n\n  private void testFlowControl(Function<Integer, Integer> function, String role, boolean expected)\n      throws InterruptedException {\n    AtomicBoolean failed = new AtomicBoolean(false);\n    CountDownLatch countDownLatch = new CountDownLatch(10);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        for (int i1 = 0; i1 < 10; i1++) {\n          try {\n            int result = function.apply(10);\n            if (result != 10) {\n              TestMgr.failed(\"\", new Exception(\"not expected\"));\n            }\n          } catch (InvocationException e) {\n            TestMgr.check(e.getStatusCode(), 429);\n            TestMgr.check(((CommonExceptionData) e.getErrorData()).getMessage(),\n                role + \" request rejected by flow control.\");\n            failed.set(true);\n            break;\n          } catch (Throwable e) {\n            e.printStackTrace();\n            TestMgr.fail(\"not expected error \" + e.getMessage());\n          }\n        }\n        countDownLatch.countDown();\n      }).start();\n    }\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(expected, failed.get());\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestNotRecommendedService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.AbstractModel;\nimport org.apache.servicecomb.demo.server.DefaultAbstractModel;\nimport org.apache.servicecomb.demo.server.NotRecommendedServiceInf;\nimport org.apache.servicecomb.demo.server.SecondAbstractModel;\nimport org.apache.servicecomb.demo.server.WrappedAbstractModel;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestNotRecommendedService implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"NotRecommendedService\")\n  private NotRecommendedServiceInf pojo;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testLongMap();\n    testAbstractModel();\n    testListAbstractModel();\n    testMapAbstractModel();\n    testWrappedModel();\n  }\n\n  private void testWrappedModel() {\n    Map<Long, AbstractModel> data = new HashMap<>();\n    AbstractModel model = new DefaultAbstractModel();\n    model.setName(\"hello\");\n    data.put(100L, model);\n\n    List<AbstractModel> data2 = new ArrayList<>();\n\n    AbstractModel model2 = new DefaultAbstractModel();\n    model2.setName(\"hello\");\n    data2.add(model2);\n\n    WrappedAbstractModel input = new WrappedAbstractModel();\n    input.setMapModel(data);\n    input.setListModel(data2);\n    AbstractModel secondModel = new SecondAbstractModel();\n    secondModel.setName(\"second\");\n    input.setModel(secondModel);\n    input.setName(\"wrapped\");\n\n    WrappedAbstractModel result = pojo.wrappedAbstractModel(input);\n\n    TestMgr.check(1, result.getMapModel().size());\n    TestMgr.check(\"hello\", result.getMapModel().get(result.getMapModel().keySet().iterator().next()).getName());\n\n    TestMgr.check(1, result.getListModel().size());\n    TestMgr.check(\"hello\", result.getListModel().get(0).getName());\n\n    TestMgr.check(\"second\", result.getModel().getName());\n    TestMgr.check(true, result.getModel() instanceof SecondAbstractModel);\n    TestMgr.check(\"wrapped\", result.getName());\n  }\n\n  private void testMapAbstractModel() {\n    Map<Long, AbstractModel> data = new HashMap<>();\n    AbstractModel model = new DefaultAbstractModel();\n    model.setName(\"hello\");\n    data.put(100L, model);\n    Map<Long, AbstractModel> result = pojo.mapAbstractModel(data);\n    TestMgr.check(1, result.size());\n    TestMgr.check(\"hello\", result.get(result.keySet().iterator().next()).getName());\n  }\n\n  private void testListAbstractModel() {\n    List<AbstractModel> data = new ArrayList<>();\n    AbstractModel model = new DefaultAbstractModel();\n    model.setName(\"hello\");\n    data.add(model);\n    List<AbstractModel> result = pojo.listAbstractModel(data);\n    TestMgr.check(1, result.size());\n    TestMgr.check(\"hello\", result.get(0).getName());\n  }\n\n  private void testAbstractModel() {\n    AbstractModel model = new DefaultAbstractModel();\n    model.setName(\"hello\");\n\n    AbstractModel result = pojo.abstractModel(model);\n    TestMgr.check(\"hello\", result.getName());\n  }\n\n  private void testLongMap() {\n    Map<Long, Long> data = new HashMap<>();\n    data.put(100L, 200L);\n    Map<Long, Long> result = pojo.longMap(data);\n    TestMgr.check(1, result.size());\n    TestMgr.check(200L, result.get(100L));\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestRpcReferenceMethodInjection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestRpcReferenceMethodInjection implements CategorizedTestCase {\n\n  private SchemeInterfacePojo pojo;\n\n  private SchemeInterfacePojo pojoValue;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SchemeInterfacePojoImpl\")\n  public void setSchemeInterfacePojo(SchemeInterfacePojo pojo) {\n    this.pojo = pojo;\n  }\n\n  @RpcReference(microserviceName = \"${servicecomb.provider.name}\", schemaId = \"SchemeInterfacePojoImpl\")\n  public void setSchemeInterfacePojoValue(SchemeInterfacePojo pojoValue) {\n    this.pojoValue = pojoValue;\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    TestMgr.check(-1, pojo.reduce(1, 2));\n    TestMgr.check(-1, pojoValue.reduce(1, 2));\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestSameService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.servers.Server;\n\n@Component\npublic class TestSameService implements CategorizedTestCase {\n  @OpenAPIDefinition(servers = {@Server(url = \"/SameInterface1\")})\n  public interface SameInterface1 {\n    String sayHello(String name);\n  }\n\n  @OpenAPIDefinition(servers = {@Server(url = \"/SameInterface2\")})\n  public interface SameInterface2 {\n    String sayHello(String name);\n  }\n\n  @OpenAPIDefinition(servers = {@Server(url = \"/SameService1\")})\n  public interface SameService1 {\n    String sayHello(String name);\n  }\n\n  @OpenAPIDefinition(servers = {@Server(url = \"/SameService2\")})\n  public interface SameService2 {\n    String sayHello(String name);\n  }\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SameService1\")\n  SameService1 sameService1;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SameService2\")\n  SameService2 sameService2;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SameInterface1\")\n  SameInterface1 sameInterface1;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SameInterface2\")\n  SameInterface2 sameInterface2;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    TestMgr.check(\"pk1-svc-1\", sameService1.sayHello(\"1\"));\n    TestMgr.check(\"pk2-svc-1\", sameService2.sayHello(\"1\"));\n    TestMgr.check(\"pk1-inf-1\", sameInterface1.sayHello(\"1\"));\n    TestMgr.check(\"pk2-inf-1\", sameInterface2.sayHello(\"1\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestSchemeInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestSchemeInterface implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SchemaInterface\")\n  private SchemaInterface pojo;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    TestMgr.check(\"hello\", pojo.echo(\"hello\"));\n\n    try {\n      pojo.echoError(\"hello\");\n      TestMgr.failed(\"should throw exception\", new Exception());\n    } catch (InvocationException e) {\n      TestMgr.check(\n          \"Consumer method org.apache.servicecomb.demo.pojo.client.SchemaInterface:\"\n              + \"echoError not exist in contract, microserviceName=pojo, schemaId=SchemaInterface.\",\n          ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestSchemeInterfacePojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestSchemeInterfacePojo implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"SchemeInterfacePojoImpl\")\n  private SchemeInterfacePojo pojo;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    TestMgr.check(-1, pojo.reduce(1, 2));\n\n    try {\n      pojo.add(1, 2);\n      TestMgr.failed(\"should throw exception\", new Exception());\n    } catch (InvocationException e) {\n      TestMgr.check(\n          \"Consumer method org.apache.servicecomb.demo.pojo.client.SchemeInterfacePojo:\"\n              + \"add not exist in contract, microserviceName=pojo, \"\n              + \"schemaId=SchemeInterfacePojoImpl.\",\n          ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestTestImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.Test;\nimport org.apache.servicecomb.demo.server.TestRequest;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestTestImpl implements CategorizedTestCase {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestTestImpl.class);\n\n  private static final byte[] buffer = new byte[1024];\n\n  static {\n    Arrays.fill(buffer, (byte) 1);\n  }\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"server\")\n  private Test test;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testNull(test);\n\n    // This test case shows destroy of WeightedResponseTimeRule timer task. after test finished will not print:\n    // \"Weight adjusting job started\" and thread \"NFLoadBalancer-serverWeightTimer-unknown\" destroyed.\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.loadbalance.strategy.name\", \"WeightedResponse\");\n    testStringArray(test);\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.loadbalance.strategy.name\", \"RoundRobin\");\n    testStringArray(test);\n\n    testChinese(test);\n    testStringHaveSpace(test);\n    testWrapParam(test);\n\n    testSplitParam(test);\n    testInputArray(test);\n\n    testException(test);\n\n    testIntArray(test);\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testNullRest(test);\n    testExceptionRest(test);\n    testEmptyRest(test);\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n    testNullHighway(test);\n    testEmptyHighway(test);\n  }\n\n  private static void testIntArray(Test test) {\n    int[] request = new int[] {5, 11, 4};\n    int[] result = test.testIntArray(request);\n    TestMgr.check(request.length, result.length);\n    TestMgr.check(request[1], result[1]);\n  }\n\n  private static void testEmptyHighway(Test test) {\n    TestMgr.check(\"code is ''\", test.getTestString(\"\"));\n  }\n\n  private static void testEmptyRest(Test test) {\n    TestMgr.check(\"code is ''\", test.getTestString(\"\"));\n  }\n\n  private static void testNullRest(Test test) {\n    TestMgr.check(null, test.wrapParam(null));\n  }\n\n  private static void testNullHighway(Test test) {\n    TestMgr.check(\"nameA\", test.wrapParam(null).getName());\n  }\n\n  private static void testNull(Test test) {\n    TestMgr.check(\"code is 'null'\", test.getTestString(null));\n    TestMgr.check(null, test.postTestStatic(2));\n    TestMgr.check(null, test.patchTestStatic(2));\n  }\n\n  private static void testChinese(Test test) {\n    TestMgr.check(\"code is '测试'\", test.getTestString(\"测试\"));\n\n    User user = new User();\n    user.setName(\"名字\");\n    User result = test.splitParam(1, user);\n    TestMgr.check(\"名字,  users count:0\", result.getName());\n  }\n\n  private static void testStringHaveSpace(Test test) {\n    TestMgr.check(\"code is 'a b'\", test.getTestString(\"a b\"));\n  }\n\n  private static void testStringArray(Test test) {\n    //        TestMgr.check(\"arr is '[a, , b]'\", test.testStringArray(new String[] {\"a\", null, \"b\"}));\n    TestMgr.check(\"arr is '[a, b]'\", test.testStringArray(new String[] {\"a\", \"b\"}));\n  }\n\n  private static void testWrapParam(Test test) {\n    User user = new User();\n\n    TestRequest request = new TestRequest();\n    request.setUser(user);\n    request.setIndex(0);\n    request.setData(buffer);\n    request.getUsers().add(user);\n\n    User result = test.wrapParam(request);\n    LOGGER.info(\"wrap param result:{}\", result);\n\n    TestMgr.check(\"User [name=nameA,  users count:1, age=100, index=0]\", result);\n  }\n\n\n  private static void testExceptionRest(Test test) {\n    try {\n      test.testException(456);\n    } catch (InvocationException e) {\n      TestMgr.check(\"456 error\", e.getErrorData());\n    }\n\n    try {\n      test.testException(556);\n    } catch (InvocationException e) {\n      TestMgr.check(\"[556 error]\", e.getErrorData());\n    }\n\n    try {\n      test.testException(557);\n    } catch (InvocationException e) {\n      TestMgr.check(\"[[557 error]]\", e.getErrorData());\n    }\n  }\n\n  private static void testException(Test test) {\n    try {\n      test.testException(456);\n    } catch (InvocationException e) {\n      TestMgr.check(\"456 error\", e.getErrorData());\n    }\n\n    try {\n      test.testException(556);\n    } catch (InvocationException e) {\n      TestMgr.check(\"[556 error]\", e.getErrorData());\n    }\n\n    try {\n      test.testException(557);\n    } catch (InvocationException e) {\n      TestMgr.check(\"[[557 error]]\", e.getErrorData());\n    }\n  }\n\n  private static void testInputArray(Test test) {\n    String result = test.addString(new String[] {\"a\", \"b\"});\n    LOGGER.info(\"input array result:{}\", result);\n    TestMgr.check(\"[a, b]\", result);\n  }\n\n  private static void testSplitParam(Test test) {\n    User result = test.splitParam(1, new User());\n    LOGGER.info(\"split param result:{}\", result);\n    TestMgr.check(\"User [name=nameA,  users count:0, age=100, index=1]\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestWeakPojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.GenericsModel;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\n\n/*\nThis is the provider definition:\n\n<code>\n  @GetMapping(path = \"/diffNames\")\n  @ApiOperation(value = \"differentName\", nickname = \"differentName\")\n  public int diffNames(@RequestParam(\"x\") int a, @RequestParam(\"y\") int b)\n</code>\n\nand the swagger is:\n\n<code>\n  paths:\n    /diffNames:\n      get:\n        summary: \"differentName\"\n        operationId: \"differentName\"\n        parameters:\n        - name: \"x\"\n          in: \"query\"\n          required: true\n          type: \"integer\"\n          format: \"int32\"\n        - name: \"y\"\n          in: \"query\"\n          required: true\n          type: \"integer\"\n          format: \"int32\"\n        responses:\n          \"200\":\n            description: \"response of 200\"\n            schema:\n              type: \"integer\"\n              format: \"int32\"\n</code>\n\nIn consumer, you can define any prototype that matches generated swagger of provider.\n */\n\ninterface DiffNames {\n  int differentName(int x, int y);\n}\n\ninterface DiffNames2 {\n  int differentName(int y, int x);\n}\n\ninterface Generics {\n  List<List<String>> genericParams(int code, List<List<String>> names);\n}\n\ninterface GenericsModelInf {\n  GenericsModel genericParamsModel(int code, GenericsModel model);\n}\n\ninterface ObjectInf {\n  GenericsModel obj(GenericsModel obj);\n}\n\n@Component\npublic class TestWeakPojo implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"WeakPojo\")\n  private DiffNames diffNames;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"WeakPojo\")\n  private DiffNames2 diffNames2;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"WeakPojo\")\n  private Generics generics;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"WeakPojo\")\n  private GenericsModelInf genericsModelInf;\n\n  @RpcReference(microserviceName = \"pojo\", schemaId = \"WeakPojo\")\n  private ObjectInf objectInf;\n\n  @Override\n  public void testRestTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testDiffName();\n\n    testGenerics();\n\n    testGenericsModel();\n\n    testObject();\n  }\n\n  private void testObject() throws JsonProcessingException {\n    GenericsModel model = new GenericsModel();\n    model.setName(\"model\");\n    List<List<String>> namesList = new ArrayList<>();\n    List<String> names = new ArrayList<>();\n    names.add(\"hello\");\n    namesList.add(names);\n    model.setNameList(namesList);\n    List<List<List<Object>>> objectLists = new ArrayList<>();\n    List<List<Object>> objectList = new ArrayList<>();\n    List<Object> objects = new ArrayList<>();\n    objects.add(\"object\");\n    objectList.add(objects);\n    objectLists.add(objectList);\n    model.setObjectLists(objectLists);\n    GenericsModel result = objectInf.obj(model);\n    TestMgr.check(JsonUtils.writeValueAsString(model), JsonUtils.writeValueAsString(result));\n  }\n\n  private void testGenericsModel() throws JsonProcessingException {\n    GenericsModel model = new GenericsModel();\n    model.setName(\"model\");\n    List<List<String>> namesList = new ArrayList<>();\n    List<String> names = new ArrayList<>();\n    names.add(\"hello\");\n    namesList.add(names);\n    model.setNameList(namesList);\n    List<List<List<Object>>> objectLists = new ArrayList<>();\n    List<List<Object>> objectList = new ArrayList<>();\n    List<Object> objects = new ArrayList<>();\n    objects.add(\"object\");\n    objectList.add(objects);\n    objectLists.add(objectList);\n    model.setObjectLists(objectLists);\n    GenericsModel result = genericsModelInf.genericParamsModel(100, model);\n    TestMgr.check(JsonUtils.writeValueAsString(model), JsonUtils.writeValueAsString(result));\n  }\n\n  private void testGenerics() {\n    List<List<String>> namesList = new ArrayList<>();\n    List<String> names = new ArrayList<>();\n    names.add(\"hello\");\n    namesList.add(names);\n    List<List<String>> nameListResult = generics.genericParams(100, namesList);\n    TestMgr.check(1, nameListResult.size());\n    TestMgr.check(1, nameListResult.get(0).size());\n    TestMgr.check(\"hello\", nameListResult.get(0).get(0));\n  }\n\n  private void testDiffName() {\n    TestMgr.check(7, diffNames.differentName(2, 3));\n    TestMgr.check(8, diffNames2.differentName(2, 3));\n    Map<String, Object> args = new HashMap<>();\n    args.put(\"x\", 2);\n    args.put(\"y\", 3);\n    Map<String, Object> swaggerArgs = new HashMap<>();\n    swaggerArgs.put(\"differentNameBody\", args);\n    TestMgr.check(7, InvokerUtils.syncInvoke(\"pojo\", \"WeakPojo\",\n        \"differentName\", swaggerArgs, Integer.class));\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/invoker/ClientModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client.invoker;\n\npublic class ClientModel {\n  private String name;\n  private int code;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/invoker/TestInvokerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.client.invoker;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CountDownLatch;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.stereotype.Component;\n\n@Component\n@SuppressWarnings({\"unchecked\", \"rawtypes\"})\npublic class TestInvokerEndpoint implements CategorizedTestCase {\n  @Override\n  public void testRestTransport() throws Exception {\n    testInvokerUtilsDiffModelRest();\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n    testInvokerUtilsDiffModelHighway();\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testInvokerUtilsDiffModel();\n    testInvokerUtilsDiffModelMapArgs();\n  }\n\n  private void testInvokerUtilsDiffModelHighway() throws Exception {\n    Map<String, Object> args = new HashMap<>();\n    ClientModel model = new ClientModel();\n    model.setCode(200);\n    model.setName(\"hello\");\n    args.put(\"request\", model);\n\n    Map result = InvokerUtils.syncInvoke(\"pojo\", \"highway\", \"InvokerEndpoint\",\n        \"model\", args, Map.class);\n    TestMgr.check(model.getCode(), result.get(\"code\"));\n    TestMgr.check(model.getName(), result.get(\"name\"));\n\n    ClientModel modelResult = InvokerUtils\n        .syncInvoke(\"pojo\", \"highway\", \"InvokerEndpoint\", \"model\", args, ClientModel.class);\n    TestMgr.check(model.getCode(), modelResult.getCode());\n    TestMgr.check(model.getName(), modelResult.getName());\n\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    InvokerUtils\n        .reactiveInvoke(\"pojo\", \"highway\", \"InvokerEndpoint\", \"model\", args, ClientModel.class, response -> {\n          ClientModel reactiveResult = response.getResult();\n          TestMgr.check(model.getCode(), reactiveResult.getCode());\n          TestMgr.check(model.getName(), reactiveResult.getName());\n          System.out.println(\"done\");\n          countDownLatch.countDown();\n        });\n    countDownLatch.await();\n  }\n\n  private void testInvokerUtilsDiffModelRest() throws Exception {\n    Map<String, Object> args = new HashMap<>();\n    ClientModel model = new ClientModel();\n    model.setCode(200);\n    model.setName(\"hello\");\n    args.put(\"request\", model);\n\n    Map result = InvokerUtils.syncInvoke(\"pojo\", \"rest\", \"InvokerEndpoint\",\n        \"model\", args, Map.class);\n    TestMgr.check(model.getCode(), result.get(\"code\"));\n    TestMgr.check(model.getName(), result.get(\"name\"));\n\n    ClientModel modelResult = InvokerUtils\n        .syncInvoke(\"pojo\", \"rest\", \"InvokerEndpoint\", \"model\", args, ClientModel.class);\n    TestMgr.check(model.getCode(), modelResult.getCode());\n    TestMgr.check(model.getName(), modelResult.getName());\n\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    InvokerUtils.reactiveInvoke(\"pojo\", \"rest\", \"InvokerEndpoint\", \"model\", args, ClientModel.class, response -> {\n      ClientModel reactiveResult = response.getResult();\n      TestMgr.check(model.getCode(), reactiveResult.getCode());\n      TestMgr.check(model.getName(), reactiveResult.getName());\n      System.out.println(\"done\");\n      countDownLatch.countDown();\n    });\n    countDownLatch.await();\n  }\n\n  private void testInvokerUtilsDiffModel() throws Exception {\n    Map<String, Object> args = new HashMap<>();\n    ClientModel model = new ClientModel();\n    model.setCode(200);\n    model.setName(\"hello\");\n    args.put(\"request\", model);\n\n    Map result = InvokerUtils.syncInvoke(\"pojo\", \"InvokerEndpoint\",\n        \"model\", args, Map.class);\n    TestMgr.check(model.getCode(), result.get(\"code\"));\n    TestMgr.check(model.getName(), result.get(\"name\"));\n\n    ClientModel modelResult = InvokerUtils.syncInvoke(\"pojo\", \"InvokerEndpoint\", \"model\", args, ClientModel.class);\n    TestMgr.check(model.getCode(), modelResult.getCode());\n    TestMgr.check(model.getName(), modelResult.getName());\n\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    InvokerUtils.reactiveInvoke(\"pojo\", \"InvokerEndpoint\", \"model\", args,\n        ClientModel.class, response -> {\n      ClientModel reactiveResult = response.getResult();\n      TestMgr.check(model.getCode(), reactiveResult.getCode());\n      TestMgr.check(model.getName(), reactiveResult.getName());\n      System.out.println(\"done\");\n      countDownLatch.countDown();\n    });\n    countDownLatch.await();\n  }\n\n  private void testInvokerUtilsDiffModelMapArgs() throws Exception {\n    Map<String, Object> args = new HashMap<>();\n    Map model = new HashMap();\n    model.put(\"code\", 20);\n    model.put(\"name\", \"hello\");\n    args.put(\"request\", model);\n\n    Map result = InvokerUtils.syncInvoke(\"pojo\", \"InvokerEndpoint\", \"model\", args, Map.class);\n    TestMgr.check(model.get(\"code\"), result.get(\"code\"));\n    TestMgr.check(model.get(\"name\"), result.get(\"name\"));\n\n    ClientModel modelResult = InvokerUtils.syncInvoke(\"pojo\", \"InvokerEndpoint\", \"model\", args, ClientModel.class);\n    TestMgr.check(model.get(\"code\"), modelResult.getCode());\n    TestMgr.check(model.get(\"name\"), modelResult.getName());\n\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    InvokerUtils.reactiveInvoke(\"pojo\", \"InvokerEndpoint\", \"model\", args, ClientModel.class, response -> {\n      ClientModel reactiveResult = response.getResult();\n      TestMgr.check(model.get(\"code\"), reactiveResult.getCode());\n      TestMgr.check(model.get(\"name\"), reactiveResult.getName());\n      countDownLatch.countDown();\n    });\n    countDownLatch.await();\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/resources/META-INF/spring/pojo.client.bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xmlns:cse=\"http://www.huawei.com/schema/paas/cse/rpc\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n\t\thttp://www.huawei.com/schema/paas/cse/rpc classpath:META-INF/spring/spring-paas-cse-rpc.xsd\">\n\n  <cse:rpc-reference id=\"smartcare\" microservice-name=\"pojo\"\n    schema-id=\"smartcare\" interface=\"org.apache.servicecomb.demo.smartcare.SmartCare\"></cse:rpc-reference>\n\n  <cse:rpc-reference id=\"server\" microservice-name=\"pojo\"\n    schema-id=\"server\" interface=\"org.apache.servicecomb.demo.server.Test\"></cse:rpc-reference>\n\n  <bean class=\"org.apache.servicecomb.demo.pojo.client.PojoClient\">\n    <property name=\"testFromXml\" ref=\"server\"></property>\n  </bean>\n\n  <cse:rpc-reference id=\"codeFirstFromXml\" microservice-name=\"pojo\"\n    schema-id=\"org.apache.servicecomb.demo.CodeFirstPojoIntf\"></cse:rpc-reference>\n\n  <bean class=\"org.apache.servicecomb.demo.pojo.client.BeanRpcTest\" init-method=\"init\">\n  </bean>\n</beans>\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: pojotest\n    name: pojoClient\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest.client.enabled: false # using only http2\n  swagger:\n    disableDataTypeCheck: true\n\n  isolation:\n    Consumer:\n      enabled: false\n  loadbalance:\n    strategy:\n      name: Random\n  metrics:\n    window_time: 12000\n    publisher.defaultLog.enabled: false # when in testing , can turn on\n  flowcontrol:\n    enabled: true\n    Consumer:\n      qps:\n        limit:\n          pojo:\n            FlowControlClientSchema:\n              foo: 3\n              bar: 3000\n  provider:\n    name: pojo\n"
  },
  {
    "path": "demo/demo-pojo/pojo-client/src/test/java/org/apache/servicecomb/demo/pojo/PojoIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.pojo.client.PojoClient;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = PojoClient.class)\npublic class PojoIT {\n\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    PojoClient.run();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-pojo</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>pojo-server</artifactId>\n  <name>Java Chassis::Demo::POJO::Server</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.pojo.server.PojoServer</demo.main>\n    <build.docker.image.enable>true</build.docker.image.enable>\n  </properties>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/CodeFirstPojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.demo.CodeFirstPojoIntf;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.mapnull.ParseRequest;\nimport org.apache.servicecomb.demo.mapnull.ParseResponse;\nimport org.apache.servicecomb.demo.server.MapModel;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.servers.Server;\n\n@RpcSchema()\n@OpenAPIDefinition(servers = {@Server(url = \"/pojo/rest\")})\npublic class CodeFirstPojo implements CodeFirstPojoIntf {\n  @Override\n  public ParseResponse parse(ParseRequest request) {\n    ParseResponse r = new ParseResponse();\n    r.setResultCode(\"CU1I0000\");\n    r.setResultInfo(\"报文处理成功！报文解析成功！\");\n    r.setMsgType(\"cncc.111.001.01\");\n    Map<String, String> h = new HashMap<>();\n    h.put(\"C11\", \"20200101\");\n    h.put(\"F41\", \"3\");\n    h.put(\"F40\", \"cncc.111.001.01\");\n    h.put(\"E24\", \"HVPA5C30177808463743\");\n    h.put(\"E35\", \"HVPA5C30177808463743\");\n    h.put(\"A29\", \"{N:, K20=}\");\n    h.put(\"F38\", \"HVPS\");\n    h.put(\"K13\", \"01\");\n    h.put(\"F39\", \"SAPS\");\n    h.put(\"K14\", \"CMT\");\n    h.put(\"K16\", \"\");\n    h.put(\"C92\", \"102633\");\n    r.setMsgHeader(h);\n    Map<String, Object> b = new HashMap<>();\n    b.put(\"E50\", \"hvps.141.001.01\");\n    b.put(\"A00\", \"402451000010\");\n    b.put(\"A01\", \"105100000017\");\n    b.put(\"F32\", \"NORM\");\n    b.put(\"E57\", \"19218385\");\n    b.put(\"D14\", \"200000.00\");\n    b.put(\"C14\", \"20200101\");\n    b.put(\"F25\", \"02711\");\n    b.put(\"A70\", \"908100000002\");\n    b.put(\"C92\", \"20200101\");\n    b.put(\"F2H\", \"G105\");\n    r.setMsgBody(b);\n    return r;\n  }\n\n  @Override\n  public MapModel testMapModel(MapModel model) {\n    return model;\n  }\n\n  @Override\n  public Map<String, String> testMap(Map<String, String> map) {\n    return map;\n  }\n\n  @Override\n  public Map<String, User> testUserMap(Map<String, User> userMap) {\n    return userMap;\n  }\n\n  @Override\n  public List<User> testUserArray(List<User> users) {\n    return users;\n  }\n\n  public String[] testStrings(String[] input) {\n    input[0] += input[0] + \"0\";\n    return input;\n  }\n\n  public byte[] testBytes(byte[] input) {\n    input[0] = (byte) (input[0] + 1);\n    return input;\n  }\n\n  public int reduce(int a, int b) {\n    return a - b;\n  }\n\n  public Date addDate(Date date, long second) {\n    return new Date(date.getTime() + second * 1000);\n  }\n\n  public Person sayHello(Person user) {\n    user.setName(\"hello \" + user.getName());\n    return user;\n  }\n\n  public String saySomething(String prefix, Person user) {\n    return prefix + \" \" + user.getName();\n  }\n\n  public String sayHi(String name) {\n    ContextUtils.getInvocationContext().setStatus(202);\n    return name + \" sayhi, context k: \"\n        + (ContextUtils.getInvocationContext() == null ? \"\"\n        : ContextUtils.getInvocationContext().getContext(\"k\"));\n  }\n\n  @Operation(operationId = \"sayHi2\", summary = \"\")\n  public CompletableFuture<String> sayHi2Async(String name) {\n    CompletableFuture<String> future = new CompletableFuture<>();\n    future.complete(name + \" sayhi 2\");\n    return future;\n  }\n\n  public boolean isTrue() {\n    return true;\n  }\n\n  public String addString(List<String> s) {\n    StringBuilder result = new StringBuilder();\n    for (String x : s) {\n      result.append(x);\n    }\n    return result.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlClientSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"FlowControlClientSchema\")\npublic class FlowControlClientSchema {\n  public int foo(int num) {\n    return num;\n  }\n\n  public int bar(int num) {\n    return num;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/FlowControlSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"FlowControlSchema\")\npublic class FlowControlSchema {\n  public int foo(int num) {\n    return num;\n  }\n\n  public int bar(int num) {\n    return num;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/HelloImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.apache.servicecomb.demo.helloworld.greeter.Hello;\n\npublic class HelloImpl implements Hello {\n\n  @Override\n  public String SayHello(String name) {\n    return \"Hello Message fast\";\n  }\n\n  @Override\n  public String SayHelloAgain(String name) {\n    try {\n      Thread.sleep(5000);\n    } catch (InterruptedException e) {\n      e.printStackTrace();\n    }\n    return \"Hello Message slow\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/NotRecommendedService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.server.AbstractModel;\nimport org.apache.servicecomb.demo.server.NotRecommendedServiceInf;\nimport org.apache.servicecomb.demo.server.WrappedAbstractModel;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"NotRecommendedService\", schemaInterface = NotRecommendedServiceInf.class)\npublic class NotRecommendedService implements NotRecommendedServiceInf {\n\n  @Override\n  public Map<Long, Long> longMap(Map<Long, Long> map) {\n    return map;\n  }\n\n  @Override\n  public List<AbstractModel> listAbstractModel(List<AbstractModel> listModel) {\n    return listModel;\n  }\n\n  @Override\n  public AbstractModel abstractModel(AbstractModel model) {\n    return model;\n  }\n\n  @Override\n  public Map<Long, AbstractModel> mapAbstractModel(Map<Long, AbstractModel> mapModel) {\n    return mapModel;\n  }\n\n  @Override\n  public WrappedAbstractModel wrappedAbstractModel(WrappedAbstractModel wrappedModel) {\n    return wrappedModel;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/PojoProducersCustomized.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.apache.servicecomb.provider.pojo.schema.PojoProducers;\nimport org.springframework.context.annotation.Primary;\nimport org.springframework.stereotype.Component;\n\n@Primary\n@Component\n// This example shows user's how to customize PojoProducers by @Primary annotation\npublic class PojoProducersCustomized extends PojoProducers {\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/PojoServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.context.annotation.ImportResource;\n\n@SpringBootApplication\n@ImportResource(value = \"classpath*:META-INF/spring/*.bean.xml\")\npublic class PojoServer {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder(PojoServer.class).web(WebApplicationType.NONE).run(args);\n    } catch (Throwable e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/SchemaInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\npublic interface SchemaInterface {\n  String echo(String content);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/SchemaInterfaceImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\npublic class SchemaInterfaceImpl implements SchemaInterface {\n  @Override\n  public String echo(String content) {\n    return content;\n  }\n\n  public String echoError(String content) {\n    return content;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/SchemeInterfacePojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\npublic interface SchemeInterfacePojo {\n  int reduce(int a, int b);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/SchemeInterfacePojoImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"SchemeInterfacePojoImpl\", schemaInterface = SchemeInterfacePojo.class)\npublic class SchemeInterfacePojoImpl implements SchemeInterfacePojo {\n  @Override\n  public int reduce(int a, int b) {\n    return a - b;\n  }\n\n  public int add(int a, int b) {\n    return a + b;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/SmartCareImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport org.apache.servicecomb.demo.smartcare.Application;\nimport org.apache.servicecomb.demo.smartcare.Response;\nimport org.apache.servicecomb.demo.smartcare.SmartCare;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class SmartCareImpl implements SmartCare {\n  private static final Logger LOG = LoggerFactory.getLogger(SmartCareImpl.class);\n\n  @Override\n  public Response addApplication(Application application) {\n    LOG.info(application.toString());\n\n    Response resp = new Response();\n    resp.setResultCode(0);\n    resp.setResultMessage(\"add application \" + application.getName() + \" success\");\n    return resp;\n  }\n\n  @SuppressWarnings(\"divzero\")\n  @Override\n  public Response delApplication(String appName) {\n    LOG.info(appName);\n\n    try {\n      System.out.println(5 / 0);\n    } catch (Exception e) {\n      Response resp = new Response();\n      resp.setResultCode(1);\n      resp.setResultMessage(\"delete application \" + appName + \" failed\");\n      return resp;\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/TestImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.demo.server.Test;\nimport org.apache.servicecomb.demo.server.TestRequest;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\n@RpcSchema(schemaId = \"server\")\npublic class TestImpl implements Test {\n  @Override\n  public String testStringArray(String[] arr) {\n    return String.format(\"arr is '%s'\", Arrays.toString(arr));\n  }\n\n  @Override\n  public String getTestString(String code) {\n    return String.format(\"code is '%s'\", code);\n  }\n\n  @Override\n  public String postTestStatic(int code) {\n    return null;\n  }\n\n  @Override\n  public String patchTestStatic(int code) {\n    return null;\n  }\n\n  private User doTest(int index, User user, List<User> users, byte[] data) {\n    if (user == null) {\n      user = new User();\n    }\n\n    user.setIndex(index);\n\n    int userCount = (users == null) ? 0 : users.size();\n    user.setName(user.getName() + \",  users count:\" + userCount);\n    return user;\n  }\n\n  @Override\n  public String testException(int code) {\n    String strCode = String.valueOf(code);\n    switch (code) {\n      case 200:\n        return strCode;\n      case 456:\n        throw new InvocationException(code, strCode, strCode + \" error\");\n      case 556:\n        throw new InvocationException(code, strCode, Arrays.asList(strCode + \" error\"));\n      case 557:\n        throw new InvocationException(code, strCode, Arrays.asList(Arrays.asList(strCode + \" error\")));\n      default:\n        break;\n    }\n\n    return \"not expected\";\n  }\n\n  @Override\n  public User splitParam(int index, User user) {\n    return doTest(index, user, null, null);\n  }\n\n  @Override\n  public User wrapParam(TestRequest request) {\n    if (request == null || request.getUser() == null) {\n      return null;\n    }\n    return doTest(request.getIndex(), request.getUser(), request.getUsers(), request.getData());\n  }\n\n  @Override\n  public String addString(String[] strArr) {\n    String result = Arrays.toString(strArr);\n    System.out.println(\"addString: \" + result);\n    return result;\n  }\n\n  @Override\n  public String testTraceId() {\n    return ContextUtils.getInvocationContext().getContext(CoreConst.TRACE_ID_NAME);\n  }\n\n  @Override\n  public int[] testIntArray(int[] request) {\n    return request;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/WeakPojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.server.GenericsModel;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.Parameter;\n\n@RpcSchema(schemaId = \"WeakPojo\")\npublic class WeakPojo {\n  @Operation(summary = \"differentName\", operationId = \"differentName\")\n  public int diffNames(@Parameter(name = \"x\") int a, @Parameter(name = \"y\") int b) {\n    return a * 2 + b;\n  }\n\n  public List<List<String>> genericParams(int code, List<List<String>> names) {\n    return names;\n  }\n\n  public GenericsModel genericParamsModel(int code, GenericsModel model) {\n    return model;\n  }\n\n  public Object obj(Object obj) {\n    return obj;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/invoker/InvokerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.invoker;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"InvokerEndpoint\")\npublic class InvokerEndpoint {\n  public ServerModel model(ServerModel request) {\n    return request;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/invoker/ServerModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.invoker;\n\npublic class ServerModel {\n  private String name;\n  private int code;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/same/pk1/SameInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.same.pk1;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.servers.Server;\n\n@OpenAPIDefinition(servers = {@Server(url = \"/SameInterface1\")})\npublic interface SameInterface {\n  String sayHello(String name);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/same/pk1/SameInterfaceImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.same.pk1;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.springframework.stereotype.Component;\n\n@RpcSchema(schemaId = \"SameInterface1\", schemaInterface = SameInterface.class)\n@Component(\"SameInterface1\")\npublic class SameInterfaceImpl implements SameInterface {\n  @Override\n  public String sayHello(String name) {\n    return \"pk1-inf-\" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/same/pk1/SameService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.same.pk1;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.springframework.stereotype.Component;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.servers.Server;\n\n@RpcSchema(schemaId = \"SameService1\")\n@Component(\"SameService1\")\n@OpenAPIDefinition(servers = {@Server(url = \"/SameService1\")})\npublic class SameService {\n  public String sayHello(String name) {\n    return \"pk1-svc-\" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/same/pk2/SameInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.same.pk2;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.servers.Server;\n\n@OpenAPIDefinition(servers = {@Server(url = \"/SameInterface2\")})\npublic interface SameInterface {\n  String sayHello(String name);\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/same/pk2/SameInterfaceImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.same.pk2;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.springframework.stereotype.Component;\n\n@RpcSchema(schemaId = \"SameInterface2\", schemaInterface = SameInterface.class)\n@Component(\"SameInterface2\")\npublic class SameInterfaceImpl implements SameInterface {\n  @Override\n  public String sayHello(String name) {\n    return \"pk2-inf-\" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/java/org/apache/servicecomb/demo/pojo/server/same/pk2/SameService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.pojo.server.same.pk2;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.springframework.stereotype.Component;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.servers.Server;\n\n@RpcSchema(schemaId = \"SameService2\")\n@Component(\"SameService2\")\n@OpenAPIDefinition(servers = {@Server(url = \"/SameService2\")})\npublic class SameService {\n  public String sayHello(String name) {\n    return \"pk2-svc-\" + name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/resources/META-INF/spring/pojo.server.bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xmlns:cse=\"http://www.huawei.com/schema/paas/cse/rpc\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n\t\thttp://www.huawei.com/schema/paas/cse/rpc classpath:META-INF/spring/spring-paas-cse-rpc.xsd\">\n\n  <bean id=\"hello\" class=\"org.apache.servicecomb.demo.pojo.server.HelloImpl\"></bean>\n  <cse:rpc-schema schema-id=\"helloworld.Greeter\"\n    implementation=\"spring:hello\"></cse:rpc-schema>\n\n  <cse:rpc-schema schema-id=\"smartcare\"\n    implementation=\"org.apache.servicecomb.demo.pojo.server.SmartCareImpl\"></cse:rpc-schema>\n\n  <cse:rpc-schema schema-id=\"SchemaInterface\" schema-interface=\"org.apache.servicecomb.demo.pojo.server.SchemaInterface\"\n    implementation=\"org.apache.servicecomb.demo.pojo.server.SchemaInterfaceImpl\"></cse:rpc-schema>\n</beans>\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml",
    "content": "﻿## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: pojotest\n    name: pojo\n    version: 0.0.4\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080?protocol=http2\n    server:\n      http2:\n        useAlpnEnabled: false\n  highway:\n    address: 0.0.0.0:7070\n  swagger:\n    disableDataTypeCheck: true\n\n  flowcontrol:\n    enabled: true\n    Provider:\n      qps:\n        limit:\n          ANY:\n            FlowControlSchema:\n              foo: 3\n              bar: 3000\n"
  },
  {
    "path": "demo/demo-pojo/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-pojo</artifactId>\n  <name>Java Chassis::Demo::POJO</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>pojo-server</module>\n    <module>pojo-client</module>\n  </modules>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-publickey-auth</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-register-url-prefix/README.md",
    "content": "This demo is an integration test for testing\n\n```yaml\nservicecomb:\n  service:\n    registry:\n      registerUrlPrefix: true\n```\n\nWhen this configuration is enabled, web context path is added to swagger, and consumer can\ninvoke with context path\n\n```yaml\ntemplate.getForObject(\n  \"cse://demo-register-url-prefix-server/hellodemo/register/url/prefix/getName?name=2\",\n   String.class)\n```\n\nThis feature is not recommended for use by default, but for some backward capabilities.\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-register-url-prefix-client</artifactId>\n  <name>Java Chassis::Demo::Register URL Prefix client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-register-url-prefix</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.prefix.Application</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>demo-register-url-prefix-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-client/src/main/java/org/apache/servicecomb/demo/prefix/Application.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.prefix;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.web.client.RestOperations;\n\n@SpringBootApplication\npublic class Application {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(Application.class).web(WebApplicationType.SERVLET).build().run(args);\n\n    runTest();\n  }\n\n  public static void runTest() {\n    RestOperations template = RestTemplateBuilder.create();\n    TestMgr.check(\"2\", template\n        .getForObject(\"cse://demo-register-url-prefix-server/hellodemo/register/url/prefix/getName?name=2\",\n            String.class));\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8082\n\nservicecomb:\n  service:\n    application: demo-register-url-prefix\n    name: demo-register-url-prefix-client\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  handler:\n    chain:\n      Consumer:\n        default: loadbalance\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-client/src/test/java/org/apache/servicecomb/demo/prefix/RegisterUrlPrefixIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.prefix;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.SpringApplication;\n\npublic class RegisterUrlPrefixIT {\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    SpringApplication.run(Application.class);\n\n    Application.runTest();\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-register-url-prefix-server</artifactId>\n  <name>Java Chassis::Demo::Register URL Prefix Server</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-register-url-prefix</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.prefix.PrefixApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-server/src/main/java/org/apache/servicecomb/demo/prefix/PrefixApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.prefix;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class PrefixApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(PrefixApplication.class).web(WebApplicationType.SERVLET).build().run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-server/src/main/java/org/apache/servicecomb/demo/prefix/RegisterUrlPrefixEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.prefix;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"RegisterUrlPrefixEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class RegisterUrlPrefixEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-server/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  servlet:\n    context-path: /hellodemo\n  port: 8080\n\nservicecomb:\n  service:\n    application: demo-register-url-prefix\n    name: demo-register-url-prefix-server\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n    registerUrlPrefix: true\n  rest:\n    address: 0.0.0.0:8080\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-register-url-prefix/demo-register-url-prefix-server/src/main/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<configuration scan=\"true\">\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n    <encoder>\n      <pattern>%d [%level] [%thread] - %msg (%F:%L\\)%n</pattern>\n    </encoder>\n  </appender>\n\n  <root level=\"info\">\n    <appender-ref ref=\"STDOUT\"/>\n  </root>\n</configuration>\n"
  },
  {
    "path": "demo/demo-register-url-prefix/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-register-url-prefix</artifactId>\n  <name>Java Chassis::Demo::Register URL Prefix</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-register-url-prefix-server</module>\n    <module>demo-register-url-prefix-client</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-schema/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-schema</artifactId>\n  <name>Java Chassis::Demo::Schema</name>\n\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <configuration>\n          <excludes>\n            <exclude>config/log4j.eclipse.properties</exclude>\n          </excludes>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n</project>\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\npublic interface CategorizedTestCase {\n  /**\n   * test case which only successful in REST transport\n   */\n  default void testRestTransport() throws Exception {\n\n  }\n\n  /**\n   * test case which only successful in HIGHWAY transport\n   */\n  default void testHighwayTransport() throws Exception {\n\n  }\n\n  /**\n   * test case which successful in both REST and HIGHWAY transport\n   */\n  default void testAllTransport() throws Exception {\n\n  }\n\n  default String getMicroserviceName() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCaseRunner.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class CategorizedTestCaseRunner {\n  private static final Logger LOGGER = LoggerFactory.getLogger(CategorizedTestCaseRunner.class);\n\n  public static void runCategorizedTestCase(String microserviceName) throws Exception {\n    Map<String, CategorizedTestCase> tests = BeanUtils.getContext().getBeansOfType(CategorizedTestCase.class);\n    for (String transport : DemoConst.transports) {\n      for (CategorizedTestCase testCase : tests.values()) {\n\n        try {\n          if (testCase.getMicroserviceName() != null) {\n            changeTransport(testCase.getMicroserviceName(), transport);\n          } else {\n            changeTransport(microserviceName, transport);\n          }\n\n          testCase.testAllTransport();\n          if (\"rest\".equals(transport)) {\n            testCase.testRestTransport();\n          } else if (\"highway\".equals(transport)) {\n            testCase.testHighwayTransport();\n          }\n        } catch (Exception e) {\n          LOGGER.error(\"run categorized test case \" +\n              testCase.getClass().getName() +\n              \" failed.\", e);\n          throw e;\n        }\n      }\n    }\n  }\n\n  public static void changeTransport(String microserviceName, String transport) {\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n    TestMgr.setMsg(microserviceName, transport);\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstPojoIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.mapnull.ParseRequest;\nimport org.apache.servicecomb.demo.mapnull.ParseResponse;\nimport org.apache.servicecomb.demo.server.MapModel;\nimport org.apache.servicecomb.demo.server.User;\n\npublic interface CodeFirstPojoIntf {\n  ParseResponse parse(ParseRequest request);\n\n  MapModel testMapModel(MapModel model);\n\n  Map<String, String> testMap(Map<String, String> map);\n\n  Map<String, User> testUserMap(Map<String, User> userMap);\n\n  List<User> testUserArray(List<User> users);\n\n  String[] testStrings(String[] input);\n\n  byte[] testBytes(byte[] input);\n\n  int reduce(int a, int b);\n\n  Date addDate(Date date, long second);\n\n  Person sayHello(Person user);\n\n  String saySomething(String prefix, Person user);\n\n  String sayHi(String name);\n\n  boolean isTrue();\n\n  String addString(List<String> s);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;\nimport org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.ParameterizedTypeReference;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.HttpStatusCode;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.client.RestOperations;\n\nimport io.vertx.core.json.JsonObject;\n\npublic class CodeFirstRestTemplate {\n  protected Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  protected void changeTransport(String microserviceName, String transport) {\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n    TestMgr.setMsg(microserviceName, transport);\n  }\n\n  public void testCodeFirst(RestOperations template, String microserviceName, String basePath) {\n    String cseUrlPrefix = \"cse://\" + microserviceName + basePath;\n    changeTransport(microserviceName, \"highway\");\n    testOnlyHighway(template, cseUrlPrefix);\n\n    changeTransport(microserviceName, CoreConst.RESTFUL);\n    testOnlyRest(microserviceName, template, cseUrlPrefix);\n\n    for (String transport : DemoConst.transports) {\n      changeTransport(microserviceName, transport);\n      testAllTransport(microserviceName, template, cseUrlPrefix);\n    }\n  }\n\n  protected void testAllTransport(String microserviceName, RestOperations template, String cseUrlPrefix) {\n    testCodeFirstUserMap(template, cseUrlPrefix);\n    testCodeFirstTextPlain(template, cseUrlPrefix);\n    testCodeFirstBytes(template, cseUrlPrefix);\n    testCseResponse(microserviceName, template, cseUrlPrefix);\n    testCodeFirstAddDate(template, cseUrlPrefix);\n\n    testCodeFirstAdd(template, cseUrlPrefix);\n    testCodeFirstAddString(template, cseUrlPrefix);\n    testCodeFirstIsTrue(template, cseUrlPrefix);\n    testCodeFirstSayHi2(template, cseUrlPrefix);\n    testCodeFirstSayHi(template, cseUrlPrefix);\n    testCodeFirstSaySomething(template, cseUrlPrefix);\n    testCodeFirstSayHello(template, cseUrlPrefix);\n    testCodeFirstReduce(template, cseUrlPrefix);\n\n    testTraceIdOnContextContainsTraceId(template, cseUrlPrefix);\n\n    testRawJson(template, cseUrlPrefix);\n  }\n\n  protected void testOnlyHighway(RestOperations template, String cseUrlPrefix) {\n\n  }\n\n  protected void testOnlyRest(String microserviceName, RestOperations template, String cseUrlPrefix) {\n    testCodeFirstUserMap(template, cseUrlPrefix);\n    testCodeFirstTextPlain(template, cseUrlPrefix);\n    testCodeFirstBytes(template, cseUrlPrefix);\n    testCseResponse(microserviceName, template, cseUrlPrefix);\n    testCodeFirstAddDate(template, cseUrlPrefix);\n    testCodeFirstAdd(template, cseUrlPrefix);\n    testCodeFirstAddString(template, cseUrlPrefix);\n\n    testModelFieldIgnore(template, cseUrlPrefix);\n    testCodeFirstReduce(template, cseUrlPrefix);\n    // only rest transport will set trace id\n    testTraceIdOnNotSetBefore(template, cseUrlPrefix);\n  }\n\n  private void testCodeFirstUserMap(RestOperations template, String cseUrlPrefix) {\n    User user1 = new User();\n    user1.setNames(new String[] {\"u1\", \"u2\"});\n\n    User user2 = new User();\n    user2.setNames(new String[] {\"u3\", \"u4\"});\n\n    Map<String, User> userMap = new HashMap<>();\n    userMap.put(\"u1\", user1);\n    userMap.put(\"u2\", user2);\n\n    // TODO: shall we support this usage? Seams not valid, cause result should be Map<String, Object> and type not defined.\n//    @SuppressWarnings(\"unchecked\")\n//    Map<String, User> result = template.postForObject(cseUrlPrefix + \"testUserMap\",\n//        userMap,\n//        Map.class);\n\n    Map<String, User> result = template.exchange(cseUrlPrefix + \"testUserMap\", HttpMethod.POST,\n        new HttpEntity<>(userMap),\n        new ParameterizedTypeReference<Map<String, User>>() {\n        }).getBody();\n\n    TestMgr.check(\"u1\", result.get(\"u1\").getNames()[0]);\n    TestMgr.check(\"u2\", result.get(\"u1\").getNames()[1]);\n    TestMgr.check(\"u3\", result.get(\"u2\").getNames()[0]);\n    TestMgr.check(\"u4\", result.get(\"u2\").getNames()[1]);\n  }\n\n  private void testCodeFirstTextPlain(RestOperations template, String cseUrlPrefix) {\n    String body = \"a=1\";\n    String result = template.postForObject(cseUrlPrefix + \"textPlain\",\n        body,\n        String.class);\n    TestMgr.check(body, result);\n  }\n\n  private void testCodeFirstBytes(RestOperations template, String cseUrlPrefix) {\n    byte[] body = new byte[] {0, 1, 2};\n    byte[] result = template.postForObject(cseUrlPrefix + \"bytes\",\n        body,\n        byte[].class);\n    TestMgr.check(3, result.length);\n    TestMgr.check(1, result[0]);\n    TestMgr.check(1, result[1]);\n    TestMgr.check(2, result[2]);\n  }\n\n  protected void checkStatusCode(String microserviceName, int expectStatusCode, HttpStatusCode httpStatus) {\n    TestMgr.check(expectStatusCode, httpStatus.value());\n  }\n\n  private void testCseResponse(String targetMicroserviceName, RestOperations template,\n      String cseUrlPrefix) {\n    String srcMicroserviceName = BootStrapProperties.readServiceName(environment);\n\n    ResponseEntity<User> responseEntity =\n        template.exchange(cseUrlPrefix + \"cseResponse\", HttpMethod.GET, null, User.class);\n    TestMgr.check(\"User [name=nameA, age=100, index=0]\", responseEntity.getBody());\n    TestMgr.check(\"h1v \" + srcMicroserviceName, responseEntity.getHeaders().getFirst(\"h1\"));\n    TestMgr.check(\"h2v \" + srcMicroserviceName, responseEntity.getHeaders().getFirst(\"h2\"));\n    checkStatusCode(targetMicroserviceName, 202, responseEntity.getStatusCode());\n  }\n\n  private void testCodeFirstAddDate(RestOperations template, String cseUrlPrefix) {\n    Map<String, Object> body = new HashMap<>();\n    Date date = new Date();\n    body.put(\"date\", date);\n\n    int seconds = 1;\n    Date result = template.postForObject(cseUrlPrefix + \"addDate?seconds={seconds}\",\n        body,\n        Date.class,\n        seconds);\n    TestMgr.check(new Date(date.getTime() + seconds * 1000), result);\n  }\n\n  private void testCodeFirstAddString(RestOperations template, String cseUrlPrefix) {\n    ResponseEntity<String> responseEntity =\n        template.exchange(cseUrlPrefix + \"addstring?s=a&s=b\",\n            HttpMethod.DELETE,\n            null,\n            String.class);\n    TestMgr.check(\"ab\", responseEntity.getBody());\n  }\n\n  private void testCodeFirstIsTrue(RestOperations template, String cseUrlPrefix) {\n    boolean result = template.getForObject(cseUrlPrefix + \"istrue\", boolean.class);\n    TestMgr.check(true, result);\n  }\n\n  private void testCodeFirstSayHi2(RestOperations template, String cseUrlPrefix) {\n    ResponseEntity<String> responseEntity =\n        template.exchange(cseUrlPrefix + \"sayhi/{name}/v2\", HttpMethod.PUT, null, String.class, \"world\");\n    TestMgr.check(\"world sayhi 2\", responseEntity.getBody());\n  }\n\n  private void testCodeFirstSayHi(RestOperations template, String cseUrlPrefix) {\n    ResponseEntity<String> responseEntity =\n        template.exchange(cseUrlPrefix + \"sayhi/{name}\", HttpMethod.PUT, null, String.class, \"world\");\n    TestMgr.check(202, responseEntity.getStatusCode().value());\n    TestMgr.check(\"world sayhi\", responseEntity.getBody());\n  }\n\n  private void testCodeFirstSaySomething(RestOperations template, String cseUrlPrefix) {\n    Person person = new Person();\n    person.setName(\"person name\");\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"prefix\", \"prefix  prefix\");\n    headers.add(\"userId\", \"serviceCombUser\");\n\n    HttpEntity<Person> requestEntity = new HttpEntity<>(person, headers);\n    String result = template.postForObject(cseUrlPrefix + \"saysomething\", requestEntity, String.class);\n    TestMgr.check(\"prefix  prefix person name\", result);\n  }\n\n  private void testCodeFirstSayHello(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> persionFieldMap = new HashMap<>();\n    persionFieldMap.put(\"name\", \"person name from map\");\n    Person result = template.postForObject(cseUrlPrefix + \"sayhello\", persionFieldMap, Person.class);\n    TestMgr.check(\"hello person name from map\", result);\n\n    Person input = new Person();\n    input.setName(\"person name from Object\");\n    result = template.postForObject(cseUrlPrefix + \"sayhello\", input, Person.class);\n    TestMgr.check(\"hello person name from Object\", result);\n  }\n\n  private void testCodeFirstAdd(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n    params.put(\"b\", \"3\");\n    int result =\n        template.postForObject(cseUrlPrefix + \"add\", params, Integer.class);\n    TestMgr.check(8, result);\n  }\n\n  private void testCodeFirstReduce(RestOperations template, String cseUrlPrefix) {\n    Map<String, String> params = new HashMap<>();\n    params.put(\"a\", \"5\");\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(HttpHeaders.COOKIE, \"b=3\");\n\n    HttpEntity<?> requestEntity = new HttpEntity<>(headers);\n    ResponseEntity<Integer> result =\n        template.exchange(cseUrlPrefix + \"reduce?a={a}\", HttpMethod.GET, requestEntity, Integer.class, params);\n    TestMgr.check(2, result.getBody());\n  }\n\n  private void testModelFieldIgnore(RestOperations template, String cseUrlPrefix) {\n    InputModelForTestIgnore input = new InputModelForTestIgnore(\"input_id_rest\", \"input_id_content\",\n        new Person(\"inputSomeone\"), new JsonObject(\"{\\\"InputJsonKey\\\" : \\\"InputJsonValue\\\"}\"), () -> {\n    });\n    OutputModelForTestIgnore output = template\n        .postForObject(cseUrlPrefix + \"ignore\", input, OutputModelForTestIgnore.class);\n\n    TestMgr.check(null, output.getInputId());\n    TestMgr.check(input.getContent(), output.getContent());\n    TestMgr.check(null, output.getOutputId());\n\n    TestMgr.check(null, output.getInputIgnoreInterface());\n    TestMgr.check(null, output.getInputJsonObject());\n    TestMgr.check(null, output.getInputObject());\n\n    TestMgr.check(null, output.getOutputIgnoreInterface());\n    TestMgr.check(null, output.getOutputJsonObject());\n    TestMgr.check(null, output.getOutputObject());\n  }\n\n  private void testRawJson(RestOperations template, String cseUrlPrefix) {\n    String input = \"{\\\"name\\\" : \\\"zyy\\\"}\";\n    String output = template.postForObject(cseUrlPrefix + \"rawJsonAnnotation\", input, String.class);\n    TestMgr.check(\"hello zyy\", output);\n  }\n\n  private void testTraceIdOnNotSetBefore(RestOperations template, String cseUrlPrefix) {\n    String traceIdUrl = cseUrlPrefix + \"traceId\";\n    String result = template.getForObject(traceIdUrl, String.class);\n    TestMgr.checkNotEmpty(result);\n  }\n\n  private void testTraceIdOnContextContainsTraceId(RestOperations template, String cseUrlPrefix) {\n    String traceIdUrl = cseUrlPrefix + \"traceId\";\n    InvocationContext invocationContext = new InvocationContext();\n    invocationContext.addContext(CoreConst.TRACE_ID_NAME, String.valueOf(Long.MIN_VALUE));\n    ContextUtils.setInvocationContext(invocationContext);\n    String result = template.getForObject(traceIdUrl, String.class);\n    TestMgr.check(String.valueOf(Long.MIN_VALUE), result);\n    ContextUtils.removeInvocationContext();\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CommonSchemaInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\n@RequestMapping(\"/CommonSchemaInterface\")\npublic interface CommonSchemaInterface {\n  @GetMapping(path = \"testInvocationTimeout\")\n  String testInvocationTimeout(@RequestParam(\"timeout\") long timeout, @RequestParam(\"name\") String name);\n\n  @GetMapping(path = \"testInvocationTimeoutWithInvocation\")\n  @Operation(summary = \"testInvocationTimeoutWithInvocation\", operationId = \"testInvocationTimeoutWithInvocation\")\n  String testInvocationTimeout(InvocationContext context, @RequestParam(\"timeout\") long timeout,\n      @RequestParam(\"name\") String name);\n\n  @GetMapping(path = \"testInvocationTimeoutInClientWait\")\n  String testInvocationTimeoutInClientWait(@RequestParam(\"timeout\") long timeout, @RequestParam(\"name\") String name);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/DemoConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport org.apache.servicecomb.core.CoreConst;\n\npublic interface DemoConst {\n  String[] transports = new String[] {\"rest\", \"highway\", CoreConst.ANY_TRANSPORT};\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/DemoSSLCustom.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport java.io.File;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class DemoSSLCustom extends SSLCustom {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DemoSSLCustom.class);\n\n  @Override\n  public char[] decode(char[] encrypted) {\n    return encrypted;\n  }\n\n  @Override\n  public String getFullPath(String filename) {\n    LOGGER.info(\"current working dir :\" + System.getProperty(\"user.dir\"));\n\n    if (StringUtils.isEmpty(filename)) {\n      return null;\n    }\n\n    // local for different IDEs\n    File localFile = new File(\n        System.getProperty(\"user.dir\") + \"/demo/demo-springmvc/springmvc-server/src/main/resources/certificates/\"\n            + filename);\n    if (localFile.isFile()) {\n      return localFile.getAbsolutePath();\n    }\n\n    localFile = new File(\n        System.getProperty(\"user.dir\") + \"/src/main/resources/certificates/\"\n            + filename);\n    if (localFile.isFile()) {\n      return localFile.getAbsolutePath();\n    }\n\n    localFile = new File(System.getProperty(\"user.dir\") + \"/certificates/\" + filename);\n    if (localFile.isFile()) {\n      return localFile.getAbsolutePath();\n    }\n\n    // docker\n    localFile = new File(\"/maven/maven/certificates/\" + filename);\n    if (localFile.isFile()) {\n      return localFile.getAbsolutePath();\n    }\n\n    // in jar, maybe\n    LOGGER.info(\"not found file {} in file system, maybe in jar.\", filename);\n    return \"certificates/\" + filename;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/EmptyObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo;\n\npublic class EmptyObject {\n\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/Generic.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo;\n\npublic class Generic<T> {\n  public T value;\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.RestObjectMapper;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.BeanUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\n/**\n *  Demonstrate how to using String as raw type when using RestTemplate to invoke a service that use POJO. e.g.\n *  <p/>\n *  Provider: <p/>\n *  <code>\n *    public Response errorCodeWithHeader(MultiRequest request)\n *  </code>\n *   <p/>\n *  Consumer: <p/>\n *  <code>\n *    String stringRequest = \"{\\\"key\\\":\\\"testValue\\\"}\";\n *    template.postForEntity(url, stringRequest, MultiResponse200.class);\n *  </code>\n * <p/>\n *  <b>Caution:</b> json will convert String to object based on String constructor, using this feature will make default\n *  conversion change. You must write  convertValue to check possible types using.\n */\npublic class RestObjectMapperWithStringMapper extends RestObjectMapper {\n  private static final long serialVersionUID = 4279371572149490568L;\n\n  private static Logger LOGGER = LoggerFactory.getLogger(RestObjectMapperWithStringMapper.class);\n\n  public RestObjectMapperWithStringMapper() {\n    super();\n  }\n\n  @Override\n  public <T> T convertValue(Object fromValue, JavaType toValueType) throws IllegalArgumentException {\n    if (String.class.isInstance(fromValue)\n        && !BeanUtils.isSimpleValueType(toValueType.getRawClass())) {\n      try {\n        return super.readValue((String) fromValue, toValueType);\n      } catch (IOException e) {\n        LOGGER.error(\"Failed to convert value for {}.\", e.getMessage());\n      }\n    }\n    return super.convertValue(fromValue, toValueType);\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport com.fasterxml.jackson.annotation.JsonInclude.Include;\n\n/**\n *  Demonstrate how to using String as raw type when using RestTemplate to invoke a service that use POJO. e.g.\n *  <p/>\n *  Provider: <p/>\n *  <code>\n *    public Response errorCodeWithHeader(MultiRequest request)\n *  </code>\n *   <p/>\n *  Consumer: <p/>\n *  <code>\n *    String stringRequest = \"{\\\"key\\\":\\\"testValue\\\"}\";\n *    template.postForEntity(url, stringRequest, MultiResponse200.class);\n *  </code>\n * <p/>\n *  <b>Caution:</b> json will convert String to object based on String constructor, using this feature will make default\n *  conversion change. You must write  convertValue to check possible types using.\n */\npublic class RestObjectMapperWithStringMapperNotWriteNull extends RestObjectMapperWithStringMapper {\n  private static final long serialVersionUID = 4279371572149490560L;\n\n  public RestObjectMapperWithStringMapperNotWriteNull() {\n    super();\n    setSerializationInclusion(Include.NON_NULL);\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class TestMgr {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestMgr.class);\n\n  private static final List<Throwable> errorList = new ArrayList<>();\n\n  private static String msg = \"\";\n\n  private static final AtomicLong checks = new AtomicLong(0);\n\n  public static void setMsg(String msg) {\n    TestMgr.msg = msg;\n  }\n\n  public static void setMsg(String microserviceName, String transport) {\n    TestMgr.msg = String.format(\"microservice=%s, transport=%s\", microserviceName, transport);\n  }\n\n  public static void check(Object expect, Object real) {\n    check(expect, real, null);\n  }\n\n  public static void check(Object expect, Object real, Throwable error) {\n    checks.incrementAndGet();\n\n    if (expect == real) {\n      return;\n    }\n\n    String strExpect = String.valueOf(expect);\n    String strReal = String.valueOf(real);\n\n    if (!strExpect.equals(strReal)) {\n      Error newError = new Error(msg + \" | Expect \" + strExpect + \", but \" + strReal);\n      if (error != null) {\n        newError.setStackTrace(error.getStackTrace());\n      }\n      errorList.add(newError);\n    }\n  }\n\n  public static void checkNotEmpty(String real) {\n    checks.incrementAndGet();\n\n    if (StringUtils.isEmpty(real)) {\n      errorList.add(new Error(msg + \" | unexpected null result, method is \" + getCaller()));\n    }\n  }\n\n  public static void fail(String desc) {\n    failed(desc, new Exception(desc));\n  }\n\n  public static void failed(String desc, Throwable e) {\n    checks.incrementAndGet();\n\n    Error error = new Error(msg + \" | \" + desc + \", method is \" + getCaller());\n    if (e != null) {\n      error.setStackTrace(e.getStackTrace());\n    }\n    errorList.add(error);\n  }\n\n  public static boolean isSuccess() {\n    return errorList.isEmpty();\n  }\n\n  public static void summary() {\n    if (errorList.isEmpty()) {\n      LOGGER.info(\"............. test finished ............\");\n      LOGGER.info(\"............. total checks : \" + checks.get());\n      return;\n    }\n\n    LOGGER.info(\"............. test not finished ............\");\n    LOGGER.info(\"............. total checks : \" + checks.get());\n    LOGGER.info(\"............. total errors : \" + errorList.size());\n    LOGGER.info(\"............. error details: \");\n    for (Throwable e : errorList) {\n      LOGGER.info(\"\", e);\n    }\n  }\n\n  public static List<Throwable> errors() {\n    return errorList;\n  }\n\n  private static String getCaller() {\n    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();\n    if (stackTrace.length < 3) {\n      return null;\n    }\n    StackTraceElement stackTraceElement = stackTrace[3];\n    return stackTraceElement.getClassName() + \".\" + stackTraceElement.getMethodName();\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/api/IHeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.api;\n\nimport java.util.List;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.enums.Explode;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.enums.ParameterStyle;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.Path;\n\n@Path(\"/headerList\")\npublic interface IHeaderParamWithListSchema {\n  @Path(\"headerListDefault\")\n  @GET\n  String headerListDefault(\n      @HeaderParam(\"headerList\") List<String> headerList);\n\n  @Path(\"headerListCSV\")\n  @GET\n  String headerListCSV(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.FORM, explode = Explode.FALSE)\n          List<String> headerList);\n\n  @Path(\"headerListMULTI\")\n  @GET\n  String headerListMULTI(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.FORM, explode = Explode.TRUE)\n          List<String> headerList);\n\n  @Path(\"headerListSSV\")\n  @GET\n  String headerListSSV(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.SPACEDELIMITED, explode = Explode.FALSE)\n          List<String> headerList);\n\n  @Path(\"headerListPIPES\")\n  @GET\n  String headerListPIPES(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.PIPEDELIMITED, explode = Explode.FALSE)\n          List<String> headerList);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/api/IHeaderParamWithListSchemaSpringMvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.api;\n\n\nimport java.util.List;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.enums.Explode;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.enums.ParameterStyle;\n\n@RequestMapping(\"/headerList\")\npublic interface IHeaderParamWithListSchemaSpringMvc {\n  @GetMapping(\"headerListDefault\")\n  String headerListDefault(\n      @RequestHeader(\"headerList\") List<String> headerList);\n\n  @GetMapping(\"headerListCSV\")\n  String headerListCSV(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.FORM, explode = Explode.FALSE)\n          List<String> headerList);\n\n  @GetMapping(\"headerListMULTI\")\n  String headerListMULTI(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.FORM, explode = Explode.TRUE)\n          List<String> headerList);\n\n  @GetMapping(\"headerListSSV\")\n  String headerListSSV(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.SPACEDELIMITED, explode = Explode.FALSE)\n          List<String> headerList);\n\n  @GetMapping(\"headerListPIPES\")\n  String headerListPIPES(\n      @Parameter(name = \"headerList\", in = ParameterIn.HEADER, style = ParameterStyle.PIPEDELIMITED, explode = Explode.FALSE)\n          List<String> headerList);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/Compute.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.compute;\n\npublic interface Compute {\n\n  int add(int a, int b);\n\n  int reduce(int a, int b);\n\n  Person sayHello(Person user);\n\n  String testRawJsonString(String jsonInput);\n\n  String saySomething(String prefix, Person user);\n\n  void sayHi(String name);\n\n  void sayHi2(String name);\n\n  void sayHei(String name);\n\n  boolean isTrue();\n\n  String addString(String[] s);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/GenericParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.compute;\n\npublic class GenericParam<T> {\n  private String str;\n\n  private long num;\n\n  private T data;\n\n  public String getStr() {\n    return str;\n  }\n\n  public void setStr(String str) {\n    this.str = str;\n  }\n\n  public GenericParam<T> str(String str) {\n    this.str = str;\n    return this;\n  }\n\n  public long getNum() {\n    return num;\n  }\n\n  public void setNum(long num) {\n    this.num = num;\n  }\n\n  public GenericParam<T> num(long num) {\n    this.num = num;\n    return this;\n  }\n\n  public T getData() {\n    return data;\n  }\n\n  public void setData(T data) {\n    this.data = data;\n  }\n\n  public GenericParam<T> data(T data) {\n    this.data = data;\n    return this;\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder sb = new StringBuilder(\"GenericParam{\");\n    sb.append(\"str='\").append(str).append('\\'');\n    sb.append(\", num=\").append(num);\n    sb.append(\", data=\").append(data);\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/GenericParamExtended.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.compute;\n\npublic class GenericParamExtended<T> extends GenericParam<T> {\n  private String strExtended;\n\n  private int intExtended;\n\n  public String getStrExtended() {\n    return strExtended;\n  }\n\n  public void setStrExtended(String strExtended) {\n    this.strExtended = strExtended;\n  }\n\n  public GenericParamExtended<T> strExtended(String strExtended) {\n    this.strExtended = strExtended;\n    return this;\n  }\n\n  public int getIntExtended() {\n    return intExtended;\n  }\n\n  public void setIntExtended(int intExtended) {\n    this.intExtended = intExtended;\n  }\n\n  public GenericParamExtended<T> intExtended(int intExtended) {\n    this.intExtended = intExtended;\n    return this;\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder sb = new StringBuilder(\"GenericParamExtended{\");\n    sb.append(\"strExtended='\").append(strExtended).append('\\'');\n    sb.append(\", intExtended=\").append(intExtended);\n    sb.append(\", super=\").append(super.toString());\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/GenericParamWithJsonIgnore.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.compute;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\npublic class GenericParamWithJsonIgnore<T> {\n  private String str;\n\n  private long num;\n\n  @JsonIgnore\n  private T data;\n\n  public String getStr() {\n    return str;\n  }\n\n  public void setStr(String str) {\n    this.str = str;\n  }\n\n  public GenericParamWithJsonIgnore<T> str(String str) {\n    this.str = str;\n    return this;\n  }\n\n  public long getNum() {\n    return num;\n  }\n\n  public void setNum(long num) {\n    this.num = num;\n  }\n\n  public GenericParamWithJsonIgnore<T> num(long num) {\n    this.num = num;\n    return this;\n  }\n\n  public T getData() {\n    return data;\n  }\n\n  public void setData(T data) {\n    this.data = data;\n  }\n\n  public GenericParamWithJsonIgnore<T> data(T data) {\n    this.data = data;\n    return this;\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder sb = new StringBuilder(\"GenericParamWithJsonIgnore{\");\n    sb.append(\"str='\").append(str).append('\\'');\n    sb.append(\", num=\").append(num);\n    sb.append(\", data=\").append(data);\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/Person.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.compute;\n\npublic class Person {\n  private String name;\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return this.name;\n  }\n\n  public Person() {\n  }\n\n  public Person(String name) {\n    this.name = name;\n  }\n\n  @Override\n  public String toString() {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/controller/Controller.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.controller;\n\npublic interface Controller {\n  int add(int a, int b);\n\n  String sayHello(String name);\n\n  String saySomething(String prefix, Person user);\n\n  String sayHi(String name);\n\n  String sayHei(String name);\n\n  String sayHello1(String name);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/controller/Person.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.controller;\n\npublic class Person {\n  private String name;\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return this.name;\n  }\n\n  @Override\n  public String toString() {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/controller/PersonAlias.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.controller;\n\npublic class PersonAlias {\n  private String name;\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return this.name;\n  }\n\n  @Override\n  public String toString() {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/helloworld/greeter/Hello.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.helloworld.greeter;\n\npublic interface Hello {\n  String SayHello(String name);\n\n  String SayHelloAgain(String name);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/ignore/IgnoreInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.ignore;\n\npublic interface IgnoreInterface {\n  void ignoreMethod();\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/ignore/InputModelForTestIgnore.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.ignore;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\nimport io.vertx.core.json.JsonObject;\n\npublic class InputModelForTestIgnore {\n  @JsonIgnore\n  private String inputId = null;\n\n  private String content = null;\n\n  @JsonIgnore\n  private Object inputObject = null;\n\n  @JsonIgnore\n  private JsonObject inputJsonObject = null;\n\n  @JsonIgnore\n  private IgnoreInterface inputIgnoreInterface = null;\n\n  public String getInputId() {\n    return this.inputId;\n  }\n\n  public void setInputId(String inputId) {\n    this.inputId = inputId;\n  }\n\n  public String getContent() {\n    return this.content;\n  }\n\n  public void setContent(String content) {\n    this.content = content;\n  }\n\n  public Object getInputObject() {\n    return inputObject;\n  }\n\n  public void setInputObject(Object inputObject) {\n    this.inputObject = inputObject;\n  }\n\n  public JsonObject getInputJsonObject() {\n    return inputJsonObject;\n  }\n\n  public void setInputJsonObject(JsonObject inputJsonObject) {\n    this.inputJsonObject = inputJsonObject;\n  }\n\n  public IgnoreInterface getInputIgnoreInterface() {\n    return inputIgnoreInterface;\n  }\n\n  public void setInputIgnoreInterface(IgnoreInterface inputIgnoreInterface) {\n    this.inputIgnoreInterface = inputIgnoreInterface;\n  }\n\n  public InputModelForTestIgnore() {\n  }\n\n  public InputModelForTestIgnore(String inputId, String content, Object inputObject,\n      JsonObject inputJsonObject, IgnoreInterface inputIgnoreInterface) {\n    this.inputId = inputId;\n    this.content = content;\n    this.inputObject = inputObject;\n    this.inputJsonObject = inputJsonObject;\n    this.inputIgnoreInterface = inputIgnoreInterface;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/ignore/OutputModelForTestIgnore.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.ignore;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\nimport io.vertx.core.json.JsonObject;\n\npublic class OutputModelForTestIgnore {\n  @JsonIgnore\n  private String outputId = null;\n\n  private String inputId = null;\n\n  private String content = null;\n\n  @JsonIgnore\n  private Object inputObject = null;\n\n  @JsonIgnore\n  private JsonObject inputJsonObject = null;\n\n  @JsonIgnore\n  private IgnoreInterface inputIgnoreInterface = null;\n\n  @JsonIgnore\n  private Object outputObject = null;\n\n  @JsonIgnore\n  private JsonObject outputJsonObject = null;\n\n  @JsonIgnore\n  private IgnoreInterface outputIgnoreInterface = null;\n\n  public String getOutputId() {\n    return this.outputId;\n  }\n\n  public void setOutputId(String outputId) {\n    this.outputId = outputId;\n  }\n\n  public String getInputId() {\n    return this.inputId;\n  }\n\n  public void setInputId(String inputId) {\n    this.inputId = inputId;\n  }\n\n  public String getContent() {\n    return this.content;\n  }\n\n  public void setContent(String content) {\n    this.content = content;\n  }\n\n  public Object getInputObject() {\n    return inputObject;\n  }\n\n  public void setInputObject(Object inputObject) {\n    this.inputObject = inputObject;\n  }\n\n  public JsonObject getInputJsonObject() {\n    return inputJsonObject;\n  }\n\n  public void setInputJsonObject(JsonObject inputJsonObject) {\n    this.inputJsonObject = inputJsonObject;\n  }\n\n  public IgnoreInterface getInputIgnoreInterface() {\n    return inputIgnoreInterface;\n  }\n\n  public void setInputIgnoreInterface(IgnoreInterface inputIgnoreInterface) {\n    this.inputIgnoreInterface = inputIgnoreInterface;\n  }\n\n  public Object getOutputObject() {\n    return outputObject;\n  }\n\n  public void setOutputObject(Object outputObject) {\n    this.outputObject = outputObject;\n  }\n\n  public JsonObject getOutputJsonObject() {\n    return outputJsonObject;\n  }\n\n  public void setOutputJsonObject(JsonObject outputJsonObject) {\n    this.outputJsonObject = outputJsonObject;\n  }\n\n  public IgnoreInterface getOutputIgnoreInterface() {\n    return outputIgnoreInterface;\n  }\n\n  public void setOutputIgnoreInterface(IgnoreInterface outputIgnoreInterface) {\n    this.outputIgnoreInterface = outputIgnoreInterface;\n  }\n\n  public OutputModelForTestIgnore() {\n  }\n\n  public OutputModelForTestIgnore(String outputId, String inputId, String content, Object inputObject,\n      JsonObject inputJsonObject, IgnoreInterface inputIgnoreInterface, Object outputObject,\n      JsonObject outputJsonObject, IgnoreInterface outputIgnoreInterface) {\n    this.outputId = outputId;\n    this.inputId = inputId;\n    this.content = content;\n    this.inputObject = inputObject;\n    this.inputJsonObject = inputJsonObject;\n    this.inputIgnoreInterface = inputIgnoreInterface;\n    this.outputObject = outputObject;\n    this.outputJsonObject = outputJsonObject;\n    this.outputIgnoreInterface = outputIgnoreInterface;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBJob.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxbbean;\n\n\nimport jakarta.xml.bind.annotation.XmlAccessOrder;\nimport jakarta.xml.bind.annotation.XmlAccessType;\nimport jakarta.xml.bind.annotation.XmlAccessorOrder;\nimport jakarta.xml.bind.annotation.XmlAccessorType;\nimport jakarta.xml.bind.annotation.XmlRootElement;\n\n@XmlRootElement(name = \"job\")\n@XmlAccessorType(XmlAccessType.FIELD)\n@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)\npublic class JAXBJob {\n  private String name;\n\n  private String content;\n\n  public JAXBJob() {\n  }\n\n  public JAXBJob(String name, String content) {\n    this.name = name;\n    this.content = content;\n  }\n\n  @Override\n  public String toString() {\n    return \"Job{\" + \"name'\" + name + '\\'' + \", content='\" + content + '\\'' + '}';\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getContent() {\n    return content;\n  }\n\n  public void setContent(String content) {\n    this.content = content;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBPerson.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.jaxbbean;\n\nimport java.io.Serializable;\n\nimport jakarta.xml.bind.annotation.XmlAccessOrder;\nimport jakarta.xml.bind.annotation.XmlAccessorOrder;\nimport jakarta.xml.bind.annotation.XmlAttribute;\nimport jakarta.xml.bind.annotation.XmlElement;\nimport jakarta.xml.bind.annotation.XmlRootElement;\nimport jakarta.xml.bind.annotation.XmlTransient;\nimport jakarta.xml.bind.annotation.XmlType;\n\n@XmlType(propOrder = {\"name\", \"role\", \"job\"})\n@XmlRootElement(name = \"person\")\n@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)\npublic class JAXBPerson implements Serializable {\n  private static final long serialVersionUID = -7127275268696924681L;\n\n  private String name;\n\n  private int age;\n\n  private String role;\n\n  private String weight;\n\n  private JAXBJob job;\n\n  public JAXBPerson() {\n  }\n\n  public JAXBPerson(String name, int age, String role, String weight) {\n    this.name = name;\n    this.age = age;\n    this.role = role;\n    this.weight = weight;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  @XmlAttribute\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n\n  @XmlElement(nillable = true)\n  public String getRole() {\n    return role;\n  }\n\n  public void setRole(String role) {\n    this.role = role;\n  }\n\n  @XmlTransient\n  public String getWeight() {\n    return weight;\n  }\n\n  public void setWeight(String weight) {\n    this.weight = weight;\n  }\n\n  @XmlElement\n  public JAXBJob getJob() {\n    return job;\n  }\n\n  public void setJob(JAXBJob job) {\n    this.job = job;\n  }\n\n  @Override\n  public String toString() {\n    return \"Person{\" +\n        \"name='\" + name + '\\'' +\n        \", age=\" + age +\n        \", role='\" + role + '\\'' +\n        \", job=\" + job +\n        '}';\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.jaxrs.server.validation;\n\nimport java.util.List;\n\nimport jakarta.validation.constraints.NotNull;\n\npublic class ValidationModel {\n  @NotNull\n  private Integer age;\n\n  @NotNull\n  private List<String> members;\n\n  @NotNull\n  private String name;\n\n  public Integer getAge() {\n    return age;\n  }\n\n  public void setAge(Integer age) {\n    this.age = age;\n  }\n\n  public List<String> getMembers() {\n    return members;\n  }\n\n  public void setMembers(List<String> members) {\n    this.members = members;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/mapnull/ParseRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.mapnull;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ParseRequest {\n  public String msgType = \"\";\n\n  public String strMsg;\n\n  public String strID = \"\";\n\n  public Map<String, Object> flags = new HashMap<>();\n\n  public String getMsgType() {\n    return msgType;\n  }\n\n  public void setMsgType(String msgType) {\n    this.msgType = msgType;\n  }\n\n  public String getStrMsg() {\n    return strMsg;\n  }\n\n  public void setStrMsg(String strMsg) {\n    this.strMsg = strMsg;\n  }\n\n  public String getStrID() {\n    return strID;\n  }\n\n  public void setStrID(String strID) {\n    this.strID = strID;\n  }\n\n  public Map<String, Object> getFlags() {\n    return flags;\n  }\n\n  public void setFlags(Map<String, Object> flags) {\n    this.flags = flags;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/mapnull/ParseResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.mapnull;\n\nimport java.util.Map;\n\npublic class ParseResponse {\n  public String resultCode = \"99999999\";\n\n  public String resultInfo = \"unknown result\";\n\n  public String msgType = \"\";\n\n  public Map<String, String> msgHeader;\n\n  public Map<String, Object> msgBody;\n\n  public String getResultCode() {\n    return resultCode;\n  }\n\n  public void setResultCode(String resultCode) {\n    this.resultCode = resultCode;\n  }\n\n  public String getResultInfo() {\n    return resultInfo;\n  }\n\n  public void setResultInfo(String resultInfo) {\n    this.resultInfo = resultInfo;\n  }\n\n  public String getMsgType() {\n    return msgType;\n  }\n\n  public void setMsgType(String msgType) {\n    this.msgType = msgType;\n  }\n\n  public Map<String, String> getMsgHeader() {\n    return msgHeader;\n  }\n\n  public void setMsgHeader(Map<String, String> msgHeader) {\n    this.msgHeader = msgHeader;\n  }\n\n  public Map<String, Object> getMsgBody() {\n    return msgBody;\n  }\n\n  public void setMsgBody(Map<String, Object> msgBody) {\n    this.msgBody = msgBody;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/model/SpecialNameModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.model;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\npublic class SpecialNameModel {\n  // names starts with only one lower case , although getter/setter generated by IDE is correct,\n  // will cause jackson generate incorrect swagger names.\n  // @JsonProperty must be used to make json work in a predictable way.\n  @JsonProperty(\"aIntName\")\n  private int aIntName;\n\n  public int getaIntName() {\n    return aIntName;\n  }\n\n  public void setaIntName(int aIntName) {\n    this.aIntName = aIntName;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiErrorCode;\n\npublic class MultiRequest{\n  private String message;\n\n  private int code;\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiResponse200.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiErrorCode;\n\npublic class MultiResponse200 {\n  private String message;\n\n  private int code;\n\n  private long t200;\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n\n  public long getT200() {\n    return t200;\n  }\n\n  public void setT200(long t200) {\n    this.t200 = t200;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiResponse400.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiErrorCode;\n\npublic class MultiResponse400 {\n  private String message;\n\n  private int code;\n\n  private long t400;\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n\n  public long getT400() {\n    return t400;\n  }\n\n  public void setT400(long t400) {\n    this.t400 = t400;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiResponse500.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.multiErrorCode;\n\npublic class MultiResponse500 {\n  private String message;\n\n  private int code;\n\n  private long t500;\n\n  public String getMessage() {\n    return message;\n  }\n\n  public void setMessage(String message) {\n    this.message = message;\n  }\n\n  public int getCode() {\n    return code;\n  }\n\n  public void setCode(int code) {\n    this.code = code;\n  }\n\n  public long getT500() {\n    return t500;\n  }\n\n  public void setT500(long t500) {\n    this.t500 = t500;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/ProduceAppXmlProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.produceprocessor;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;\nimport org.apache.servicecomb.demo.utils.JAXBUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic class ProduceAppXmlProcessor implements ProduceProcessor {\n\n  @Override\n  public String getName() {\n    return MediaType.APPLICATION_XML;\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n\n  @Override\n  public void doEncodeResponse(OutputStream output, Object result) throws Exception {\n    output.write(JAXBUtils.convertToXml(result).getBytes(StandardCharsets.UTF_8));\n  }\n\n  @Override\n  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {\n    return JAXBUtils.convertToJavaBean(input, type);\n  }\n\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/override/ProduceAppXmlProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.produceprocessor.override;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;\nimport org.apache.servicecomb.demo.utils.JAXBUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic class ProduceAppXmlProcessor implements ProduceProcessor {\n\n  @Override\n  public String getName() {\n    return MediaType.APPLICATION_XML;\n  }\n\n  @Override\n  public int getOrder() {\n    return -1;\n  }\n\n  @Override\n  public void doEncodeResponse(OutputStream output, Object result) throws Exception {\n    output.write(JAXBUtils.convertToXml(result).getBytes(StandardCharsets.UTF_8));\n  }\n\n  @Override\n  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {\n    return JAXBUtils.convertToJavaBean(input, type);\n  }\n\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/AbstractModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport com.fasterxml.jackson.annotation.JsonSubTypes;\nimport com.fasterxml.jackson.annotation.JsonTypeInfo;\nimport com.fasterxml.jackson.annotation.JsonTypeInfo.Id;\n\n// 当使用 List<AbstractModel> 等 Collection 类型的时候， jackson 序列化不会携带类以外的其他属性\n// 即会忽略掉类型信息。 当抽象类型用于 Collection 类型参数的时候，必须使用已有的属性（例子中的 property = \"type\"）来确定类型，\n// 并在子类中显示指定属性的值，而不能使用和依赖jackson根据类型信息自己生成的类型。\n\n// 还有一种方法，是序列化的时候指定类型， see: https://www.studytrails.com/2016/09/12/java-jackson-serialization-list/\n// 但是多数序列化接口，包括 RestTemplate 等，都无法得知参数的类型。 这种方式难于应用于开发框架实现，因此对于Collection 类型参数场景，使用已有属性\n// 是最简洁的方法。\n\n@JsonTypeInfo(\n    use = Id.NAME, property = \"type\"\n)\n@JsonSubTypes({\n    @JsonSubTypes.Type(value = DefaultAbstractModel.class, name = \"default\"),\n    @JsonSubTypes.Type(value = SecondAbstractModel.class, name = \"second\"),\n})\npublic abstract class AbstractModel {\n  protected String type;\n\n  protected String name;\n\n  public abstract String getType();\n\n  public abstract String getName();\n\n  public abstract void setName(String name);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/DefaultAbstractModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\npublic class DefaultAbstractModel extends AbstractModel {\n  @Override\n  public String getType() {\n    return \"default\";\n  }\n\n  @Override\n  public String getName() {\n    return this.name;\n  }\n\n  @Override\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/GenericsModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport java.util.List;\n\npublic class GenericsModel {\n  private String name;\n\n  private List<List<String>> nameList;\n\n  private List<List<List<Object>>> objectLists;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public List<List<String>> getNameList() {\n    return nameList;\n  }\n\n  public void setNameList(List<List<String>> nameList) {\n    this.nameList = nameList;\n  }\n\n  public List<List<List<Object>>> getObjectLists() {\n    return objectLists;\n  }\n\n  public void setObjectLists(List<List<List<Object>>> objectLists) {\n    this.objectLists = objectLists;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/MapModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport java.util.Map;\n\npublic class MapModel {\n  private String name;\n\n  private Map<String, String> names;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public Map<String, String> getNames() {\n    return names;\n  }\n\n  public void setNames(Map<String, String> names) {\n    this.names = names;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/NotRecommendedServiceInf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport java.util.List;\nimport java.util.Map;\n\npublic interface NotRecommendedServiceInf {\n  Map<Long, Long> longMap(Map<Long, Long> map);\n\n  List<AbstractModel> listAbstractModel(List<AbstractModel> listModel);\n\n  AbstractModel abstractModel(AbstractModel model);\n\n  Map<Long, AbstractModel> mapAbstractModel(Map<Long, AbstractModel> mapModel);\n\n  WrappedAbstractModel wrappedAbstractModel(WrappedAbstractModel wrappedModel);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/SecondAbstractModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\npublic class SecondAbstractModel extends AbstractModel {\n  @Override\n  public String getType() {\n    return \"second\";\n  }\n\n  @Override\n  public String getName() {\n    return this.name;\n  }\n\n  @Override\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/Test.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\npublic interface Test {\n  String testStringArray(String[] arr);\n\n  String getTestString(String code);\n\n  String postTestStatic(int code);\n\n  String patchTestStatic(int code);\n\n  String testException(int code);\n\n  User wrapParam(TestRequest request);\n\n  User splitParam(int index, User user);\n\n  String addString(String[] strArr);\n\n  String testTraceId();\n\n  int[] testIntArray(int[] request);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/TestRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class TestRequest {\n  private int index;\n\n  private User user;\n\n  private List<User> users = new ArrayList<>();\n\n  private byte[] data;\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  public List<User> getUsers() {\n    return users;\n  }\n\n  public void setUsers(List<User> users) {\n    this.users = users;\n  }\n\n  public byte[] getData() {\n    return data;\n  }\n\n  public void setData(byte[] data) {\n    this.data = data;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/TestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\npublic class TestResponse {\n  private User user;\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestResponse [user=\" + user + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\n\npublic class User {\n  private String name = \"nameA\";\n\n  private int age = 100;\n\n  private int index;\n\n  private String[] names;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String[] getNames() {\n    return names;\n  }\n\n  public void setNames(String[] names) {\n    this.names = names;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  @Override\n  public String toString() {\n    return \"User [name=\" + name + \", age=\" + age + \", index=\" + index + \"]\";\n  }\n\n  public String jsonString() {\n    try {\n      return JsonUtils.writeValueAsString(this);\n    } catch (JsonProcessingException e) {\n      throw new IllegalStateException(e);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/server/WrappedAbstractModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.server;\n\nimport java.util.List;\nimport java.util.Map;\n\npublic class WrappedAbstractModel {\n  private String name;\n\n  private Map<Long, AbstractModel> mapModel;\n\n  private List<AbstractModel> listModel;\n\n  private AbstractModel model;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public Map<Long, AbstractModel> getMapModel() {\n    return mapModel;\n  }\n\n  public void setMapModel(Map<Long, AbstractModel> mapModel) {\n    this.mapModel = mapModel;\n  }\n\n  public List<AbstractModel> getListModel() {\n    return listModel;\n  }\n\n  public void setListModel(List<AbstractModel> listModel) {\n    this.listModel = listModel;\n  }\n\n  public AbstractModel getModel() {\n    return model;\n  }\n\n  public void setModel(AbstractModel model) {\n    this.model = model;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/smartcare/Application.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.smartcare;\n\nimport java.util.List;\n\npublic class Application {\n  private String name;\n\n  private String labelEN;\n\n  private String labelCH;\n\n  private String defaultGroup;\n\n  private String version;\n\n  private boolean dynamicFlag;\n\n  private List<Group> groups;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getLabelEN() {\n    return labelEN;\n  }\n\n  public void setLabelEN(String labelEN) {\n    this.labelEN = labelEN;\n  }\n\n  public String getLabelCH() {\n    return labelCH;\n  }\n\n  public void setLabelCH(String labelCH) {\n    this.labelCH = labelCH;\n  }\n\n  public String getDefaultGroup() {\n    return defaultGroup;\n  }\n\n  public void setDefaultGroup(String defaultGroup) {\n    this.defaultGroup = defaultGroup;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public boolean isDynamicFlag() {\n    return dynamicFlag;\n  }\n\n  public void setDynamicFlag(boolean dynamicFlag) {\n    this.dynamicFlag = dynamicFlag;\n  }\n\n  public List<Group> getGroups() {\n    return groups;\n  }\n\n  public void setGroups(List<Group> groups) {\n    this.groups = groups;\n  }\n\n  @Override\n  public String toString() {\n    return \"name=\" + name + \"\\n\"\n        + \"version=\" + version;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/smartcare/Group.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.smartcare;\n\npublic class Group {\n  private String name;\n\n  private String labelEN;\n\n  private String labelCH;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getLabelEN() {\n    return labelEN;\n  }\n\n  public void setLabelEN(String labelEN) {\n    this.labelEN = labelEN;\n  }\n\n  public String getLabelCH() {\n    return labelCH;\n  }\n\n  public void setLabelCH(String labelCH) {\n    this.labelCH = labelCH;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/smartcare/Response.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.smartcare;\n\npublic class Response {\n  private int resultCode;\n\n  private String resultMessage;\n\n  public int getResultCode() {\n    return resultCode;\n  }\n\n  public void setResultCode(int resultCode) {\n    this.resultCode = resultCode;\n  }\n\n  public String getResultMessage() {\n    return resultMessage;\n  }\n\n  public void setResultMessage(String resultMessage) {\n    this.resultMessage = resultMessage;\n  }\n\n  @Override\n  public String toString() {\n    return \"resultCode: \" + resultCode + \"\\n\" + \"resultMessage: \" + resultMessage;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/smartcare/SmartCare.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.smartcare;\n\npublic interface SmartCare {\n\n  Response addApplication(Application application);\n\n  Response delApplication(String appName);\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/utils/JAXBUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.utils;\n\nimport java.io.InputStream;\nimport java.io.StringWriter;\nimport java.nio.charset.StandardCharsets;\n\nimport javax.xml.parsers.SAXParserFactory;\nimport javax.xml.transform.Source;\nimport javax.xml.transform.sax.SAXSource;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.xml.sax.InputSource;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport jakarta.xml.bind.JAXBContext;\nimport jakarta.xml.bind.Marshaller;\nimport jakarta.xml.bind.Unmarshaller;\n\npublic class JAXBUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(JAXBUtils.class);\n\n  private JAXBUtils() {\n  }\n\n  public static String convertToXml(Object obj) {\n    return convertToXml(obj, StandardCharsets.UTF_8.toString());\n  }\n\n  public static String convertToXml(Object obj, String encoding) {\n    String result = null;\n    try {\n      JAXBContext context = JAXBContext.newInstance(obj.getClass());\n      Marshaller marshaller = context.createMarshaller();\n      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);\n      marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);\n\n      StringWriter writer = new StringWriter();\n      marshaller.marshal(obj, writer);\n      result = writer.toString();\n    } catch (Exception e) {\n      LOGGER.error(\"Bean convert to xml failed, error message: {}\", e.getMessage(), e);\n    }\n    return result;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T convertToJavaBean(InputStream xml, JavaType type) {\n    return (T) convertToJavaBean(xml, type.getRawClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T convertToJavaBean(InputStream xml, Class<T> c) {\n    T t = null;\n    try {\n      JAXBContext context = JAXBContext.newInstance(c);\n      Unmarshaller unmarshaller = context.createUnmarshaller();\n      t = (T) unmarshaller.unmarshal(XXEPrevention(xml));\n    } catch (Exception e) {\n      LOGGER.error(\"Xml convert to Bean failed, error message: {}\", e.getMessage());\n    }\n    return t;\n  }\n\n  private static Source XXEPrevention(InputStream xml) {\n    Source xmlSource = null;\n    SAXParserFactory spf = SAXParserFactory.newInstance();\n    try {\n      spf.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n      spf.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n      spf.setFeature(\"http://apache.org/xml/features/nonvalidating/load-external-dtd\", false);\n      xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(xml));\n    } catch (Exception e) {\n      LOGGER.error(\"Xml External Entity (XXE) Processing report error, error message: {}\", e.getMessage());\n    }\n    return xmlSource;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/validator/Student.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.validator;\n\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.NotNull;\n\npublic class Student {\n  @NotNull\n  private String name;\n\n  @Max(20)\n  private int age;\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return this.name;\n  }\n\n  public Student() {\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n\n  public Student(String name, int age) {\n    this.name = name;\n    this.age = age;\n  }\n\n  @Override\n  public String toString() {\n    return name + \" \" + age;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/java/org/apache/servicecomb/demo/validator/Teacher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.validator;\n\nimport jakarta.validation.constraints.NotBlank;\n\npublic class Teacher {\n\n  @NotBlank(message = \"must not be blank\")\n  private String name;\n\n  private String age;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getAge() {\n    return age;\n  }\n\n  public void setAge(String age) {\n    this.age = age;\n  }\n\n  @Override\n  public String toString() {\n    return name + \" \" + age;\n  }\n}\n"
  },
  {
    "path": "demo/demo-schema/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.produceprocessor.ProduceAppXmlProcessor\norg.apache.servicecomb.demo.produceprocessor.override.ProduceAppXmlProcessor\n"
  },
  {
    "path": "demo/demo-schema/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb-config-order: -1\n\ndemo.multi.service.center.serverB:\n  key1: key1\n  key2: key2\n  key3: key3\n\nservicecomb:\n  # verbose exceptions information\n  invocation:\n    exception:\n      print-stack-trace: true\n      print-rate-limit: true\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-spring-boot-pojo-client</artifactId>\n  <name>Java Chassis::Demo::Spring Boot::Transport::POJO Client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-spring-boot-transport</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.springboot.pojo.client.PojoClient</demo.main>\n  </properties>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>demo-spring-boot-pojo-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/client/DemoConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.client;\n\nimport org.apache.servicecomb.core.CoreConst;\n\npublic interface DemoConst {\n  String[] transports = new String[] {\"rest\", CoreConst.ANY_TRANSPORT};\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/client/PojoClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.client;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.context.annotation.ImportResource;\n\n/**\n * SpringmvcClient\n *\n *\n */\n@SpringBootApplication\n@ImportResource(value = \"classpath*:META-INF/spring/*.bean.xml\")\npublic class PojoClient {\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(PojoClient.class).web(WebApplicationType.SERVLET).build().run(args);\n\n    PojoClientTest.runTest();\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/client/PojoClientTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.client;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.springboot.pojo.server.schema.server.Test;\nimport org.apache.servicecomb.demo.springboot.pojo.server.schema.server.TestRequest;\nimport org.apache.servicecomb.demo.springboot.pojo.server.schema.server.User;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class PojoClientTest {\n  private static Logger LOGGER = LoggerFactory.getLogger(PojoClientTest.class);\n\n  @RpcReference(microserviceName = \"spring-boot-pojo-server\", schemaId = \"server\")\n  public static Test test;\n\n  private static Test testFromXml;\n\n  public static final byte[] buffer = new byte[1024];\n\n  public static final String SPLITPARAM_RESPONSE_USER_SUFFIX = \"(modified by MyHandler)\";\n\n  static {\n    Arrays.fill(buffer, (byte) 1);\n  }\n\n  public static void setTestFromXml(Test testFromXml) {\n    PojoClientTest.testFromXml = testFromXml;\n  }\n\n  public static void runTest() throws Exception {\n    String microserviceName = \"spring-boot-pojo-server\";\n\n    for (String transport : DemoConst.transports) {\n      InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n      TestMgr.setMsg(microserviceName, transport);\n      LOGGER.info(\"test {}, transport {}\", microserviceName, transport);\n\n      testNull(testFromXml);\n      testNull(test);\n      testEmpty(test);\n      testStringArray(test);\n      testChinese(test);\n      testStringHaveSpace(test);\n      testWrapParam(test);\n      testSplitParam(test);\n      testInputArray(test);\n\n      testCommonInvoke(transport);\n    }\n    TestMgr.summary();\n  }\n\n  private static void testInputArray(Test test) {\n    String result = test.addString(new String[] {\"a\", \"b\"});\n    LOGGER.info(\"input array result:{}\", result);\n    TestMgr.check(\"[a, b]\", result);\n  }\n\n  private static void testSplitParam(Test test) {\n    User result = test.splitParam(1, new User());\n    LOGGER.info(\"split param result:{}\", result);\n    TestMgr.check(\"User [name=nameA,  users count:0\" + SPLITPARAM_RESPONSE_USER_SUFFIX\n            + \", age=100, index=1]\",\n        result);\n  }\n\n  @SuppressWarnings({\"deprecation\"})\n  private static void testCommonInvoke(String transport) {\n    Map<String, Object> arguments = new HashMap<>();\n    Map<String, Object> wrap = new HashMap<>();\n    arguments.put(\"index\", 2);\n    arguments.put(\"user\", new User());\n    wrap.put(\"splitParamBody\", arguments);\n\n    Object result = InvokerUtils.syncInvoke(\"spring-boot-pojo-server\", \"server\", \"splitParam\", wrap, User.class);\n    TestMgr.check(\"User [name=nameA,  users count:0\" + SPLITPARAM_RESPONSE_USER_SUFFIX\n        + \", age=100, index=2]\", result);\n\n    arguments = new HashMap<>();\n    arguments.put(\"index\", 3);\n    arguments.put(\"user\", new User());\n    wrap = new HashMap<>();\n    wrap.put(\"splitParamBody\", arguments);\n    result =\n        InvokerUtils.syncInvoke(\"spring-boot-pojo-server\",\n            transport,\n            \"server\",\n            \"splitParam\",\n            wrap, User.class);\n    TestMgr.check(\"User [name=nameA,  users count:0\" + SPLITPARAM_RESPONSE_USER_SUFFIX\n        + \", age=100, index=3]\", result);\n  }\n\n  private static void testEmpty(Test test) {\n    TestMgr.check(\"code is ''\", test.getTestString(\"\"));\n  }\n\n  private static void testNull(Test test) {\n    TestMgr.check(\"code is 'null'\", test.getTestString(null));\n    TestMgr.check(null, test.wrapParam(null));\n  }\n\n  private static void testChinese(Test test) {\n    TestMgr.check(\"code is '测试'\", test.getTestString(\"测试\"));\n\n    User user = new User();\n    user.setName(\"名字\");\n    User result = test.splitParam(1, user);\n    TestMgr.check(\"名字,  users count:0\" + SPLITPARAM_RESPONSE_USER_SUFFIX, result.getName());\n  }\n\n  private static void testStringHaveSpace(Test test) {\n    TestMgr.check(\"code is 'a b'\", test.getTestString(\"a b\"));\n  }\n\n  private static void testStringArray(Test test) {\n    //        TestMgr.check(\"arr is '[a, , b]'\", test.testStringArray(new String[] {\"a\", null, \"b\"}));\n    TestMgr.check(\"arr is '[a, b]'\", test.testStringArray(new String[] {\"a\", \"b\"}));\n  }\n\n  private static void testWrapParam(Test test) {\n    User user = new User();\n\n    TestRequest request = new TestRequest();\n    request.setUser(user);\n    request.setIndex(0);\n    request.setData(buffer);\n    request.getUsers().add(user);\n\n    User result = test.wrapParam(request);\n    LOGGER.info(\"wrap param result:{}\", result);\n\n    TestMgr.check(\"User [name=nameA,  users count:1, age=100, index=0]\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/client/TestMgr.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.client;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class TestMgr {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestMgr.class);\n\n  private static final List<Throwable> errorList = new ArrayList<>();\n\n  private static String msg = \"\";\n\n  public static void setMsg(String msg) {\n    TestMgr.msg = msg;\n  }\n\n  public static void setMsg(String microserviceName, String transport) {\n    TestMgr.msg = String.format(\"microservice=%s, transport=%s\", microserviceName, transport);\n  }\n\n  public static void check(Object expect, Object real) {\n    String strExpect = String.valueOf(expect);\n    String strReal = String.valueOf(real);\n\n    if (!strExpect.equals(strReal)) {\n      errorList.add(new Error(msg + \" | Expect \" + strExpect + \", but \" + strReal));\n    }\n  }\n\n  public static void summary() {\n    if (errorList.isEmpty()) {\n      LOGGER.info(\"............. test finished ............\");\n      return;\n    }\n\n    LOGGER.info(\"............. test not finished ............\");\n    for (Throwable e : errorList) {\n      LOGGER.info(\"\", e);\n    }\n  }\n\n  public static List<Throwable> errors() {\n    return errorList;\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/Test.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\npublic interface Test {\n  String testStringArray(String[] arr);\n\n  String getTestString(String code);\n\n  String postTestStatic(int code);\n\n  String testException(int code);\n\n  User wrapParam(TestRequest request);\n\n  User splitParam(int index, User user);\n\n  String addString(String[] strArr);\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/TestRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class TestRequest {\n  private int index;\n\n  private User user;\n\n  private List<User> users = new ArrayList<>();\n\n  private byte[] data;\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  public List<User> getUsers() {\n    return users;\n  }\n\n  public void setUsers(List<User> users) {\n    this.users = users;\n  }\n\n  public byte[] getData() {\n    return data;\n  }\n\n  public void setData(byte[] data) {\n    this.data = data;\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/TestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\npublic class TestResponse {\n  private User user;\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestResponse [user=\" + user + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\npublic class User {\n  private String name = \"nameA\";\n\n  private int age = 100;\n\n  private int index;\n\n  private String[] names;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String[] getNames() {\n    return names;\n  }\n\n  public void setNames(String[] names) {\n    this.names = names;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  @Override\n  public String toString() {\n    return \"User [name=\" + name + \", age=\" + age + \", index=\" + index + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/resources/META-INF/spring/pojo.client.bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xmlns:cse=\"http://www.huawei.com/schema/paas/cse/rpc\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n\t\thttp://www.huawei.com/schema/paas/cse/rpc classpath:META-INF/spring/spring-paas-cse-rpc.xsd\">\n\n  <cse:rpc-reference id=\"server\" microservice-name=\"spring-boot-pojo-server\"\n    schema-id=\"server\" interface=\"org.apache.servicecomb.demo.springboot.pojo.server.schema.server.Test\"></cse:rpc-reference>\n\n  <bean class=\"org.apache.servicecomb.demo.springboot.pojo.client.PojoClientTest\">\n    <property name=\"testFromXml\" ref=\"server\"></property>\n  </bean>\n</beans>\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8082\n\nservicecomb:\n  service:\n    application: spring-boot-pojotest\n    name: spring-boot-pojo-client\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  handler:\n    chain:\n      Consumer:\n        default: loadbalance\n  isolation:\n    Consumer:\n      enabled: false\n  references:\n    pojo:\n      version-rule: 0.0.1\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/src/test/java/org/apache/servicecomb/demo/springboot/pojo/client/PojoClientIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.client;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = PojoClient.class)\npublic class PojoClientIT {\n\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    PojoClientTest.runTest();\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-spring-boot-pojo-server</artifactId>\n  <name>Java Chassis::Demo::Spring Boot::Transport::POJO Server</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-spring-boot-transport</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.springboot.pojo.server.PojoServer</demo.main>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/PojoServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class PojoServer {\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(PojoServer.class).web(WebApplicationType.SERVLET).build().run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/handler/MyHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.handler;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.demo.springboot.pojo.server.schema.server.User;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyHandler extends AbstractFilter implements ProviderFilter {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class);\n\n  public static final String SPLITPARAM_RESPONSE_USER_SUFFIX = \"(modified by MyHandler)\";\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 100;\n  }\n\n  @Override\n  public String getName() {\n    return \"test-my-filter\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    LOGGER.info(\"If you see this log, that means this demo project has been converted to ServiceComb framework.\");\n\n    return nextNode.onFilter(invocation).whenComplete((response, throwable) -> {\n      if (invocation.getOperationMeta().getSchemaQualifiedName().equals(\"server.splitParam\")) {\n        User user = response.getResult();\n        user.setName(user.getName() + SPLITPARAM_RESPONSE_USER_SUFFIX);\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/greeter/Hello.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.greeter;\n\npublic interface Hello {\n  String SayHello(String name);\n\n  String SayHelloAgain(String name);\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/HelloImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\nimport org.apache.servicecomb.demo.springboot.pojo.server.schema.greeter.Hello;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\n@RpcSchema(schemaId = \"helloworld.Greeter\")\npublic class HelloImpl implements Hello {\n\n  @Override\n  public String SayHello(String name) {\n    return \"Hello Message fast\";\n  }\n\n  @Override\n  public String SayHelloAgain(String name) {\n    try {\n      Thread.sleep(5000);\n    } catch (InterruptedException e) {\n      e.printStackTrace();\n    }\n    return \"Hello Message slow\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/Test.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\npublic interface Test {\n  String testStringArray(String[] arr);\n\n  String getTestString(String code);\n\n  String postTestStatic(int code);\n\n  String testException(int code);\n\n  User wrapParam(TestRequest request);\n\n  User splitParam(int index, User user);\n\n  String addString(String[] strArr);\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/TestImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\n@RpcSchema(schemaId = \"server\")\npublic class TestImpl implements Test {\n  @Override\n  public String testStringArray(String[] arr) {\n    return String.format(\"arr is '%s'\", Arrays.toString(arr));\n  }\n\n  @Override\n  public String getTestString(String code) {\n    return String.format(\"code is '%s'\", code);\n  }\n\n  @Override\n  public String postTestStatic(int code) {\n    return null;\n  }\n\n  private User doTest(int index, User user, List<User> users, byte[] data) {\n    if (user == null) {\n      user = new User();\n    }\n\n    user.setIndex(index);\n\n    int userCount = (users == null) ? 0 : users.size();\n    user.setName(user.getName() + \",  users count:\" + userCount);\n    return user;\n  }\n\n  @Override\n  public String testException(int code) {\n    String strCode = String.valueOf(code);\n    switch (code) {\n      case 200:\n        return strCode;\n      case 456:\n        throw new InvocationException(code, strCode, strCode + \" error\");\n      case 556:\n        throw new InvocationException(code, strCode, Arrays.asList(strCode + \" error\"));\n      case 557:\n        throw new InvocationException(code, strCode, Arrays.asList(Arrays.asList(strCode + \" error\")));\n      default:\n        break;\n    }\n\n    return \"not expected\";\n  }\n\n  @Override\n  public User splitParam(int index, User user) {\n    return doTest(index, user, null, null);\n  }\n\n  @Override\n  public User wrapParam(TestRequest request) {\n    if (request == null) {\n      return null;\n    }\n    return doTest(request.getIndex(), request.getUser(), request.getUsers(), request.getData());\n  }\n\n  @Override\n  public String addString(String[] strArr) {\n    String result = Arrays.toString(strArr);\n    System.out.println(\"addString: \" + result);\n    return result;\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/TestRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class TestRequest {\n  private int index;\n\n  private User user;\n\n  private List<User> users = new ArrayList<>();\n\n  private byte[] data;\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  public List<User> getUsers() {\n    return users;\n  }\n\n  public void setUsers(List<User> users) {\n    this.users = users;\n  }\n\n  public byte[] getData() {\n    return data;\n  }\n\n  public void setData(byte[] data) {\n    this.data = data;\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/TestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\npublic class TestResponse {\n  private User user;\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  @Override\n  public String toString() {\n    return \"TestResponse [user=\" + user + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/springboot/pojo/server/schema/server/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springboot.pojo.server.schema.server;\n\npublic class User {\n  private String name = \"nameA\";\n\n  private int age = 100;\n\n  private int index;\n\n  private String[] names;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String[] getNames() {\n    return names;\n  }\n\n  public void setNames(String[] names) {\n    this.names = names;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n\n  public int getIndex() {\n    return index;\n  }\n\n  public void setIndex(int index) {\n    this.index = index;\n  }\n\n  @Override\n  public String toString() {\n    return \"User [name=\" + name + \", age=\" + age + \", index=\" + index + \"]\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8080\n\nservicecomb:\n  service:\n    application: spring-boot-pojotest\n    name: spring-boot-pojo-server\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>demo-spring-boot-springmvc-client</artifactId>\n  <name>Java Chassis::Demo::Spring Boot::Spring MVC Client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-spring-boot-transport</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>demo-spring-boot-springmvc-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/java/org/apache/servicecomb/springboot/springmvc/client/PlaceHolderSchemaTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class PlaceHolderSchemaTest implements CategorizedTestCase {\n  @Override\n  public void testRestTransport() throws Exception {\n    RestOperations template = RestTemplateBuilder.create();\n    String result = template.getForObject(\"servicecomb://springmvc/placeholder/schema?name=test\", String.class);\n    TestMgr.check(\"test\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/java/org/apache/servicecomb/springboot/springmvc/client/ReactiveStreamIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.springboot.springmvc.client.ThirdSvcConfiguration.ReactiveStreamClient;\nimport org.apache.servicecomb.springboot.springmvc.client.ThirdSvcConfiguration.ReactiveStreamClient.Model;\nimport org.reactivestreams.Publisher;\nimport org.reactivestreams.Subscriber;\nimport org.reactivestreams.Subscription;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ReactiveStreamIT implements CategorizedTestCase {\n  @Autowired\n  @Qualifier(\"reactiveStreamProvider\")\n  ReactiveStreamClient reactiveStreamProvider;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testSseString(reactiveStreamProvider);\n    testSseModel(reactiveStreamProvider);\n  }\n\n  private void testSseModel(ReactiveStreamClient client) throws Exception {\n    Publisher<Model> result = client.sseModel();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(Model s) {\n        buffer.append(s.getName()).append(s.getAge());\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"jack0jack1jack2jack3jack4\", buffer.toString());\n  }\n\n  private void testSseString(ReactiveStreamClient client) throws Exception {\n    Publisher<String> result = client.sseString();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(String s) {\n        buffer.append(s);\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"abc\", buffer.toString());\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/java/org/apache/servicecomb/springboot/springmvc/client/SpringMvcClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n/**\n * SpringMvcClient\n *\n *\n */\n@SpringBootApplication\npublic class SpringMvcClient {\n\n  public static void main(final String[] args) throws Exception {\n\n    new SpringApplicationBuilder().sources(SpringMvcClient.class).web(WebApplicationType.SERVLET).build().run(args);\n\n    runTest();\n  }\n\n  public static void runTest() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"springmvc\");\n\n    TestMgr.summary();\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/java/org/apache/servicecomb/springboot/springmvc/client/TestAnnotationsSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;\nimport org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class TestAnnotationsSchema implements CategorizedTestCase {\n  private static final String microserviceName = \"springmvc\";\n\n  private static final RestTemplate templateUrlWithServiceName = new CseRestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());\n    testRequiredBody(templateUrlWithServiceName, microserviceName);\n    testRegExpPath();\n  }\n\n  private void testRegExpPath() {\n    String prefix = \"cse://\" + microserviceName;\n    String result = templateUrlWithServiceName.getForObject(prefix + \"/annotations/testRegExpPath/a?name={name}\",\n        String.class, \"a\");\n    TestMgr.check(\"a\", result);\n    result = templateUrlWithServiceName.getForObject(prefix + \"/annotations/testRegExpPath/a/b?name={name}\",\n        String.class, \"ab\");\n    TestMgr.check(\"ab\", result);\n    result = templateUrlWithServiceName.getForObject(prefix + \"/annotations/testRegExpPath/a/b/c?name={name}\",\n        String.class, \"abc\");\n    TestMgr.check(\"abc\", result);\n  }\n\n  private static void testRequiredBody(RestTemplate template, String microserviceName) {\n    String prefix = \"cse://\" + microserviceName;\n    Person user = new Person();\n\n    TestMgr.check(\"No user data found\",\n        template.postForObject(prefix + \"/annotations/saysomething?prefix={prefix}\",\n            user,\n            String.class,\n            \"ha\"));\n\n    user.setName(\"world\");\n    TestMgr.check(\"ha world\",\n        template.postForObject(prefix + \"/annotations/saysomething?prefix={prefix}\",\n            user,\n            String.class,\n            \"ha\"));\n\n    TestMgr.check(\"No user data found\",\n        template.postForObject(prefix + \"/annotations/saysomething?prefix={prefix}\",\n            null,\n            String.class,\n            \"ha\"));\n\n    TestMgr.check(\"No user name found\",\n        template.postForObject(prefix + \"/annotations/say\",\n            \"\",\n            String.class,\n            \"ha\"));\n    TestMgr.check(\"test\",\n        template.postForObject(prefix + \"/annotations/say\",\n            \"test\",\n            String.class,\n            \"ha\"));\n\n    try {\n      template.postForObject(prefix + \"/annotations/testRequiredBody\",\n          null,\n          String.class);\n      TestMgr.fail(\"should fail\");\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/java/org/apache/servicecomb/springboot/springmvc/client/ThirdSvcConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.reactivestreams.Publisher;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@Configuration\npublic class ThirdSvcConfiguration {\n  @RequestMapping(path = \"/\")\n  public interface ReactiveStreamClient {\n    class Model {\n      private String name;\n\n      private int age;\n\n      public Model() {\n\n      }\n\n      public Model(String name, int age) {\n        this.name = name;\n        this.age = age;\n      }\n\n      public int getAge() {\n        return age;\n      }\n\n      public Model setAge(int age) {\n        this.age = age;\n        return this;\n      }\n\n      public String getName() {\n        return name;\n      }\n\n      public Model setName(String name) {\n        this.name = name;\n        return this;\n      }\n    }\n\n    @GetMapping(\"/sseString\")\n    Publisher<String> sseString();\n\n    @GetMapping(\"/sseModel\")\n    Publisher<Model> sseModel();\n  }\n\n  @Bean(\"reactiveStreamProvider\")\n  public ReactiveStreamClient reactiveStreamProvider() {\n    return Invoker.createProxy(\"springmvc\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/java/org/apache/servicecomb/springboot/springmvc/client/UploadDownloadSchemaTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport java.io.File;\nimport java.nio.charset.StandardCharsets;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class UploadDownloadSchemaTest implements CategorizedTestCase {\n  RestOperations restOperations = RestTemplateBuilder.create();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testEmptyFileUploadWork();\n    testNonEmptyFileUploadWork();\n  }\n\n  private void testNonEmptyFileUploadWork() throws Exception {\n    String file2Content = \" bonjour\";\n    File someFile = File.createTempFile(\"upload2\", \".txt\");\n    FileUtils.writeStringToFile(someFile, file2Content, StandardCharsets.UTF_8, false);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.MULTIPART_FORM_DATA);\n    Map<String, Object> params = new HashMap<>();\n    params.put(\"name\", \"test\");\n    params.put(\"file\", someFile);\n    HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);\n    String url = \"servicecomb://springmvc/up/down/upload\";\n    String result = restOperations.postForObject(url, entity, String.class);\n    TestMgr.check(\"test; bonjour\", result);\n  }\n\n  private void testEmptyFileUploadWork() {\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.MULTIPART_FORM_DATA);\n    Map<String, Object> params = new HashMap<>();\n    params.put(\"name\", \"test\");\n    HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);\n    String url = \"servicecomb://springmvc/up/down/upload\";\n    String result = restOperations.postForObject(url, entity, String.class);\n    TestMgr.check(\"test;\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8999\nservicecomb:\n  service:\n    application: springmvcboottest\n    name: springmvcclient\n    version: 0.0.3\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  test:\n    vert:\n      transport: false\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb-config-order: 100\n\n3rd-svc:\n  urls:\n    - rest://localhost:8080?sslEnabled=false\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/src/test/java/org/apache/servicecomb/springboot/springmvc/client/SpringMvcClientIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = SpringMvcClient.class)\npublic class SpringMvcClientIT {\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    try {\n      SpringMvcClient.runTest();\n\n      Assertions.assertTrue(TestMgr.errors().isEmpty());\n    } catch (Throwable e) {\n      e.printStackTrace();\n      Assertions.fail(\"test case failed, message=\" + e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>demo-spring-boot-springmvc-server</artifactId>\n  <name>Java Chassis::Demo::Spring Boot::Spring MVC Server</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-spring-boot-transport</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/java/org/apache/servicecomb/springboot/springmvc/server/AnnotationsSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.server;\n\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.Parameters;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"annotations\")\n@RequestMapping(path = \"/springmvc/annotations\", produces = MediaType.APPLICATION_JSON)\npublic class AnnotationsSchema {\n  @GetMapping(path = \"/add\")\n  public int add(@RequestParam(name = \"a\", defaultValue = \"10\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"10\") int b) {\n    return a + b;\n  }\n\n  @RequestMapping(path = \"/sayhei\", method = RequestMethod.GET)\n  public String sayHei(@RequestHeader(name = \"name\", defaultValue = \"test\") String name) {\n    return \"hei \" + name;\n  }\n\n  @GetMapping(path = \"/sayhi\")\n  @Parameters({\n      @Parameter(name = \"name\", in = ParameterIn.QUERY, schema = @Schema(type = \"string\", defaultValue = \"test\")),\n      @Parameter(name = \"age\", in = ParameterIn.QUERY, schema = @Schema(type = \"integer\", defaultValue = \"20\"))\n  })\n  public String sayHi(String name, int age) {\n    return \"hi \" + name + \" your age is : \" + age;\n  }\n\n  @RequestMapping(path = \"/saysomething\", method = RequestMethod.POST)\n  public String saySomething(String prefix, @RequestBody(required = false) Person user) {\n    if (user == null || user.getName() == null || user.getName().isEmpty()) {\n      return \"No user data found\";\n    }\n    return prefix + \" \" + user.getName();\n  }\n\n  @RequestMapping(path = \"/say\", method = RequestMethod.POST)\n  public String say(@RequestBody(required = false) String user) {\n    if (user == null || user.isEmpty()) {\n      return \"No user name found\";\n    }\n    return user;\n  }\n\n  @RequestMapping(path = \"/testRequiredBody\", method = RequestMethod.POST)\n  public String testRequiredBody(@RequestBody(required = true) Person user) {\n    if (user == null) {\n      return \"Should not happen\";\n    }\n    return user.getName();\n  }\n\n  @RequestMapping(path = \"/testRegExpPath/{path: .+}\", method = RequestMethod.GET)\n  public String testRegExpPath(@RequestParam(\"name\") String name) {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/java/org/apache/servicecomb/springboot/springmvc/server/PlaceHolderSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"PlaceHolderSchema\")\n@RequestMapping(path = \"${test.placeholder.schema}\")\npublic class PlaceHolderSchema {\n  @GetMapping(path = \"/\")\n  public String root(@RequestParam(\"name\") String name) {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/java/org/apache/servicecomb/springboot/springmvc/server/ReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.springboot.springmvc.server;\n\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.reactivex.rxjava3.core.Flowable;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\npublic class ReactiveStreamController {\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  public Publisher<String> sseString() {\n    return Flowable.fromArray(\"a\", \"b\", \"c\");\n  }\n\n  @GetMapping(\"/sseModel\")\n  public Publisher<Model> sseModel() {\n    return Flowable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)\n        .map(item -> new Model(\"jack\", item.intValue()));\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/java/org/apache/servicecomb/springboot/springmvc/server/SpringmvcServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.server;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication(exclude = {WebMvcAutoConfiguration.class})\npublic class SpringmvcServer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SpringmvcServer.class);\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(SpringmvcServer.class).web(WebApplicationType.SERVLET).build().run(args);\n\n    assertPropertyCorrect();\n  }\n\n  private static void assertPropertyCorrect() {\n    // spring environment will fail for unresolved placeholder property\n    try {\n      LegacyPropertyFactory.getStringProperty(\"test.unresolved.placeholder\");\n    } catch (IllegalArgumentException e) {\n      return;\n    }\n    LOGGER.error(\"tests for configuration error, stop\");\n    SCBEngine.getInstance().destroy();\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/java/org/apache/servicecomb/springboot/springmvc/server/UploadDownloadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.springmvc.server;\n\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"UploadDownloadSchema\")\n@RequestMapping(path = \"/up/down\")\npublic class UploadDownloadSchema {\n  @PostMapping(path = \"/upload\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public String fileUpload(@RequestPart MultipartFile file, @RequestPart(value = \"name\") String name) throws Exception {\n    StringBuilder result = new StringBuilder();\n    result.append(name).append(\";\");\n    if (file == null || file.isEmpty()) {\n      return result.toString();\n    }\n    try (InputStream is = file.getInputStream()) {\n      result.append(IOUtils.toString(is, StandardCharsets.UTF_8));\n    }\n    return result.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8080\n\ntest.unresolved.placeholder: jdbc:postgresql://${ip}:${port}/pt\ntest:\n  placeholder:\n    schema: placeholder/schema\n\nservicecomb:\n  service:\n    application: springmvcboottest\n    name: springmvc\n    version: 0.0.3\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n  test:\n    vert:\n      transport: false\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  config:\n    ignoreResolveFailure: true\n\n  service:\n    registry:\n      registerPath: true\n      address: http://127.0.0.1:9980,http://127.0.0.1:30100\n      client:\n        timeout:\n          idle: 60\n          watch: 60\n      instance:\n        healthCheck:\n          interval: 3\n        pull:\n          interval: 10\n        watch: true\n      autodiscovery: true\n  uploads:\n    directory: target\n\n  rest:\n    address: 0.0.0.0:8080?sslEnabled=false\n"
  },
  {
    "path": "demo/demo-spring-boot-transport/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-spring-boot-transport</artifactId>\n  <name>Java Chassis::Demo::Spring Boot::Transport</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-spring-boot-springmvc-server</module>\n    <module>demo-spring-boot-springmvc-client</module>\n    <module>demo-spring-boot-pojo-server</module>\n    <module>demo-spring-boot-pojo-client</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n      <exclusions>\n        <exclusion>\n          <groupId>org.springframework.boot</groupId>\n          <artifactId>spring-boot-starter-logging</artifactId>\n        </exclusion>\n      </exclusions>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-springmvc/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-springmvc</artifactId>\n  <name>Java Chassis::Demo::Spring MVC</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>springmvc-server</module>\n    <module>springmvc-client</module>\n  </modules>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-springmvc</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>springmvc-client</artifactId>\n  <name>Java Chassis::Demo::Spring MVC::Client</name>\n\n  <dependencies>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.springmvc.SpringmvcClient</demo.main>\n  </properties>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <properties>\n        <demo.service.name>springmvc-server</demo.service.name>\n      </properties>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>servicecomb/service-center</name>\n                    <alias>service-center</alias>\n                    <run>\n                      <wait>\n                        <log>server is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>30100</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>30100:30100</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>${demo.service.name}:${project.version}</name>\n                    <alias>${demo.service.name}</alias>\n                    <run>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/${demo.service.name}-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>service-center:sc.servicecomb.io</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>7070:7070</port>\n                        <port>8080:8080</port>\n                      </ports>\n                      <dependsOn>\n                        <container>service-center</container>\n                      </dependsOn>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/SpringmvcClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.DemoConst;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.demo.springmvc.client.CodeFirstRestTemplateSpringmvc;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.provider.springmvc.reference.UrlWithProviderPrefixClientHttpRequestFactory;\nimport org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\nimport org.springframework.context.annotation.ImportResource;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n\n@SpringBootApplication\n@ImportResource(value = \"classpath*:META-INF/spring/*.bean.xml\")\npublic class SpringmvcClient {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SpringmvcClient.class);\n\n  private static RestTemplate templateUrlWithServiceName = new CseRestTemplate();\n\n  private static RestTemplate templateUrlWithProviderPrefix = new CseRestTemplate();\n\n  private static RestOperations restTemplate;\n\n  public static void main(String[] args) {\n    new SpringApplicationBuilder(SpringmvcClient.class).web(WebApplicationType.NONE).run(args);\n\n    run();\n  }\n\n  private static void changeTransport(String microserviceName, String transport) {\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.references.transport.\" + microserviceName, transport);\n    TestMgr.setMsg(microserviceName, transport);\n  }\n\n  public static void run() {\n    try {\n      runImpl();\n    } catch (Throwable e) {\n      TestMgr.check(\"success\", \"failed\");\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n    LOGGER.info(\"-------------- last time updated checks(maybe more/less): 1344 -------------\");\n  }\n\n  private static void runImpl() throws Exception {\n    testHttpClientsIsOk();\n\n    templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());\n    restTemplate = RestTemplateBuilder.create();\n    templateUrlWithProviderPrefix.setRequestFactory(new UrlWithProviderPrefixClientHttpRequestFactory(\"/pojo/rest\"));\n\n    String prefix = \"cse://springmvc\";\n    String microserviceName = \"springmvc\";\n\n    try {\n      // only works in rest, highway does not have name param, because not defined.\n      templateUrlWithServiceName.getForObject(prefix + \"/controller/sayhi?name=throwexception\", String.class);\n      TestMgr.check(\"true\", \"false\");\n    } catch (Exception e) {\n      TestMgr.check(\"true\", \"true\");\n    }\n    try {\n      // only works in rest, highway does not have name param, because not defined.\n      templateUrlWithServiceName.getForObject(prefix + \"/controller/sayhi?name=throwexception\", String.class);\n      TestMgr.check(\"true\", \"false\");\n    } catch (Exception e) {\n      TestMgr.check(\"true\", \"true\");\n    }\n\n    testHandler(microserviceName);\n    CodeFirstRestTemplateSpringmvc codeFirstClient =\n        BeanUtils.getContext().getBean(CodeFirstRestTemplateSpringmvc.class);\n    codeFirstClient.testCodeFirst(restTemplate, \"springmvc\", \"/codeFirstSpringmvc/\");\n    codeFirstClient.testCodeFirst(templateUrlWithProviderPrefix, \"springmvc\", \"/pojo/rest/codeFirstSpringmvc/\");\n    testAllTransport(microserviceName);\n    testRestTransport(microserviceName, prefix);\n    CategorizedTestCaseRunner.runCategorizedTestCase(microserviceName);\n  }\n\n  private static void testHandler(String microserviceName) {\n    changeTransport(microserviceName, \"rest\");\n    String prefix = \"cse://springmvc\";\n    String result = templateUrlWithServiceName.getForObject(prefix + \"/controller/sayHello1?name=tom\", String.class);\n    TestMgr.check(\"Hello tom,v\", result);\n  }\n\n  private static void testHttpClientsIsOk() {\n    TestMgr.check(HttpClients.getClient(\"http-transport-client\") != null, true);\n    TestMgr.check(HttpClients.getClient(\"http2-transport-client\") != null, true);\n\n    TestMgr.check(HttpClients.getClient(\"http-transport-client\", false) != null, true);\n    TestMgr.check(HttpClients.getClient(\"http2-transport-client\", false) != null, true);\n  }\n\n  private static void testRestTransport(String microserviceName, String prefix) {\n    changeTransport(microserviceName, \"rest\");\n\n    testControllerRest(templateUrlWithServiceName, microserviceName);\n    testSpringMvcDefaultValuesRest(templateUrlWithServiceName, microserviceName);\n    testSpringMvcDefaultValuesJavaPrimitiveRest(templateUrlWithServiceName, microserviceName);\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.set(\"Accept-Encoding\", \"gzip\");\n    HttpEntity<String> entity = new HttpEntity<>(headers);\n    ResponseEntity<String> entityCompress =\n        restTemplate.exchange(prefix\n            + \"/codeFirstSpringmvc/sayhi/compressed/{name}/v2\", HttpMethod.GET, entity, String.class, \"Test\");\n    TestMgr.check(\n        \"Test sayhi compressed:This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text!\",\n        entityCompress.getBody());\n    // if server response is compressed, the content-length header will be removed , so can't check this.\n    // the transfer-encoding header will be missing when the server is set to not compressed\n    if (entityCompress.getHeaders().get(\"transfer-encoding\") != null) {\n      TestMgr.check(\"chunked\", entityCompress.getHeaders().get(\"transfer-encoding\").get(0));\n    }\n\n    //0.5.0 later version metrics integration test\n    @SuppressWarnings(\"unchecked\")\n    Map<String, Double> metrics = restTemplate.getForObject(prefix + \"/scb/metrics\", Map.class);\n\n    //    TestMgr.check(true, metrics.get(\"jvm(name=heapUsed,statistic=gauge)\") != 0);\n    TestMgr.check(true, metrics.size() > 0);\n\n    //prometheus integration test\n    try {\n      String content = restTemplate\n          .getForObject(\"cse://springmvc/codeFirstSpringmvc/prometheusForTest\", String.class);\n\n      String application = LegacyPropertyFactory.getStringProperty(\"servicecomb.service.application\", \"\");\n\n      TestMgr.check(true,\n          content.contains(\n              \"servicecomb_invocation{appId=\\\"\" + application + \"\\\",operation=\\\"springmvc.codeFirst.addDate\"));\n      TestMgr.check(true,\n          content.contains(\n              \"servicecomb_invocation{appId=\\\"\" + application + \"\\\",operation=\\\"springmvc.codeFirst.sayHello\"));\n      TestMgr.check(true,\n          content\n              .contains(\"servicecomb_invocation{appId=\\\"\" + application + \"\\\",operation=\\\"springmvc.codeFirst.isTrue\"));\n      TestMgr.check(true,\n          content.contains(\"servicecomb_invocation{appId=\\\"\" + application + \"\\\",operation=\\\"springmvc.codeFirst.add\"));\n      TestMgr.check(true,\n          content\n              .contains(\"servicecomb_invocation{appId=\\\"\" + application + \"\\\",operation=\\\"springmvc.codeFirst.sayHi2\"));\n      TestMgr.check(true, content\n          .contains(\n              \"servicecomb_invocation{appId=\\\"\" + application + \"\\\",operation=\\\"springmvc.codeFirst.saySomething\"));\n\n      String[] metricLines = content.split(\"\\n\");\n      if (metricLines.length > 0) {\n        for (String metricLine : metricLines) {\n          if (!metricLine.startsWith(\"#\")) {\n            String[] metricKeyAndValue = metricLine.split(\" \");\n            if (!metricKeyAndValue[0].startsWith(\"jvm\") && !metricKeyAndValue[0].startsWith(\"os\")) {\n              if (Double.parseDouble(metricKeyAndValue[1]) < 0) {\n                TestMgr.check(\"true\", \"false\");\n                break;\n              }\n            }\n          }\n        }\n      } else {\n        TestMgr.check(\"true\", \"false\");\n      }\n    } catch (Exception e) {\n      LOGGER.error(\"\", e);\n      TestMgr.check(\"true\", \"false\");\n    }\n  }\n\n  private static void testAllTransport(String microserviceName) {\n    for (String transport : DemoConst.transports) {\n      changeTransport(microserviceName, transport);\n\n      TestMgr.setMsg(microserviceName, transport);\n\n      testControllerAllTransport(templateUrlWithServiceName, microserviceName);\n\n      testSpringMvcDefaultValuesAllTransport(templateUrlWithServiceName, microserviceName);\n      testSpringMvcDefaultValuesJavaPrimitiveAllTransport(templateUrlWithServiceName, microserviceName);\n    }\n  }\n\n  private static void testControllerRest(RestTemplate template, String microserviceName) {\n    String prefix = \"cse://\" + microserviceName;\n\n    TestMgr.check(\"hi world [world]\",\n        template.getForObject(prefix + \"/controller/sayhi?name=world\",\n            String.class));\n\n    TestMgr.check(\"hi world boot [world boot]\",\n        template.getForObject(prefix + \"/controller/sayhi?name=world boot\",\n            String.class));\n\n    TestMgr.check(\"hi world boot [world boot]\",\n        template.getForObject(prefix + \"/controller/sayhi?name=world+boot\",\n            String.class));\n\n    TestMgr.check(\"hi world1 [world1]\",\n        template.getForObject(prefix + \"/controller/sayhi?name={name}\",\n            String.class,\n            \"world1\"));\n\n    TestMgr.check(\"hi world1+world2 [world1+world2]\",\n        template.getForObject(prefix + \"/controller/sayhi?name={name}\",\n            String.class,\n            \"world1+world2\"));\n\n    TestMgr.check(\"hi hi 中国 [hi 中国]\",\n        template.getForObject(prefix + \"/controller/sayhi?name={name}\",\n            String.class,\n            \"hi 中国\"));\n\n    Map<String, String> params = new HashMap<>();\n    params.put(\"name\", \"world2\");\n    TestMgr.check(\"hi world2 [world2]\",\n        template.getForObject(prefix + \"/controller/sayhi?name={name}\",\n            String.class,\n            params));\n\n    try {\n      template.postForObject(prefix + \"/controller/sayhello/{name}\",\n          null,\n          String.class,\n          \"exception\");\n      TestMgr.check(true, false);\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 503);\n    }\n  }\n\n  private static void testControllerAllTransport(RestTemplate template, String microserviceName) {\n    String prefix = \"cse://\" + microserviceName;\n\n    TestMgr.check(7,\n        template.getForObject(prefix + \"/controller/add?a=3&b=4\",\n            Integer.class));\n\n    try {\n      template.getForObject(prefix + \"/controller/add\",\n          Integer.class);\n      TestMgr.check(\"failed\", \"success\");\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 400);\n    }\n\n    TestMgr.check(\"hello world\",\n        template.postForObject(prefix + \"/controller/sayhello/{name}\",\n            null,\n            String.class,\n            \"world\"));\n    TestMgr.check(\"hello hello 中国\",\n        template.postForObject(prefix + \"/controller/sayhello/{name}\",\n            null,\n            String.class,\n            \"hello 中国\"));\n\n    try {\n      template.postForObject(prefix + \"/controller/sayhello/{name}\",\n          null,\n          String.class,\n          \"exception\");\n      TestMgr.check(true, false);\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), 503);\n    }\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"name\", \"world\");\n    @SuppressWarnings(\"rawtypes\")\n    HttpEntity entity = new HttpEntity<>(null, headers);\n    ResponseEntity<String> response = template.exchange(prefix + \"/controller/sayhei\",\n        HttpMethod.GET,\n        entity,\n        String.class);\n    TestMgr.check(\"hei world\", response.getBody());\n\n    Person user = new Person();\n    user.setName(\"world\");\n    TestMgr.check(\"ha world\",\n        template.postForObject(prefix + \"/controller/saysomething?prefix={prefix}\",\n            user,\n            String.class,\n            \"ha\"));\n  }\n\n  private static void testSpringMvcDefaultValuesRest(RestTemplate template, String microserviceName) {\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/SpringMvcDefaultValues/\";\n    String result = template.getForObject(cseUrlPrefix + \"/query?d=10\", String.class);\n    TestMgr.check(\"Hello 20bobo4010\", result);\n    boolean failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2?d=2&e=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2?a=&d=2&e=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query2?d=30&e=2\", String.class);\n    TestMgr.check(\"Hello 20bobo40302\", result);\n\n    failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query3?a=2&b=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n  }\n\n  private static void testSpringMvcDefaultValuesAllTransport(RestTemplate template, String microserviceName) {\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/SpringMvcDefaultValues/\";\n    //default values\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();\n    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);\n    String result = template.postForObject(cseUrlPrefix + \"/form\", request, String.class);\n    TestMgr.check(\"Hello 20bobo\", result);\n\n    headers = new HttpHeaders();\n    HttpEntity<String> entity = new HttpEntity<>(null, headers);\n    result = template.postForObject(cseUrlPrefix + \"/header\", entity, String.class);\n    TestMgr.check(\"Hello 20bobo30\", result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query?d=10\", String.class);\n    TestMgr.check(\"Hello 20bobo4010\", result);\n    boolean failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2?d=2&e=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query2?a=&d=2&e=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query2?d=30&e=2\", String.class);\n    TestMgr.check(\"Hello 20bobo40302\", result);\n\n    failed = false;\n    result = null;\n    try {\n      result = template.getForObject(cseUrlPrefix + \"/query3?a=2&b=2\", String.class);\n    } catch (InvocationException e) {\n      failed = true;\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n    TestMgr.check(true, failed);\n    TestMgr.check(null, result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query3?a=30&b=2\", String.class);\n    TestMgr.check(\"Hello 302\", result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query3?a=30\", String.class);\n    TestMgr.check(\"Hello 30null\", result);\n\n    //input values\n    headers = new HttpHeaders();\n    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    HttpEntity<Map<String, String>> requestPara = new HttpEntity<>(null, headers);\n    result = template.postForObject(cseUrlPrefix + \"/form?a=30&b=sam\", requestPara, String.class);\n    TestMgr.check(\"Hello 30sam\", result);\n\n    headers = new HttpHeaders();\n    headers.add(\"a\", \"30\");\n    headers.add(\"b\", \"sam\");\n    headers.add(\"c\", \"40\");\n    entity = new HttpEntity<>(null, headers);\n    result = template.postForObject(cseUrlPrefix + \"/header\", entity, String.class);\n    TestMgr.check(\"Hello 30sam40\", result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query?a=3&b=sam&c=5&d=30\", String.class);\n    TestMgr.check(\"Hello 3sam530\", result);\n\n    result = template.getForObject(cseUrlPrefix + \"/query2?a=3&b=4&c=5&d=30&e=2\", String.class);\n    TestMgr.check(\"Hello 345302\", result);\n  }\n\n  private static void testSpringMvcDefaultValuesJavaPrimitiveAllTransport(RestTemplate template,\n      String microserviceName) {\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/SpringMvcDefaultValues/\";\n    //default values with primitive\n    String result = template.postForObject(cseUrlPrefix + \"/javaprimitiveint\", null, String.class);\n    TestMgr.check(\"Hello 0bobo\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivenumber\", null, String.class);\n    TestMgr.check(\"Hello 0.0false\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivestr\", null, String.class);\n    TestMgr.check(\"Hello\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivecomb\", null, String.class);\n    TestMgr.check(\"Hello nullnull\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/allprimitivetypes\", null, String.class);\n    TestMgr.check(\"Hello false,\\0,0,0,0,0,0.0,0.0,null\", result);\n\n    result = template.postForObject(cseUrlPrefix\n            + \"/allprimitivetypes?pBoolean=true&pChar=c&pByte=20&pShort=30&pInt=40&pLong=50&pFloat=60&pDouble=70&pDoubleWrap=80\",\n        null, String.class);\n    TestMgr.check(\"Hello true,c,20,30,40,50,60.0,70.0,80.0\", result);\n  }\n\n  private static void testSpringMvcDefaultValuesJavaPrimitiveRest(RestTemplate template, String microserviceName) {\n    String cseUrlPrefix = \"cse://\" + microserviceName + \"/SpringMvcDefaultValues/\";\n    //default values with primitive\n    String result = template.postForObject(cseUrlPrefix + \"/javaprimitiveint\", null, String.class);\n    TestMgr.check(\"Hello 0bobo\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivenumber\", null, String.class);\n    TestMgr.check(\"Hello 0.0false\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivestr\", null, String.class);\n    TestMgr.check(\"Hello\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/javaprimitivecomb\", null, String.class);\n    TestMgr.check(\"Hello nullnull\", result);\n\n    result = template.postForObject(cseUrlPrefix + \"/allprimitivetypes\", null, String.class);\n    TestMgr.check(\"Hello false,\\0,0,0,0,0,0.0,0.0,null\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.demo.CodeFirstRestTemplate;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.apache.servicecomb.provider.springmvc.reference.CseHttpEntity;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.io.FileSystemResource;\nimport org.springframework.core.io.Resource;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.servlet.http.Part;\n\n@Component\npublic class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {\n  interface UploadPartAndFile {\n    String fileUpload(Part file1, File someFile);\n  }\n\n  interface UploadStreamAndResource {\n    String fileUpload(InputStream file1, Resource someFile);\n  }\n\n  private UploadPartAndFile uploadPartAndFile = Invoker.createProxy(\"springmvc\", \"codeFirst\", UploadPartAndFile.class);\n\n  private UploadStreamAndResource uploadStreamAndResource =\n      Invoker.createProxy(\"springmvc\", \"codeFirst\", UploadStreamAndResource.class);\n\n  private TestResponse testResponse = new TestResponse();\n\n  private TestObject testObject = new TestObject();\n\n  private TestGeneric testGeneric = new TestGeneric();\n\n  private TestRestTemplate testRestTemplate = new TestRestTemplate();\n\n  private TestContentType testContentType = new TestContentType();\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n    testResponse.setEnvironment(environment);\n  }\n\n  @Override\n  protected void testOnlyRest(String microservcieName, RestOperations template, String cseUrlPrefix) {\n    try {\n      testUpload(template, cseUrlPrefix);\n    } catch (IOException e) {\n      throw new IllegalStateException(e);\n    }\n    testResponseEntity(\"springmvc\", template, cseUrlPrefix);\n    testCodeFirstTestFormRest(template, cseUrlPrefix);\n\n    testResponse.runRest();\n    testObject.runRest();\n    testGeneric.runRest();\n    testRestTemplate.runRest();\n    testContentType.runAllTest();\n\n    super.testOnlyRest(microservcieName, template, cseUrlPrefix);\n  }\n\n  @Override\n  protected void testOnlyHighway(RestOperations template, String cseUrlPrefix) {\n    testResponse.runHighway();\n    testObject.runHighway();\n    testGeneric.runHighway();\n    testCodeFirstTestFormHighway(template, cseUrlPrefix);\n    super.testOnlyHighway(template, cseUrlPrefix);\n  }\n\n  @Override\n  protected void testAllTransport(String microserviceName, RestOperations template, String cseUrlPrefix) {\n    testResponse.runAllTransport();\n    testObject.runAllTransport();\n    testGeneric.runAllTransport();\n    testRestTemplate.runAllTest();\n    testResponseEntity(\"springmvc\", template, cseUrlPrefix);\n    testCodeFirstTestForm(template, cseUrlPrefix);\n\n    super.testAllTransport(microserviceName, template, cseUrlPrefix);\n  }\n\n  private void testUpload(RestOperations template, String cseUrlPrefix) throws IOException {\n    String file1Content = \"hello world\";\n    File file1 = File.createTempFile(\"测 试\", \".txt\");\n    FileUtils.writeStringToFile(file1, file1Content, StandardCharsets.UTF_8, false);\n\n    String file2Content = \" bonjour\";\n    File someFile = File.createTempFile(\"upload2\", \".txt\");\n    FileUtils.writeStringToFile(someFile, file2Content, StandardCharsets.UTF_8, false);\n\n    String expect = String.format(\"%s:%s:%s\\n\"\n            + \"%s:%s:%s\",\n        file1.getName(),\n        MediaType.TEXT_PLAIN_VALUE,\n        file1Content,\n        someFile.getName(),\n        MediaType.TEXT_PLAIN_VALUE,\n        file2Content);\n\n    String result = testRestTemplateUpload(template, cseUrlPrefix, file1, someFile);\n    TestMgr.check(expect, result);\n\n    result = uploadPartAndFile.fileUpload(new FilePart(null, file1), someFile);\n    TestMgr.check(expect, result);\n\n    expect = \"hello world\";\n    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();\n    map.add(\"file1\", new FileSystemResource(file1));\n    result = template.postForObject(\n        cseUrlPrefix + \"/upload1\",\n        new HttpEntity<>(map),\n        String.class);\n    TestMgr.check(expect, result);\n\n    expect = String.format(\"null:%s:%s\\n\"\n            + \"%s:%s:%s\",\n        MediaType.APPLICATION_OCTET_STREAM_VALUE,\n        file1Content,\n        someFile.getName(),\n        MediaType.TEXT_PLAIN_VALUE,\n        file2Content);\n    result = uploadStreamAndResource\n        .fileUpload(new ByteArrayInputStream(file1Content.getBytes(StandardCharsets.UTF_8)),\n            new org.springframework.core.io.PathResource(someFile.getAbsolutePath()));\n    TestMgr.check(expect, result);\n  }\n\n  private String testRestTemplateUpload(RestOperations template, String cseUrlPrefix, File file1, File someFile) {\n    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();\n    map.add(\"file1\", new FileSystemResource(file1));\n    map.add(\"someFile\", new FileSystemResource(someFile));\n\n    return template.postForObject(\n        cseUrlPrefix + \"/upload\",\n        new HttpEntity<>(map),\n        String.class);\n  }\n\n  private void testResponseEntity(String microserviceName, RestOperations template, String cseUrlPrefix) {\n    Map<String, Object> body = new HashMap<>();\n    Date date = new Date();\n    body.put(\"date\", date);\n\n    CseHttpEntity<Map<String, Object>> httpEntity = new CseHttpEntity<>(body);\n    httpEntity.addContext(\"contextKey\", \"contextValue\");\n\n    String srcName = BootStrapProperties.readServiceName(environment);\n\n    ResponseEntity<Date> responseEntity =\n        template.exchange(cseUrlPrefix + \"responseEntity\", HttpMethod.POST, httpEntity, Date.class);\n    TestMgr.check(date, responseEntity.getBody());\n    TestMgr.check(\"h1v \" + srcName, responseEntity.getHeaders().getFirst(\"h1\"));\n    TestMgr.check(\"h2v \" + srcName, responseEntity.getHeaders().getFirst(\"h2\"));\n    checkStatusCode(microserviceName, 202, responseEntity.getStatusCode());\n\n    responseEntity =\n        template.exchange(cseUrlPrefix + \"responseEntity\", HttpMethod.PATCH, httpEntity, Date.class);\n    TestMgr.check(date, responseEntity.getBody());\n    TestMgr.check(\"h1v \" + srcName, responseEntity.getHeaders().getFirst(\"h1\"));\n    TestMgr.check(\"h2v \" + srcName, responseEntity.getHeaders().getFirst(\"h2\"));\n    checkStatusCode(microserviceName, 202, responseEntity.getStatusCode());\n\n    int retryResult = template.getForObject(cseUrlPrefix + \"retrySuccess?a=2&b=3\", Integer.class);\n    TestMgr.check(retryResult, 5);\n    retryResult = template.getForObject(cseUrlPrefix + \"retrySuccess?a=2&b=3\", Integer.class);\n    TestMgr.check(retryResult, 5);\n  }\n\n  private void testCodeFirstTestForm(RestOperations template, String cseUrlPrefix) {\n    HttpHeaders formHeaders = new HttpHeaders();\n    formHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    Map<String, String> map = new HashMap<>();\n    String code = \"servicecomb%2bwelcome%40%23%24%25%5e%26*()%3d%3d\";\n    map.put(\"form1\", code);\n    HttpEntity<Map<String, String>> formEntry = new HttpEntity<>(map, formHeaders);\n    TestMgr.check(code + \"null\",\n        template.postForEntity(cseUrlPrefix + \"/testform\", formEntry, String.class).getBody());\n    map.put(\"form2\", \"hello\");\n    TestMgr\n        .check(code + \"hello\", template.postForEntity(cseUrlPrefix + \"/testform\", formEntry, String.class).getBody());\n  }\n\n  private void testCodeFirstTestFormHighway(RestOperations template, String cseUrlPrefix) {\n    HttpHeaders formHeaders = new HttpHeaders();\n    formHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    Map<String, String> map = new HashMap<>();\n    String code = \"servicecomb%2bwelcome%40%23%24%25%5e%26*()%3d%3d\";\n    map.put(\"form1\", code);\n    map.put(\"form2\", \"\");\n    HttpEntity<Map<String, String>> formEntry = new HttpEntity<>(map, formHeaders);\n    TestMgr.check(code + \"\", template.postForEntity(cseUrlPrefix + \"/testform\", formEntry, String.class).getBody());\n\n    map = new HashMap<>();\n    code = \"servicecomb%2bwelcome%40%23%24%25%5e%26*()%3d%3d\";\n    map.put(\"form1\", code);\n    map.put(\"form2\", null);\n    formEntry = new HttpEntity<>(map, formHeaders);\n    TestMgr.check(code + \"null\",\n        template.postForEntity(cseUrlPrefix + \"/testform\", formEntry, String.class).getBody());\n  }\n\n  private void testCodeFirstTestFormRest(RestOperations template, String cseUrlPrefix) {\n    HttpHeaders formHeaders = new HttpHeaders();\n    formHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);\n    Map<String, String> map = new HashMap<>();\n    String code = \"servicecomb%2bwelcome%40%23%24%25%5e%26*()%3d%3d\";\n    map.put(\"form1\", code);\n    map.put(\"form2\", \"\");\n    HttpEntity<Map<String, String>> formEntry = new HttpEntity<>(map, formHeaders);\n    // Rest will have empty string, but users will try to avoid depend on this, This is different from highway\n    TestMgr.check(code + \"\", template.postForEntity(cseUrlPrefix + \"/testform\", formEntry, String.class).getBody());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSpringmvcIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.EmptyObject;\nimport org.apache.servicecomb.demo.Generic;\nimport org.apache.servicecomb.demo.compute.GenericParam;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.demo.springmvc.decoderesponse.DecodeTestResponse;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\n\npublic interface CodeFirstSpringmvcIntf {\n  ResponseEntity<Date> responseEntity(Date date);\n\n  Response cseResponse();\n\n  Response cseResponseCorrect();\n\n  Object testObject(Object input);\n\n  EmptyObject testEmpty(EmptyObject input);\n\n  Map<String, Object> testMapObject(Map<String, Object> input);\n\n  List<Object> testListObject(List<Object> input);\n\n  Holder<Object> testHolderObject(Holder<Object> input);\n\n  Holder<User> testHolderUser(Holder<User> input);\n\n  Generic<User> testGenericUser(Generic<User> input);\n\n  Generic<Long> testGenericLong(Generic<Long> input);\n\n  Generic<Date> testGenericDate(Generic<Date> input);\n\n  Generic<HttpStatus> testGenericEnum(Generic<HttpStatus> input);\n\n  Generic<Generic<User>> testGenericGenericUser(Generic<Generic<User>> input);\n\n  void testvoidInRPC();\n\n  Void testVoidInRPC();\n\n  String checkQueryObject(String name, String otherName, Person requestBody);\n\n  String checkQueryGenericObject(GenericParam<Person> requestBody, String str, long num);\n\n  String checkQueryGenericString(String str, GenericParam<Person> requestBody, long num, String data,\n      String strExtended, int intExtended);\n\n  String testDelay();\n\n  String testAbort();\n\n  DecodeTestResponse testDecodeResponseError();\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CustomEndpointDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.registry.discovery.AbstractEndpointDiscoveryFilter;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\n\npublic class CustomEndpointDiscoveryFilter extends AbstractEndpointDiscoveryFilter {\n  @Override\n  protected String findTransportName(DiscoveryContext context, DiscoveryTreeNode parent) {\n    //only need rest endpoints\n    return \"rest\";\n  }\n\n  @Override\n  protected Object createEndpoint(DiscoveryContext context, String transportName, String endpoint,\n      StatefulDiscoveryInstance instance) {\n    return endpoint;\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/ICompatible1xTestSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\npublic interface ICompatible1xTestSchema {\n  String parameterName(int c, int d);\n\n  @Operation(operationId = \"parameterName\", summary = \"parameterName\")\n  String parameterNamePartMatchLeft(int a, int d);\n\n  @Operation(operationId = \"parameterName\", summary = \"parameterName\")\n  String parameterNamePartMatchRight(int c, int b);\n\n  String parameterName(InvocationContext context, int c, int d);\n\n  String parameterNameServerContext(int c, int d);\n\n  String beanParameter(String notName, int notAge);\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/ResponseOKData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\npublic class ResponseOKData {\n  private String errorCode;\n\n  private String errorMessage;\n\n  public ResponseOKData() {\n\n  }\n\n  public ResponseOKData(String errorCode, String errorMessage) {\n    this.errorCode = errorCode;\n    this.errorMessage = errorMessage;\n  }\n\n  public String getErrorCode() {\n    return errorCode;\n  }\n\n  public void setErrorCode(String errorCode) {\n    this.errorCode = errorCode;\n  }\n\n  public String getErrorMessage() {\n    return errorMessage;\n  }\n\n  public void setErrorMessage(String errorMessage) {\n    this.errorMessage = errorMessage;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SchemeInterfaceSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\npublic interface SchemeInterfaceSpringmvc {\n  int add(int a, int b);\n\n  int reduce(int a, int b);\n\n  String tailingSlash(int a, int b);\n\n  String nonTailingSlash(int a, int b);\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringMVCSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.ExampleObject;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport jakarta.servlet.http.HttpServletRequest;\n\n@RestSchema(schemaId = \"SpringMVCSchema\")\n@RequestMapping(\"/springMvcSchema\")\npublic class SpringMVCSchema {\n  // TODO: examples not serialized by yaml parser\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(\n          schema = @Schema(implementation = String.class, example = \"wget http://localhost/springMvcSchema/testApiExample\"),\n          examples = {@ExampleObject(value = \"wget http://localhost/springMvcSchema/testApiExample\", name = \"text\"),\n              @ExampleObject(value = \"{name:hello}\", name = \"application/json\"),\n              @ExampleObject(value = \"{name:hello}\", name = \"json\")})\n          , description = \"success\"\n      )})\n  @RequestMapping(path = \"/testApiExample\", method = RequestMethod.POST)\n  public String testApiExample(@RequestBody String name, HttpServletRequest request) {\n    return null;\n  }\n\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class),\n          examples = {@ExampleObject(value = \"wget http://localhost/springMvcSchema/testApiExample\", name = \"text\"),\n              @ExampleObject(value = \"{name:hello}\", name = \"application/json\"),\n              @ExampleObject(value = \"{name:hello}\", name = \"json\")})\n          , description = \"success\"\n      )})\n  @RequestMapping(path = \"/testDefaultGetApiExample\")\n  public String testDefaultGetApiExample(@RequestParam String name, HttpServletRequest request) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestAnnotationsSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.http.HttpStatus;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;\nimport org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class TestAnnotationsSchema implements CategorizedTestCase {\n  private static final String microserviceName = \"springmvc\";\n\n  private static final RestTemplate templateUrlWithServiceName = new CseRestTemplate();\n\n  @Override\n  public void testAllTransport() throws Exception {\n    templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());\n    testRequiredBody(templateUrlWithServiceName, microserviceName);\n    testRegExpPath();\n  }\n\n  private void testRegExpPath() {\n    String prefix = \"cse://\" + microserviceName;\n    String result = templateUrlWithServiceName.getForObject(prefix + \"/annotations/testRegExpPath/a?name={name}\",\n        String.class, \"a\");\n    TestMgr.check(\"a\", result);\n    result = templateUrlWithServiceName.getForObject(prefix + \"/annotations/testRegExpPath/a/b?name={name}\",\n        String.class, \"ab\");\n    TestMgr.check(\"ab\", result);\n    result = templateUrlWithServiceName.getForObject(prefix + \"/annotations/testRegExpPath/a/b/c?name={name}\",\n        String.class, \"abc\");\n    TestMgr.check(\"abc\", result);\n  }\n\n  private static void testRequiredBody(RestTemplate template, String microserviceName) {\n    String prefix = \"cse://\" + microserviceName;\n    Person user = new Person();\n\n    TestMgr.check(\"No user data found\",\n        template.postForObject(prefix + \"/annotations/saysomething?prefix={prefix}\",\n            user,\n            String.class,\n            \"ha\"));\n\n    user.setName(\"world\");\n    TestMgr.check(\"ha world\",\n        template.postForObject(prefix + \"/annotations/saysomething?prefix={prefix}\",\n            user,\n            String.class,\n            \"ha\"));\n\n    TestMgr.check(\"No user data found\",\n        template.postForObject(prefix + \"/annotations/saysomething?prefix={prefix}\",\n            null,\n            String.class,\n            \"ha\"));\n\n    TestMgr.check(\"No user name found\",\n        template.postForObject(prefix + \"/annotations/say\",\n            \"\",\n            String.class,\n            \"ha\"));\n    TestMgr.check(\"test\",\n        template.postForObject(prefix + \"/annotations/say\",\n            \"test\",\n            String.class,\n            \"ha\"));\n\n    try {\n      template.postForObject(prefix + \"/annotations/testRequiredBody\",\n          null,\n          String.class);\n      TestMgr.fail(\"should fail\");\n    } catch (InvocationException e) {\n      TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestBigNumberSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestBigNumberSchema implements CategorizedTestCase {\n  interface IBigNumberSchema {\n    BigInteger bigInteger(BigInteger intHeader, BigInteger intQuery, BigInteger intForm);\n\n    BigDecimal bigDecimal(BigDecimal decimalHeader, BigDecimal decimalQuery, BigDecimal decimalForm);\n  }\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"BigNumberSchema\")\n  private IBigNumberSchema schema;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testBigInteger();\n    testBigDecimal();\n  }\n\n  public void testBigInteger() {\n    BigInteger result = schema.bigInteger(BigInteger.valueOf(100L), BigInteger.valueOf(3000000000000000000L),\n        BigInteger.valueOf(200L));\n    TestMgr.check(\"3000000000000000300\", result.toString());\n  }\n\n  public void testBigDecimal() {\n    BigDecimal a = BigDecimal.valueOf(100.1D);\n    BigDecimal b = BigDecimal.valueOf(300000000000000000.1D);\n    BigDecimal c = BigDecimal.valueOf(200.1D);\n    BigDecimal expected = a.add(b).add(c);\n    BigDecimal result = schema.bigDecimal(a, b, c);\n    TestMgr.check(expected, result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestContentType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.provider.springmvc.reference.CseHttpEntity;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.core.MediaType;\n\npublic class TestContentType {\n\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  public void runAllTest() {\n    testGlobalSetting();\n    testApiOperation();\n    testRequestMapping();\n    testProtoBuffer();\n    testResponseTypeOverwrite();\n  }\n\n  private void testGlobalSetting() {\n    HttpHeaders requestHeaders = new HttpHeaders();\n    requestHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);\n    CseHttpEntity<String> requestEntity = new CseHttpEntity<>(\"from testGlobalSetting\", requestHeaders);\n    ResponseEntity<String> responseEntity = restTemplate\n        .exchange(\"cse://springmvc/contentTypeSpringmvc/testGlobalSetting\", HttpMethod.POST,\n            requestEntity, String.class);\n    TestMgr.check(\n        \"testGlobalSetting: name=[from testGlobalSetting], request content-type=[\" + MediaType.TEXT_PLAIN + \"]\",\n        responseEntity.getBody());\n    TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType()));\n  }\n\n  private void testApiOperation() {\n    HttpHeaders requestHeaders = new HttpHeaders();\n    requestHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);\n    CseHttpEntity<String> requestEntity = new CseHttpEntity<>(\"from testApiOperation\", requestHeaders);\n    ResponseEntity<String> responseEntity = restTemplate\n        .exchange(\"cse://springmvc/contentTypeSpringmvc/testApiOperation\", HttpMethod.POST,\n            requestEntity, String.class);\n    TestMgr.check(\n        \"testApiOperation: name=[from testApiOperation], request content-type=[\" + MediaType.TEXT_PLAIN + \"]\",\n        responseEntity.getBody());\n    TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType()));\n  }\n\n  private void testRequestMapping() {\n    HttpHeaders requestHeaders = new HttpHeaders();\n    requestHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);\n    CseHttpEntity<String> requestEntity = new CseHttpEntity<>(\"from testRequestMapping\", requestHeaders);\n    ResponseEntity<String> responseEntity = restTemplate\n        .exchange(\"cse://springmvc/contentTypeSpringmvc/testRequestMapping\", HttpMethod.POST,\n            requestEntity, String.class);\n    TestMgr.check(\n        \"testRequestMapping: name=[from testRequestMapping], request content-type=[\" + MediaType.APPLICATION_JSON + \"]\",\n        responseEntity.getBody());\n    TestMgr.check(MediaType.APPLICATION_JSON, extractContentType(responseEntity.getHeaders().getContentType()));\n  }\n\n\n  private void testProtoBuffer() {\n    HttpHeaders requestHeaders = new HttpHeaders();\n    requestHeaders.add(HttpHeaders.CONTENT_TYPE, SwaggerConst.PROTOBUF_TYPE);\n    User user = new User();\n    user.setIndex(100);\n    user.setName(\"hello\");\n    user.setNames(new String[] {\"a1\", \"a2\"});\n    CseHttpEntity<User> requestEntity = new CseHttpEntity<>(user, requestHeaders);\n    ResponseEntity<String> responseEntity = restTemplate\n        .exchange(\"cse://springmvc/contentTypeSpringmvc/testProtoBuffer\", HttpMethod.POST,\n            requestEntity, String.class);\n    TestMgr.check(\n        \"testRequestMapping: name=[hello:100:[a1, a2]], request content-type=[application/protobuf]\",\n        responseEntity.getBody());\n    TestMgr.check(SwaggerConst.PROTOBUF_TYPE, extractContentType(responseEntity.getHeaders().getContentType()));\n  }\n\n  private void testResponseTypeOverwrite() {\n    ResponseEntity<String> responseEntity = restTemplate\n        .getForEntity(\"cse://springmvc/contentTypeSpringmvcOverwrite/testResponseTypeOverwrite\", String.class);\n    TestMgr.check(\"testResponseTypeOverwrite: OK\", responseEntity.getBody());\n    TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType()));\n  }\n\n  private String extractContentType(org.springframework.http.MediaType mediaType) {\n    return mediaType.getType() + \"/\" + mediaType.getSubtype();\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestControllerImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.controller.Controller;\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.demo.controller.PersonAlias;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.http.client.common.HttpUtils;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestControllerImpl implements CategorizedTestCase {\n  private static final String SERVER = \"servicecomb://springmvc\";\n\n  @Autowired\n  Controller controller;\n\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testQueryParamSpecial();\n    testResponseModel();\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testControllerBodyModel();\n    testControllerHeaderModel();\n  }\n\n  private void testControllerHeaderModel() throws Exception {\n    // HTTP header只允许 ASCII 字符。\n    // 在Header参数中使用特殊字符，需要在发送请求前进行编码，在收到响应后进行解码，具体编码方式可以业务自行选择。\n    // 如果不进行编码，则可能会出现乱码（HTTP协议历史上只标准化了ASCII字符，其他字符集可能工作，可能不工作）。\n    String encodedResult = controller.sayHei(HttpUtils.encodeURLParam(\"中文HTTP Header\"));\n    TestMgr.check(\"hei 中文HTTP Header\", HttpUtils.decodeURLParam(encodedResult));\n\n    // 普通ASCII字符不需要编码\n    TestMgr.check(\"hei ~!@#$%^&*()_+-={}[]|\\\\:\\\";''<>?,./AL340\",\n        controller.sayHei(\"~!@#$%^&*()_+-={}[]|\\\\:\\\";''<>?,./AL340\"));\n  }\n\n  private void testControllerBodyModel() {\n    Person user = new Person();\n    user.setName(\"world\");\n    TestMgr.check(\"ha world\", controller.saySomething(\"ha\", user));\n  }\n\n  private void testResponseModel() {\n    Person person = restTemplate.getForObject(SERVER + \"/springmvc/controller/testResponseModel\", Person.class);\n    TestMgr.check(\"jack\", person.getName());\n\n    PersonAlias personAlias = restTemplate.getForObject(SERVER + \"/springmvc/controller/testResponseModel\",\n        PersonAlias.class);\n    TestMgr.check(\"jack\", personAlias.getName());\n  }\n\n  private void testQueryParamSpecial() {\n    // vert.x and servlet container have different query parameter implementations\n    if (LegacyPropertyFactory.getBooleanProperty(\"servicecomb.test.vert.transport\", true)) {\n\n      TestMgr.check(restTemplate.getForObject(\n          SERVER + \"/springmvc/controller/sayHello1?name=you;me\", String.class), \"Hello you,v\");\n    } else {\n      TestMgr.check(restTemplate.getForObject(\n          SERVER + \"/springmvc/controller/sayHello1?name=you;me\", String.class), \"Hello you;me,v\");\n    }\n    TestMgr.check(restTemplate.getForObject(\n        SERVER + \"/springmvc/controller/sayHello1?name={1}\",\n        String.class, \"you;me\"), \"Hello you;me,v\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDataTypesAnnotationsSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestDataTypesAnnotationsSchema implements CategorizedTestCase {\n  public interface DataTypesAnnotationsItf {\n    int[] testIntArrayQuery(int[] param);\n\n    Integer[] testIntegerArrayQuery(Integer[] param);\n  }\n\n  @RpcReference(schemaId = \"DataTypesAnnotationsSchema\", microserviceName = \"springmvc\")\n  private DataTypesAnnotationsItf client;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testIntArrayQuery();\n    testIntegerArrayQuery();\n  }\n\n  private void testIntArrayQuery() {\n    int[] request = new int[] {5, 11, 4};\n    int[] result = client.testIntArrayQuery(request);\n    TestMgr.check(request.length, result.length);\n    TestMgr.check(request[1], result[1]);\n  }\n\n  private void testIntegerArrayQuery() {\n    Integer[] request = new Integer[] {5, 11, 4};\n    Integer[] result = client.testIntegerArrayQuery(request);\n    TestMgr.check(request.length, result.length);\n    TestMgr.check(request[1], result[1]);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDateTimeSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.net.URI;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.util.Date;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.loadbalance.LoadBalanceFilter;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.CseHttpEntity;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\ninterface DateTimeSchemaInf {\n  Date getDate(Date date);\n\n  Date getDatePath(Date date);\n\n  Date postDate(Date date);\n\n  LocalDate getLocalDate(LocalDate date);\n\n  LocalDate getLocalDatePath(LocalDate date);\n\n  LocalDate postLocalDate(LocalDate date);\n\n  LocalDateTime getLocalDateTime(LocalDateTime date);\n\n  LocalDateTime getLocalDateTimePath(LocalDateTime date);\n\n  LocalDateTime postLocalDateTime(LocalDateTime date);\n}\n\ninterface DateTimeSchemaWithContextInf {\n  Date getDate(InvocationContext context, Date date);\n}\n\n@Component\npublic class TestDateTimeSchema implements CategorizedTestCase {\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"DateTimeSchema\")\n  private DateTimeSchemaInf dateTimeSchemaInf;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"DateTimeSchema\")\n  private DateTimeSchemaWithContextInf dateTimeSchemaWithContextInf;\n\n  private DiscoveryTree discoveryTree;\n\n  private SCBEngine scbEngine;\n\n  @Autowired\n  public void setScbEngine(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryTree = new DiscoveryTree(discoveryManager);\n    discoveryTree.setDiscoveryFilters(List.of(new CustomEndpointDiscoveryFilter()));\n  }\n\n  public TestDateTimeSchema() {\n\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testDateTimeSchema();\n    testDateTimeSchemaMulticast();\n    testDateTimeSchemaMulticastRestTemplate();\n  }\n\n  private void testDateTimeSchema() {\n    Date date = new Date();\n    TestMgr.check(date.getTime(), dateTimeSchemaInf.getDate(date).getTime());\n    TestMgr.check(date.getTime(), dateTimeSchemaInf.getDatePath(date).getTime());\n    TestMgr.check(date.getTime(), dateTimeSchemaInf.postDate(date).getTime());\n\n    LocalDate localDate = LocalDate.of(2020, 2, 1);\n    TestMgr.check(localDate.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")),\n        dateTimeSchemaInf.getLocalDate(localDate).format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")));\n    TestMgr.check(localDate.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")),\n        dateTimeSchemaInf.getLocalDatePath(localDate).format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")));\n    TestMgr.check(localDate.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")),\n        dateTimeSchemaInf.postLocalDate(localDate).format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")));\n\n    LocalDateTime localDateTime = LocalDateTime.of(2020, 2, 1, 23, 23, 30, 333);\n    TestMgr.check(localDateTime.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS\")),\n        dateTimeSchemaInf.getLocalDateTime(localDateTime)\n            .format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS\")));\n    TestMgr.check(localDateTime.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS\")),\n        dateTimeSchemaInf.getLocalDateTimePath(localDateTime)\n            .format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS\")));\n    TestMgr.check(localDateTime.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS\")),\n        dateTimeSchemaInf.postLocalDateTime(localDateTime)\n            .format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd'T'HH:mm:ss.SSS\")));\n  }\n\n  private void testDateTimeSchemaMulticast() throws Exception {\n    DiscoveryContext context = new DiscoveryContext();\n    VersionedCache serversVersionedCache = discoveryTree.discovery(context, \"springmvctest\", \"springmvc\");\n    List<String> endpoints = serversVersionedCache.data();\n\n    for (String endpoint : endpoints) {\n      InvocationContext invocationContext = new InvocationContext();\n      invocationContext.addLocalContext(LoadBalanceFilter.SERVICECOMB_SERVER_ENDPOINT, endpoint);\n      Date date = new Date();\n      TestMgr.check(date.getTime(), dateTimeSchemaWithContextInf.getDate(invocationContext, date).getTime());\n\n      invocationContext = new InvocationContext();\n      invocationContext.addLocalContext(LoadBalanceFilter.SERVICECOMB_SERVER_ENDPOINT, parseEndpoint(endpoint));\n      date = new Date();\n      TestMgr.check(date.getTime(), dateTimeSchemaWithContextInf.getDate(invocationContext, date).getTime());\n    }\n  }\n\n  private Endpoint parseEndpoint(String endpointUri) throws Exception {\n    URI formatUri = new URI(endpointUri);\n    Transport transport = scbEngine.getTransportManager().findTransport(formatUri.getScheme());\n    return new Endpoint(transport, endpointUri);\n  }\n\n  private void testDateTimeSchemaMulticastRestTemplate() throws Exception {\n    DiscoveryContext context = new DiscoveryContext();\n    VersionedCache serversVersionedCache = discoveryTree.discovery(context, \"springmvctest\", \"springmvc\");\n    List<String> endpoints = serversVersionedCache.data();\n\n    RestOperations restTemplate = RestTemplateBuilder.create();\n\n    for (String endpoint : endpoints) {\n      CseHttpEntity<?> entity = new CseHttpEntity<>(null);\n      InvocationContext invocationContext = new InvocationContext();\n      invocationContext.addLocalContext(LoadBalanceFilter.SERVICECOMB_SERVER_ENDPOINT, endpoint);\n      entity.setContext(invocationContext);\n\n      Date date = new Date();\n      String dateValue = RestObjectMapperFactory.getRestObjectMapper().convertToString(date);\n      TestMgr.check(date.getTime(),\n          restTemplate\n              .exchange(\"cse://springmvc/dateTime/getDate?date={1}\", HttpMethod.GET,\n                  entity, Date.class, dateValue).getBody().getTime());\n\n      entity = new CseHttpEntity<>(null);\n      invocationContext = new InvocationContext();\n      invocationContext.addLocalContext(LoadBalanceFilter.SERVICECOMB_SERVER_ENDPOINT, parseEndpoint(endpoint));\n      entity.setContext(invocationContext);\n\n      date = new Date();\n      dateValue = RestObjectMapperFactory.getRestObjectMapper().convertToString(date);\n      TestMgr.check(date.getTime(),\n          restTemplate\n              .exchange(\"cse://springmvc/dateTime/getDate?date={1}\", HttpMethod.GET,\n                  entity, Date.class, dateValue).getBody().getTime());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownloadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.net.URI;\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class TestDownloadSchema implements CategorizedTestCase {\n  @Autowired\n  DiscoveryManager discoveryManager;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testDownloadFileAndDeleted();\n    testDownloadFileAndDeletedCN();\n    testDownloadFileNotDeleted();\n    testDownloadFileWithNull();\n    testSetContentTypeByResponseEntity();\n    testResponseOKException();\n  }\n\n  private void testResponseOKException() {\n    List<? extends DiscoveryInstance> instances =\n        discoveryManager.findServiceInstances(\"springmvctest\", \"springmvc\");\n    String endpoint = instances.get(0).getEndpoints().stream()\n        .filter(item -> item.startsWith(\"rest\")).findFirst().get();\n    URI endpointItem = URI.create(endpoint);\n    RestTemplate template = new RestTemplate();\n\n    // This is for compatible usage. For best practise, any status code\n    // should have only one type of response.\n    ResponseEntity<ResponseOKData> resultFail = template.getForEntity(\n        \"http://\" + endpointItem.getHost() + \":\" + endpointItem.getPort()\n            + \"/api/download/testResponseOKExceptionBean?exception=true\", ResponseOKData.class);\n    TestMgr.check(200, resultFail.getStatusCode().value());\n    TestMgr.check(\"code-005\", resultFail.getBody().getErrorCode());\n    TestMgr.check(\"error-005\", resultFail.getBody().getErrorMessage());\n    ResponseEntity<Boolean> resultOK = template.getForEntity(\n        \"http://\" + endpointItem.getHost() + \":\" + endpointItem.getPort()\n            + \"/api/download/testResponseOKExceptionBean?exception=false\", boolean.class);\n    TestMgr.check(true, resultOK.getBody());\n\n    resultFail = template.getForEntity(\n        \"http://\" + endpointItem.getHost() + \":\" + endpointItem.getPort()\n            + \"/api/download/testResponseOKExceptionDownload?exception=true&content=ddd&contentType=plain/text\",\n        ResponseOKData.class);\n    TestMgr.check(200, resultFail.getStatusCode().value());\n    TestMgr.check(\"code-005\", resultFail.getBody().getErrorCode());\n    TestMgr.check(\"error-005\", resultFail.getBody().getErrorMessage());\n\n    ResponseEntity<String> resultPartOK = template.getForEntity(\n        \"http://\" + endpointItem.getHost() + \":\" + endpointItem.getPort()\n            + \"/api/download/testResponseOKExceptionDownload?exception=false&content=ddd&contentType=plain/text\",\n        String.class);\n    TestMgr.check(200, resultPartOK.getStatusCode().value());\n    TestMgr.check(\"ddd\", resultPartOK.getBody());\n  }\n\n  private void testDownloadFileAndDeleted() throws Exception {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    ReadStreamPart readStreamPart = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/deleteAfterFinished?content=hello\", ReadStreamPart.class);\n    String hello = readStreamPart.saveAsString().get();\n    TestMgr.check(hello, \"hello\");\n\n    boolean exists = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/assertLastFileDeleted\", boolean.class);\n    TestMgr.check(exists, false);\n  }\n\n  private void testDownloadFileAndDeletedCN() throws Exception {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    ReadStreamPart readStreamPart = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/deleteAfterFinished?content={1}&fileName={2}\",\n            ReadStreamPart.class, \"hello\", \"中文\");\n    String hello = readStreamPart.saveAsString().get();\n    TestMgr.check(hello, \"hello\");\n\n    boolean exists = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/assertLastFileDeleted\", boolean.class);\n    TestMgr.check(exists, false);\n  }\n\n  private void testDownloadFileWithNull() throws Exception {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    ReadStreamPart readStreamPart = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/partIsNull?content=test\", ReadStreamPart.class);\n    String result = readStreamPart.saveAsString().get();\n    TestMgr.check(result, \"test\");\n\n    readStreamPart = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/partIsNull?content=\", ReadStreamPart.class);\n    result = readStreamPart.saveAsString().get();\n    TestMgr.check(result, \"\");\n  }\n\n  private void testDownloadFileNotDeleted() throws Exception {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    ReadStreamPart readStreamPart = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/notDeleteAfterFinished?content=hello\", ReadStreamPart.class);\n    String hello = readStreamPart.saveAsString().get();\n    TestMgr.check(hello, \"hello\");\n\n    boolean exists = restTemplate\n        .getForObject(\"servicecomb://springmvc/download/assertLastFileDeleted\", boolean.class);\n    TestMgr.check(exists, true);\n  }\n\n  private void testSetContentTypeByResponseEntity() throws Exception {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    ResponseEntity<ReadStreamPart> responseEntity = restTemplate\n        .getForEntity(\n            \"servicecomb://springmvc/download/setContentTypeByResponseEntity?content=hello&contentType=customType\",\n            ReadStreamPart.class);\n    String hello = responseEntity.getBody().saveAsString().get();\n    TestMgr.check(responseEntity.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections.singletonList(\"customType\"));\n    TestMgr.check(hello, \"hello\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestFactoryBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.springmvc.client.factory.ServiceBean;\nimport org.springframework.beans.BeansException;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestFactoryBean implements CategorizedTestCase, ApplicationContextAware {\n  ApplicationContext applicationContext;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    ServiceBean serviceBean = (ServiceBean) this.applicationContext.getBean(\"ServiceFactoryBean\");\n    TestMgr.check(\"a-3\", serviceBean.getName());\n  }\n\n  @Override\n  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n    this.applicationContext = applicationContext;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestGeneric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.demo.Generic;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.web.client.RestOperations;\n\npublic class TestGeneric {\n  private CodeFirstSpringmvcIntf intf;\n\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private String prefix = \"cse://springmvc/codeFirstSpringmvc\";\n\n  public TestGeneric() {\n    intf = Invoker.createProxy(\"springmvc\", \"codeFirst\", CodeFirstSpringmvcIntf.class);\n  }\n\n  public void runRest() {\n    testHolderUser_rest();\n    testGenericUser_rest();\n    testGenericGenericUser_rest();\n    testGenericLong_rest();\n    testGenericDate_rest();\n    testGenericEnum_rest();\n  }\n\n  public void runHighway() {\n  }\n\n  public void runAllTransport() {\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testGenericEnum_rest() {\n    Generic<HttpStatus> generic = new Generic<>();\n    generic.value = HttpStatus.OK;\n    Generic<HttpStatus> result = intf.testGenericEnum(generic);\n    TestMgr.check(HttpStatus.OK, result.value);\n    TestMgr.check(HttpStatus.class, result.value.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/genericEnum\", generic, Generic.class);\n    TestMgr.check(HttpStatus.OK, result.value);\n    TestMgr.check(HttpStatus.class, result.value.getClass());\n  }\n\n  @SuppressWarnings({\"unchecked\", \"deprecation\"})\n  private void testGenericDate_rest() {\n    Generic<Date> generic = new Generic<>();\n    generic.value = new Date(1001);\n    Generic<Date> result = intf.testGenericDate(generic);\n    TestMgr.check(\"1970-01-01T00:00:01.001Z\",\n        com.fasterxml.jackson.databind.util.ISO8601Utils.format(result.value, true));\n    TestMgr.check(Date.class, result.value.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/genericDate\", generic, Generic.class);\n    TestMgr.check(\"1970-01-01T00:00:01.001Z\",\n        com.fasterxml.jackson.databind.util.ISO8601Utils.format(result.value, true));\n    TestMgr.check(Date.class, result.value.getClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testGenericLong_rest() {\n    Generic<Long> generic = new Generic<>();\n    generic.value = 100L;\n    Generic<Long> result = intf.testGenericLong(generic);\n    TestMgr.check(100, result.value);\n    TestMgr.check(Long.class, result.value.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/genericLong\", generic, Generic.class);\n    TestMgr.check(100, result.value);\n    TestMgr.check(Long.class, result.value.getClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testGenericGenericUser_rest() {\n    Generic<Generic<User>> generic = new Generic<>();\n    generic.value = new Generic<>();\n    generic.value.value = new User();\n    Generic<Generic<User>> result = intf.testGenericGenericUser(generic);\n    TestMgr.check(\"{\\\"name\\\":\\\"nameA\\\",\\\"age\\\":100,\\\"index\\\":0,\\\"names\\\":null}\", result.value.value.jsonString());\n\n    result = restTemplate.postForObject(prefix + \"/genericGenericUser\", generic, Generic.class);\n    TestMgr.check(\"{\\\"name\\\":\\\"nameA\\\",\\\"age\\\":100,\\\"index\\\":0,\\\"names\\\":null}\", result.value.value.jsonString());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testGenericUser_rest() {\n    Generic<User> generic = new Generic<>();\n    generic.value = new User();\n    Generic<User> result = intf.testGenericUser(generic);\n    TestMgr.check(\"{\\\"name\\\":\\\"nameA\\\",\\\"age\\\":100,\\\"index\\\":0,\\\"names\\\":null}\", result.value.jsonString());\n\n    result = restTemplate.postForObject(prefix + \"/genericUser\", generic, Generic.class);\n    TestMgr.check(\"{\\\"name\\\":\\\"nameA\\\",\\\"age\\\":100,\\\"index\\\":0,\\\"names\\\":null}\", result.value.jsonString());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testHolderUser_rest() {\n    Holder<User> holder = new Holder<>(new User());\n    Holder<User> result = intf.testHolderUser(holder);\n    TestMgr.check(\"{\\\"name\\\":\\\"nameA\\\",\\\"age\\\":100,\\\"index\\\":0,\\\"names\\\":null}\", result.value.jsonString());\n\n    result = restTemplate.postForObject(prefix + \"/holderUser\", holder, Holder.class);\n    TestMgr.check(\"{\\\"name\\\":\\\"nameA\\\",\\\"age\\\":100,\\\"index\\\":0,\\\"names\\\":null}\", result.value.jsonString());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestInvokeWhenServerNotReady.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.CommonSchemaInterface;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestInvokeWhenServerNotReady {\n  @RpcReference(schemaId = \"SpringMVCCommonSchemaInterface\", microserviceName = \"springmvc\")\n  private CommonSchemaInterface client;\n\n  // only invoke RPC before system is up, these setup is for testing calls before system ready\n  public TestInvokeWhenServerNotReady() {\n    startRestTemplateCall();\n    startRpcCall();\n    startInvokerUtilsCall();\n  }\n\n  private void startRestTemplateCall() {\n    new Thread(() -> {\n      for (int i = 0; i < 100; i++) {\n        try {\n          RestOperations template = RestTemplateBuilder.create();\n          template.getForObject(\"servicecomb://springmvc/upload/isServerStartUpSuccess\", Boolean.class);\n        } catch (Throwable e) {\n          // ignore\n        }\n      }\n    }).start();\n  }\n\n  private void startRpcCall() {\n    new Thread(() -> {\n      for (int i = 0; i < 100; i++) {\n        try {\n          InvocationContext context = new InvocationContext();\n          client.testInvocationTimeout(context, 1001, \"customized\");\n        } catch (Throwable e) {\n          // ignore\n        }\n      }\n    }).start();\n  }\n\n  private void startInvokerUtilsCall() {\n    new Thread(() -> {\n      for (int i = 0; i < 100; i++) {\n        try {\n          Map<String, Object> args = new HashMap<>();\n          args.put(\"timeout\", 1);\n          args.put(\"name\", \"customized\");\n          InvokerUtils\n              .syncInvoke(\"springmvc\", \"SpringMVCCommonSchemaInterface\", \"testInvocationTimeout\", args, String.class);\n        } catch (Throwable e) {\n          // ignore\n        }\n      }\n    }).start();\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestManagementEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.solution.basic.integration.ManagementEndpoint;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestManagementEndpoint implements CategorizedTestCase {\n  private static final String CONTENT_SCHEMA = \"\"\"\n      openapi: 3.0.1\n      info:\n        title: swagger definition for org.apache.servicecomb.demo.springmvc.server.SchemeInterfaceSpringmvc\n        version: 1.0.0\n      servers:\n      - url: /springmvc/schemaInterface\n      paths:\n        /add:\n          get:\n            operationId: add\n            parameters:\n            - name: a\n              in: query\n              required: true\n              schema:\n                minimum: 1\n                type: integer\n                format: int32\n            - name: b\n              in: query\n              required: true\n              schema:\n                minimum: 1\n                type: integer\n                format: int32\n            responses:\n              \"200\":\n                description: response of 200\n                content:\n                  application/json:\n                    schema:\n                      type: integer\n                      format: int32\n        /nonTailingSlash:\n          get:\n            operationId: nonTailingSlash\n            parameters:\n            - name: a\n              in: query\n              required: true\n              schema:\n                minimum: 1\n                type: integer\n                format: int32\n            - name: b\n              in: query\n              required: true\n              schema:\n                minimum: 1\n                type: integer\n                format: int32\n            responses:\n              \"200\":\n                description: response of 200\n                content:\n                  application/json:\n                    schema:\n                      type: string\n        /tailingSlash/:\n          get:\n            operationId: tailingSlash\n            parameters:\n            - name: a\n              in: query\n              required: true\n              schema:\n                minimum: 1\n                type: integer\n                format: int32\n            - name: b\n              in: query\n              required: true\n              schema:\n                minimum: 1\n                type: integer\n                format: int32\n            responses:\n              \"200\":\n                description: response of 200\n                content:\n                  application/json:\n                    schema:\n                      type: string\n      components: {}\n      \"\"\";\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"SchemeInterfaceSpringmvc\")\n  private SchemeInterfaceSpringmvc schemeInterfaceSpringmvc;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = ManagementEndpoint.NAME)\n  private ManagementEndpoint managementEndpoint;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testSchemeInterfaceSpringmvcContentCorrect();\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testSchemeInterfaceSpringmvcPathSlashCorrect();\n    testSchemeInterfaceSpringmvcPathNonSlashCorrect();\n  }\n\n  private void testSchemeInterfaceSpringmvcPathSlashCorrect() {\n    String result = schemeInterfaceSpringmvc.tailingSlash(3, 5);\n    TestMgr.check(\"/api/springmvc/schemaInterface/tailingSlash/;\" +\n        \"/api/springmvc/schemaInterface/tailingSlash/;\" +\n        \"/api/springmvc/schemaInterface/tailingSlash/;\" +\n        \"-2\", result);\n  }\n\n  private void testSchemeInterfaceSpringmvcPathNonSlashCorrect() {\n    String result = schemeInterfaceSpringmvc.nonTailingSlash(3, 5);\n    TestMgr.check(\"/api/springmvc/schemaInterface/nonTailingSlash;\" +\n        \"/api/springmvc/schemaInterface/nonTailingSlash;\" +\n        \"/api/springmvc/schemaInterface/nonTailingSlash;\" +\n        \"-2\", result);\n  }\n\n  private void testSchemeInterfaceSpringmvcContentCorrect() {\n    Map<String, String> contents = managementEndpoint.schemaContents();\n    TestMgr.check(CONTENT_SCHEMA, contents.get(\"SchemeInterfaceSpringmvc\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestMaxHttpUrlLength.java",
    "content": "/*\n * Copyright 2012 The Netty Project\n *\n * The Netty Project licenses this file to you under the Apache License,\n * version 2.0 (the \"License\"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at:\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations\n * under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport static jakarta.ws.rs.core.Response.Status.REQUEST_URI_TOO_LONG;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\nimport com.google.common.base.Strings;\n\n@Component\npublic class TestMaxHttpUrlLength implements CategorizedTestCase {\n  @Override\n  public void testRestTransport() throws Exception {\n    if (LegacyPropertyFactory.getBooleanProperty(\"servicecomb.test.vert.transport\", true)) {\n      testUrlNotLongerThan4096();\n    }\n  }\n\n  private void testUrlNotLongerThan4096() {\n    RestOperations restTemplate = RestTemplateBuilder.create();\n    // \\r doesn't count for url length Since netty 4.1.88.Final See https://github.com/netty/netty/pull/12321\n    String q = Strings.repeat(\"q\",\n        4096 + 1 - \"GET /api/springmvc/controller/sayhi?name=\".length() - \" HTTP/1.1\\r\".length());\n    TestMgr.check(\"hi \" + q + \" [\" + q + \"]\",\n        restTemplate.getForObject(\"cse://springmvc/springmvc/controller/sayhi?name=\" + q,\n            String.class));\n\n    q = Strings.repeat(\"q\", 4096 + 2 - \"GET /api/springmvc/controller/sayhi?name=\".length() - \" HTTP/1.1\\r\".length());\n    try {\n      restTemplate.getForObject(\"cse://springmvc/springmvc/controller/sayhi?name=\" + q,\n          String.class);\n      TestMgr.check(true, false);\n    } catch (InvocationException e) {\n      TestMgr.check(REQUEST_URI_TOO_LONG.getStatusCode(), e.getStatusCode());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.demo.EmptyObject;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.web.client.RestOperations;\n\npublic class TestObject {\n  private CodeFirstSpringmvcIntf intf;\n\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private String prefix = \"cse://springmvc/codeFirstSpringmvc\";\n\n  public TestObject() {\n    intf = Invoker.createProxy(\"springmvc\", \"codeFirst\", CodeFirstSpringmvcIntf.class);\n  }\n\n  public void runRest() {\n\n  }\n\n  public void runHighway() {\n\n  }\n\n  public void runAllTransport() {\n    testObject();\n    testMapObject();\n    testEmptyObject();\n    testListObject();\n    testHolderObject();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testHolderObject() {\n    Holder<Object> holder = new Holder<>(\"v\");\n    Holder<Object> result = intf.testHolderObject(holder);\n    TestMgr.check(\"v\", result.value);\n\n    result = restTemplate.postForObject(prefix + \"/holderObject\", holder, Holder.class);\n    TestMgr.check(\"v\", result.value);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testListObject() {\n    List<Object> list = Collections.singletonList(\"v\");\n    List<Object> result = intf.testListObject(list);\n    TestMgr.check(\"[v]\", result);\n    TestMgr.check(ArrayList.class, result.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/listObject\", list, List.class);\n    TestMgr.check(\"[v]\", result);\n    TestMgr.check(ArrayList.class, result.getClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testMapObject() {\n    Map<String, Object> map = Collections.singletonMap(\"k\", \"v\");\n    Map<String, Object> result = intf.testMapObject(map);\n    TestMgr.check(\"{k=v}\", result);\n    // This is a behavior change in 2.0.0, before 2.0.0 runtime type of RAW is HashMap\n    TestMgr.check(LinkedHashMap.class, result.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/mapObject\", map, Map.class);\n    TestMgr.check(\"{k=v}\", result);\n    TestMgr.check(LinkedHashMap.class, result.getClass());\n  }\n\n  private void testEmptyObject() {\n    EmptyObject result = intf.testEmpty(new EmptyObject());\n    TestMgr.check(EmptyObject.class, result.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/emptyObject\", new EmptyObject(), EmptyObject.class);\n    TestMgr.check(EmptyObject.class, result.getClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testObject() {\n    // int\n    Object result = intf.testObject(1);\n    TestMgr.check(1, result);\n    TestMgr.check(Integer.class, result.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/object\", 1, Integer.class);\n    TestMgr.check(1, result);\n    TestMgr.check(Integer.class, result.getClass());\n\n    // string\n    result = intf.testObject(\"str\");\n    TestMgr.check(\"str\", result);\n    TestMgr.check(String.class, result.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/object\", \"str\", String.class);\n    TestMgr.check(\"str\", result);\n    TestMgr.check(String.class, result.getClass());\n\n    // emptyObject\n    result = intf.testObject(new EmptyObject());\n    // result may not be an empty map in highway\n    //    TestMgr.check(\"{}\", result);\n    TestMgr.check(true, Map.class.isAssignableFrom(result.getClass()));\n\n    result = restTemplate.postForObject(prefix + \"/object\", new EmptyObject(), EmptyObject.class);\n    TestMgr.check(EmptyObject.class, result.getClass());\n    result = restTemplate.postForObject(prefix + \"/object\", new EmptyObject(), EmptyObject.class);\n    TestMgr.check(EmptyObject.class, result.getClass());\n\n    // map\n    Map<String, String> map = Collections.singletonMap(\"k\", \"v\");\n    result = intf.testObject(map);\n    TestMgr.check(\"{k=v}\", result);\n    TestMgr.check(true, Map.class.isAssignableFrom(result.getClass()));\n\n    result = restTemplate.postForObject(prefix + \"/object\", map, Map.class);\n    TestMgr.check(\"{k=v}\", result);\n    TestMgr.check(true, Map.class.isAssignableFrom(result.getClass()));\n\n    // list\n    List<String> list = Collections.singletonList(\"v\");\n    result = intf.testObject(list);\n    TestMgr.check(\"[v]\", result);\n    TestMgr.check(true, List.class.isAssignableFrom(result.getClass()));\n\n    result = restTemplate.postForObject(prefix + \"/object\", list, List.class);\n    TestMgr.check(\"[v]\", result);\n    TestMgr.check(true, List.class.isAssignableFrom(result.getClass()));\n\n    // generic\n    // This test case for HIGHWAY is not stable.\n    // When proto schema contains Holder message, the result type is Map. Or the result is Holder(using json).\n    Holder<String> holder = new Holder<>(\"v\");\n    result = intf.testObject(holder);\n    TestMgr.check(\"v\", ((Map<String, String>) result).get(\"value\"));\n    TestMgr.check(LinkedHashMap.class, result.getClass());\n\n    result = restTemplate.postForObject(prefix + \"/object\", holder, Holder.class);\n    TestMgr.check(\"v\", ((Map<String, String>) result).get(\"value\"));\n    TestMgr.check(LinkedHashMap.class, result.getClass());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Date;\nimport java.util.Objects;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.compute.GenericParam;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.ResponseEntity;\n\nimport com.fasterxml.jackson.databind.exc.InvalidFormatException;\n\npublic class TestResponse {\n  private CodeFirstSpringmvcIntf intf;\n\n  private Environment environment;\n\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  public TestResponse() {\n    intf = Invoker.createProxy(\"springmvc\", \"codeFirst\", CodeFirstSpringmvcIntf.class);\n  }\n\n  public void runRest() {\n    checkQueryGenericObject();\n    checkQueryGenericString();\n    testDelay();\n    testAbort();\n    testDecodeResponseError();\n    checkQueryObject();\n    testCseResponse();\n    testResponseEntity();\n    testCseResponseCorrect();\n  }\n\n  public void runHighway() {\n  }\n\n  public void runAllTransport() {\n    testvoidResponse();\n    testVoidResponse();\n    checkQueryObject();\n    testCseResponse();\n    testResponseEntity();\n  }\n\n  private void testCseResponse() {\n    String srcName = BootStrapProperties.readServiceName(environment);\n    Response cseResponse = intf.cseResponse();\n    TestMgr.check(\"User [name=nameA, age=100, index=0]\", cseResponse.getResult());\n    TestMgr.check(\"h1v \" + srcName, cseResponse.getHeader(\"h1\"));\n    TestMgr.check(\"h2v \" + srcName, cseResponse.getHeader(\"h2\"));\n    TestMgr.check(cseResponse.getStatusCode(), 202);\n  }\n\n  private void testCseResponseCorrect() {\n    String srcName = BootStrapProperties.readServiceName(environment);\n    Response cseResponse = intf.cseResponseCorrect();\n    TestMgr.check(\"User [name=nameA, age=100, index=0]\", cseResponse.getResult());\n    TestMgr.check(\"h1v \" + srcName, cseResponse.getHeader(\"h1\"));\n    TestMgr.check(\"h2v \" + srcName, cseResponse.getHeader(\"h2\"));\n    TestMgr.check(cseResponse.getStatusCode(), 202);\n  }\n\n  private void testResponseEntity() {\n    Date date = new Date();\n\n    String srcName = BootStrapProperties.readServiceName(environment);\n\n    ResponseEntity<Date> responseEntity = intf.responseEntity(date);\n    TestMgr.check(date, responseEntity.getBody());\n    TestMgr.check(\"h1v \" + srcName, responseEntity.getHeaders().getFirst(\"h1\"));\n    TestMgr.check(\"h2v \" + srcName, responseEntity.getHeaders().getFirst(\"h2\"));\n\n    TestMgr.check(202, responseEntity.getStatusCode().value());\n  }\n\n  private void testvoidResponse() {\n    intf.testvoidInRPC();\n  }\n\n  private void testVoidResponse() {\n    intf.testVoidInRPC();\n  }\n\n  private void checkQueryObject() {\n    String result = intf.checkQueryObject(\"name1\", \"otherName2\", new Person(\"bodyName\"));\n    TestMgr.check(\"invocationContext_is_null=false,person=name1,otherName=otherName2,name=name1,requestBody=bodyName\",\n        result);\n  }\n\n  private void checkQueryGenericObject() {\n    GenericParam<Person> requestBody = new GenericParam<>();\n    requestBody.num(1).str(\"str1\").setData(new Person(\"bodyPerson\"));\n    String result = intf.checkQueryGenericObject(requestBody, \"str2\", 2);\n    TestMgr.check(\n        \"str=str2,generic=GenericParamWithJsonIgnore{str='str2', num=2, data=null},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}\",\n        result);\n  }\n\n  private void checkQueryGenericString() {\n    GenericParam<Person> requestBody = new GenericParam<>();\n    requestBody.num(1).str(\"str1\").setData(new Person(\"bodyPerson\"));\n    String result = intf.checkQueryGenericString(\"str2\", requestBody, 2, \"dataTest\", \"strInSubclass\", 33);\n    TestMgr.check(\n        \"str=str2,generic=GenericParamExtended{strExtended='strInSubclass', intExtended=33, super=\"\n            + \"GenericParam{str='str2', num=2, data=dataTest}},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}\",\n        result);\n  }\n\n  private void testDelay() {\n    StringBuilder result = new StringBuilder();\n    for (int i = 0; i < 4; ++i) {\n      result.append(intf.testDelay()).append(\"|\");\n    }\n    TestMgr.check(\"OK|OK|OK|OK|\", result.toString());\n  }\n\n  private void testAbort() {\n    AtomicInteger count = new AtomicInteger(0);\n    for (int i = 0; i < 100; ++i) {\n      try {\n        String response = intf.testAbort();\n        count.incrementAndGet();\n        TestMgr.check(\"OK\", response);\n      } catch (InvocationException e) {\n        TestMgr.check(421, e.getStatusCode());\n        TestMgr.check(\"aborted by fault inject\", ((CommonExceptionData) e.getErrorData()).getMessage());\n      }\n    }\n    // 50% percent fail\n    TestMgr.check(true, count.get() >= 30 && count.get() <= 70);\n  }\n\n  private void testDecodeResponseError() {\n    InvocationException exception = null;\n    try {\n      intf.testDecodeResponseError();\n    } catch (InvocationException e) {\n      // 1. InvocationException: wrapper exception\n      exception = e;\n    }\n    Objects.requireNonNull(exception);\n    // 2. CseException: bizKeeper exception\n    Throwable cause = exception.getCause();\n    TestMgr.check(InvalidFormatException.class, cause.getClass());\n    TestMgr.check(\n        ((InvalidFormatException) cause).getMessage().contains(\"Cannot deserialize value of type `java.util.Date`\"),\n        true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.compute.GenericParam;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.util.Assert;\nimport org.springframework.web.client.RestOperations;\n\npublic class TestRestTemplate {\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  public void runAllTest() {\n    testvoidResponse();\n    testVoidResponse();\n    checkAllVoidTestResult();\n    checkQueryObject();\n  }\n\n  public void runRest() {\n    checkQueryGenericObject();\n    checkQueryGenericString();\n    checkQueryObject();\n  }\n\n  private void testvoidResponse() {\n    ResponseEntity<Void> resultEntity = restTemplate\n        .getForEntity(\"cse://springmvc/codeFirstSpringmvc/testvoidInRestTemplate\", void.class);\n    Assert.isTrue(200 == resultEntity.getStatusCode().value(), \"void return type invocation failed\");\n  }\n\n  private void testVoidResponse() {\n    ResponseEntity<Void> resultEntity = restTemplate\n        .getForEntity(\"cse://springmvc/codeFirstSpringmvc/testVoidInRestTemplate\", Void.class);\n    Assert.isTrue(200 == resultEntity.getStatusCode().value(), \"Void return type invocation failed\");\n    resultEntity = restTemplate\n        .getForEntity(\"servicecomb://springmvc/codeFirstSpringmvc/testVoidInRestTemplate\", Void.class);\n    Assert.isTrue(200 == resultEntity.getStatusCode().value(), \"Void return type invocation failed\");\n    resultEntity = restTemplate\n        .getForEntity(\"servicecomb://springmvc/codeFirstSpringmvc/testDefaultGetApiExample\", Void.class);\n    Assert.isTrue(200 == resultEntity.getStatusCode().value(), \"Void return type invocation failed\");\n  }\n\n  private void checkAllVoidTestResult() {\n    ResponseEntity<Boolean> resultEntity = restTemplate\n        .getForEntity(\"cse://springmvc/codeFirstSpringmvc/checkVoidResult\", boolean.class);\n    Assert.isTrue(resultEntity.getBody(), \"not all void test is passed\");\n    restTemplate\n        .getForEntity(\"servicecomb://springmvc/codeFirstSpringmvc/checkVoidResult\", boolean.class);\n    Assert.isTrue(resultEntity.getBody(), \"not all void test is passed\");\n  }\n\n  private void checkQueryObject() {\n    ResponseEntity<String> responseEntity = restTemplate\n        .postForEntity(\"cse://springmvc/codeFirstSpringmvc/checkQueryObject?name={1}&otherName={2}\",\n            new Person(\"bodyName\"), String.class, \"name1\", \"otherName2\");\n    TestMgr.check(\"invocationContext_is_null=false,person=name1,otherName=otherName2,name=name1,requestBody=bodyName\",\n        responseEntity.getBody());\n  }\n\n  private void checkQueryGenericObject() {\n    GenericParam<Person> requestBody = new GenericParam<>();\n    requestBody.num(1).str(\"str1\").setData(new Person(\"bodyPerson\"));\n    HttpEntity<GenericParam<Person>> requestEntity = new HttpEntity<>(requestBody);\n    ResponseEntity<String> responseEntity = restTemplate\n        .exchange(\"cse://springmvc/codeFirstSpringmvc/checkQueryGenericObject?str={1}&num={2}\",\n            HttpMethod.PUT, requestEntity, String.class, \"str2\", 2);\n    TestMgr.check(\n        \"str=str2,generic=GenericParamWithJsonIgnore{str='str2', num=2, data=null},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}\",\n        responseEntity.getBody());\n  }\n\n  private void checkQueryGenericString() {\n    GenericParam<Person> requestBody = new GenericParam<>();\n    requestBody.num(1).str(\"str1\").setData(new Person(\"bodyPerson\"));\n    ResponseEntity<String> responseEntity = restTemplate.exchange(\n        \"cse://springmvc/codeFirstSpringmvc/checkQueryGenericString?str={1}&num={2}&data={3}&strExtended={4}&intExtended={5}\",\n        HttpMethod.PUT, new HttpEntity<>(requestBody), String.class, \"str2\", 2, \"dataTest\",\n        \"strInSubclass\", 33);\n    TestMgr.check(\n        \"str=str2,generic=GenericParamExtended{strExtended='strInSubclass', intExtended=33, super=\"\n            + \"GenericParam{str='str2', num=2, data=dataTest}},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}\",\n        responseEntity.getBody());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRetrySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestRetrySchema implements CategorizedTestCase {\n  interface RetrySchemaInf {\n    boolean successWhenRetry();\n\n    CompletableFuture<Boolean> successWhenRetryAsync();\n  }\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"RetrySchema\")\n  private RetrySchemaInf retrySchemaInf;\n\n  RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private static final String SERVER = \"servicecomb://springmvc\";\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testRetryGovernanceRestTemplate();\n    testRetryGovernanceRpc();\n  }\n\n  private void testRetryGovernanceRpc() throws Exception {\n    TestMgr.check(retrySchemaInf.successWhenRetry(), true);\n    TestMgr.check(retrySchemaInf.successWhenRetry(), true);\n\n    TestMgr.check(retrySchemaInf.successWhenRetryAsync().get(), true);\n    TestMgr.check(retrySchemaInf.successWhenRetryAsync().get(), true);\n  }\n\n  private void testRetryGovernanceRestTemplate() {\n    TestMgr.check(restTemplate.getForObject(SERVER + \"/retry/governance/successWhenRetry\", boolean.class), true);\n    TestMgr.check(restTemplate.getForObject(SERVER + \"/retry/governance/successWhenRetry\", boolean.class), true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestSchemeInterfaceSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestSchemeInterfaceSpringmvc implements CategorizedTestCase {\n  @RpcReference(schemaId = \"SchemeInterfaceSpringmvc\", microserviceName = \"springmvc\")\n  private SchemeInterfaceSpringmvc springmvc;\n\n  public void testAllTransport() throws Exception {\n    TestMgr.check(3, springmvc.add(1, 2));\n\n    try {\n      springmvc.reduce(1, 3);\n      TestMgr.failed(\"should throw exception\", new Exception());\n    } catch (InvocationException e) {\n      TestMgr.check(\n          \"Consumer method org.apache.servicecomb.demo.springmvc.client.SchemeInterfaceSpringmvc:reduce not \"\n              + \"exist in contract, microserviceName=springmvc, \"\n              + \"schemaId=SchemeInterfaceSpringmvc.\",\n          ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestSpringMVCCommonSchemaInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.invocation.timeout.ProcessingTimeStrategy;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.CommonSchemaInterface;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestSpringMVCCommonSchemaInterface implements CategorizedTestCase {\n  @RpcReference(schemaId = \"SpringMVCCommonSchemaInterface\", microserviceName = \"springmvc\")\n  private CommonSchemaInterface client;\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testInvocationTimeoutInServer();\n    testInvocationTimeoutInServerUserCheck();\n    testInvocationAlreadyTimeoutInClient();\n    testInvocationTimeoutInClientWait();\n  }\n\n  private void testInvocationTimeoutInClientWait() {\n    try {\n      long begin = System.currentTimeMillis();\n      String result = client.testInvocationTimeoutInClientWait(1000, \"hello\");\n      System.out.println(\"test code from testInvocationTimeoutInClientWait: \"\n          + (System.currentTimeMillis() - begin) + \":\" + result);\n      TestMgr.fail(\"should timeout\");\n    } catch (InvocationException e) {\n      TestMgr.check(408, e.getStatusCode());\n      TestMgr.check(\"Invocation Timeout.\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n\n  private void testInvocationTimeoutInServerUserCheck() {\n    try {\n      InvocationContext context = new InvocationContext();\n      client.testInvocationTimeout(context, 1001, \"customized\");\n      TestMgr.fail(\"should timeout\");\n    } catch (InvocationException e) {\n      TestMgr.check(408, e.getStatusCode());\n      TestMgr.check(\"Invocation Timeout.\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n\n  private void testInvocationAlreadyTimeoutInClient() {\n    try {\n      InvocationContext context = new InvocationContext();\n      context.addLocalContext(ProcessingTimeStrategy.CHAIN_START_TIME, System.nanoTime());\n      context.addLocalContext(ProcessingTimeStrategy.CHAIN_PROCESSING, TimeUnit.SECONDS.toNanos(2));\n\n      long begin = System.currentTimeMillis();\n      String result = client.testInvocationTimeout(context, 10, \"hello\");\n      System.out.println(\"testInvocationAlreadyTimeoutInClient from invocation timeout: \"\n          + (System.currentTimeMillis() - begin) + \":\" + result);\n      TestMgr.fail(\"should timeout\");\n    } catch (InvocationException e) {\n      TestMgr.check(408, e.getStatusCode());\n      TestMgr.check(\"Invocation Timeout.\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n\n  private void testInvocationTimeoutInServer() {\n    try {\n      client.testInvocationTimeout(1001, \"hello\");\n      TestMgr.fail(\"should timeout\");\n    } catch (InvocationException e) {\n      TestMgr.check(408, e.getStatusCode());\n      TestMgr.check(\"Invocation Timeout.\", ((CommonExceptionData) e.getErrorData()).getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestThirdPartyRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestThirdPartyRegistration implements BootListener, CategorizedTestCase {\n  @Autowired\n  private ThirdPartyService thirdPartyService;\n\n  @Override\n  public void onAfterRegistry(BootEvent event) {\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    Date date = new Date();\n    ResponseEntity<Date> responseEntity = thirdPartyService.responseEntity(date);\n    TestMgr.check(date, responseEntity.getBody());\n    // Third party invocation will pass cse-context to the target too\n    TestMgr.check(\"h1v null\", responseEntity.getHeaders().getFirst(\"h1\"));\n    TestMgr.check(\"h2v null\", responseEntity.getHeaders().getFirst(\"h2\"));\n\n    TestMgr.check(202, responseEntity.getStatusCode().value());\n  }\n\n  @Override\n  public String getMicroserviceName() {\n    return \"testServiceName\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestThirdSvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Date;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.springmvc.client.ThirdSvc.ThirdSvcClient;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestThirdSvc implements CategorizedTestCase {\n  private ThirdSvcClient client;\n\n  @Autowired\n  public void setThirdSvcClient(ThirdSvcClient client) {\n    this.client = client;\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testResponseEntity();\n\n    testDifferentParameterName();\n  }\n\n  private void testDifferentParameterName() {\n    String result = client.getAuthorization(\"test\", \"param\", \"auth\");\n    TestMgr.check(\"testparamauth\", result);\n  }\n\n  private void testResponseEntity() {\n    Date date = new Date();\n    ResponseEntity<Date> responseEntity = client.responseEntity(date);\n    TestMgr.check(date, responseEntity.getBody());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestTransportSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class TestTransportSchema implements CategorizedTestCase {\n  interface TransportClient {\n    boolean restTransport();\n\n    boolean highwayTransport();\n  }\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"TransportSchema\")\n  private TransportClient transportClient;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testTransportSchema();\n  }\n\n  @Override\n  public void testHighwayTransport() throws Exception {\n    testTransportSchema();\n  }\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testTransportSchema();\n  }\n\n  private void testTransportSchema() {\n    TestMgr.check(true, transportClient.highwayTransport());\n    TestMgr.check(true, transportClient.restTransport());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestUploadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.core.io.FileSystemResource;\nimport org.springframework.core.io.Resource;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.LinkedMultiValueMap;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class TestUploadSchema implements CategorizedTestCase {\n\n  interface FileUploadMultiInf {\n    String fileUploadMultiRpc(List<Resource> files);\n  }\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"UploadSchema\")\n  private FileUploadMultiInf fileUploadMultiInf;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testServerStartupSuccess();\n    testUploadMultiBigFiles();\n    testFileUploadMultiRpc();\n    testUploadFileAndAttribute();\n    testUploadFileAndAttributeCN();\n    testUploadFileRequestPartAttribute();\n    testUploadFileRequestPartAttributeList();\n  }\n\n  private void testServerStartupSuccess() {\n    RestOperations template = RestTemplateBuilder.create();\n    boolean result = template.getForObject(\"servicecomb://springmvc/upload/isServerStartUpSuccess\", Boolean.class);\n    TestMgr.check(result, true);\n  }\n\n  private void testUploadMultiBigFiles() throws Exception {\n    final int fileNum = 5;\n    List<File> files = new ArrayList<>(fileNum);\n\n    String fileName = UUID.randomUUID().toString();\n    for (int i = 0; i < fileNum; i++) {\n      File tempFile = new File(\"random-client-\" + fileName + i);\n      files.add(tempFile);\n      FileOutputStream fo = new FileOutputStream(tempFile);\n      byte[] data = new byte[1024 * 1024 * 10];\n      Arrays.fill(data, (byte) 33);\n      IOUtils.write(data, fo);\n      fo.close();\n    }\n\n    RestOperations template = RestTemplateBuilder.create();\n\n    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();\n    for (int i = 0; i < fileNum; i++) {\n      map.add(\"files\", new FileSystemResource(files.get(i)));\n    }\n\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);\n    HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(map, headers);\n\n    String result = template.postForObject(\"servicecomb://springmvc/upload/fileUpload\", entity, String.class);\n    TestMgr.check(result, \"success\");\n\n    files.forEach(File::delete);\n  }\n\n  private void testFileUploadMultiRpc() throws IOException {\n    File file1 = File.createTempFile(\"file1\", \".txt\");\n    File file2 = File.createTempFile(\"file2\", \".txt\");\n    List<Resource> files = new ArrayList<>();\n    files.add(new FileSystemResource(file1));\n    files.add(new FileSystemResource(file2));\n    String result = fileUploadMultiInf.fileUploadMultiRpc(files);\n    TestMgr.check(result, \"fileUploadMulti success, and fileNum is 2\");\n  }\n\n  private void testUploadFileAndAttribute() throws Exception {\n    RestOperations template = RestTemplateBuilder.create();\n    Map<String, Object> map = new HashMap<>();\n    String message = \"hi\";\n    File file = File.createTempFile(\"file\", \".txt\");\n    FileUtils.writeStringToFile(file, \"test\", StandardCharsets.UTF_8, false);\n\n    map.put(\"file\", new FileSystemResource(file));\n    map.put(\"attribute\", message);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);\n    String result = template.postForObject(\"servicecomb://springmvc/upload/uploadFileAndAttribute\",\n        new HttpEntity<>(map, headers), String.class);\n    TestMgr.check(\"hi test\", result);\n  }\n\n  private void testUploadFileAndAttributeCN() throws Exception {\n    RestOperations template = RestTemplateBuilder.create();\n    Map<String, Object> map = new HashMap<>();\n    String message = \"hi\";\n    File file = File.createTempFile(\"中文名称\", \".txt\");\n    FileUtils.writeStringToFile(file, \"test\", StandardCharsets.UTF_8, false);\n\n    map.put(\"file\", new FileSystemResource(file));\n    map.put(\"attribute\", message);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);\n    String result = template.postForObject(\"servicecomb://springmvc/upload/uploadFileAndAttribute\",\n        new HttpEntity<>(map, headers), String.class);\n    TestMgr.check(\"hi test\", result);\n  }\n\n\n  private void testUploadFileRequestPartAttribute() throws Exception {\n    RestOperations template = RestTemplateBuilder.create();\n    Map<String, Object> map = new HashMap<>();\n    String message = \"hi\";\n    File file = File.createTempFile(\"file\", \".txt\");\n    FileUtils.writeStringToFile(file, \"test\", StandardCharsets.UTF_8, false);\n\n    map.put(\"file\", new FileSystemResource(file));\n    map.put(\"attribute\", message);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);\n    String result = template.postForObject(\"servicecomb://springmvc/upload/uploadFileRequestPartAttribute\",\n        new HttpEntity<>(map, headers), String.class);\n    TestMgr.check(\"hi test\", result);\n  }\n\n  private void testUploadFileRequestPartAttributeList() throws Exception {\n    RestOperations template = RestTemplateBuilder.create();\n    MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();\n    String message1 = \"msg1\";\n    String message2 = \"msg2\";\n    File file1 = File.createTempFile(\"file1\", \".txt\");\n    FileUtils.writeStringToFile(file1, \"test1\", StandardCharsets.UTF_8, false);\n    File file2 = File.createTempFile(\"file2\", \".txt\");\n    FileUtils.writeStringToFile(file2, \"test2\", StandardCharsets.UTF_8, false);\n\n    map.add(\"files\", new FileSystemResource(file1));\n    map.add(\"files\", new FileSystemResource(file2));\n    map.add(\"attributes\", message1);\n    map.add(\"attributes\", message2);\n    HttpHeaders headers = new HttpHeaders();\n    headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);\n    String result = template.postForObject(\"servicecomb://springmvc/upload/uploadFileRequestPartAttributeList\",\n        new HttpEntity<>(map, headers), String.class);\n    TestMgr.check(\"test1test2msg1msg2\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestWeakSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.demo.model.SpecialNameModel;\nimport org.apache.servicecomb.demo.server.GenericsModel;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\n\n/*\nThis is the provider definition:\n\n<code>\n  @GetMapping(path = \"/diffNames\")\n  @ApiOperation(value = \"differentName\", nickname = \"differentName\")\n  public int diffNames(@RequestParam(\"x\") int a, @RequestParam(\"y\") int b)\n</code>\n\nand the swagger is:\n\n<code>\n  paths:\n    /diffNames:\n      get:\n        summary: \"differentName\"\n        operationId: \"differentName\"\n        parameters:\n        - name: \"x\"\n          in: \"query\"\n          required: true\n          type: \"integer\"\n          format: \"int32\"\n        - name: \"y\"\n          in: \"query\"\n          required: true\n          type: \"integer\"\n          format: \"int32\"\n        responses:\n          \"200\":\n            description: \"response of 200\"\n            schema:\n              type: \"integer\"\n              format: \"int32\"\n</code>\n\nIn consumer, you can define any prototype that matches generated swagger of provider.\n */\n\ninterface DiffNames {\n  int differentName(int x, int y);\n}\n\ninterface DiffNames2 {\n  int differentName(int y, int x);\n}\n\ninterface Generics {\n  List<List<String>> genericParams(int code, List<List<String>> names);\n}\n\ninterface GenericsModelInf {\n  GenericsModel genericParamsModel(int code, GenericsModel model);\n}\n\ninterface SpecialNameModelInf {\n  SpecialNameModel specialNameModel(int code, SpecialNameModel model);\n}\n\n@Component\npublic class TestWeakSpringmvc implements CategorizedTestCase {\n  @Value(\"${servicecomb.service.application}\")\n  private String applicationName;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"weakSpringmvc\")\n  private DiffNames diffNames;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"weakSpringmvc\")\n  private DiffNames2 diffNames2;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"weakSpringmvc\")\n  private Generics generics;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"weakSpringmvc\")\n  private GenericsModelInf genericsModelInf;\n\n  @RpcReference(microserviceName = \"springmvc\", schemaId = \"weakSpringmvc\")\n  private SpecialNameModelInf specialNameModelInf;\n\n  @RpcReference(microserviceName = \"${servicecomb.service.application}:springmvc\", schemaId = \"weakSpringmvc\")\n  private SpecialNameModelInf specialNameModelInfWithAppId;\n\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  @Override\n  public void testAllTransport() throws Exception {\n    testDiffName();\n\n    testGenerics();\n\n    testGenericsModel();\n\n    testSpecialNameModel();\n  }\n\n  private void testSpecialNameModel() {\n    SpecialNameModel model = new SpecialNameModel();\n    model.setaIntName(30);\n    SpecialNameModel result = specialNameModelInf.specialNameModel(0, model);\n    TestMgr.check(30, result.getaIntName());\n    result = specialNameModelInfWithAppId.specialNameModel(0, model);\n    TestMgr.check(30, result.getaIntName());\n  }\n\n  private void testGenericsModel() throws JsonProcessingException {\n    GenericsModel model = new GenericsModel();\n    model.setName(\"model\");\n    List<List<String>> namesList = new ArrayList<>();\n    List<String> names = new ArrayList<>();\n    names.add(\"hello\");\n    namesList.add(names);\n    model.setNameList(namesList);\n    List<List<List<Object>>> objectLists = new ArrayList<>();\n    List<List<Object>> objectList = new ArrayList<>();\n    List<Object> objects = new ArrayList<>();\n    objects.add(\"object\");\n    objectList.add(objects);\n    objectLists.add(objectList);\n    model.setObjectLists(objectLists);\n    GenericsModel result = genericsModelInf.genericParamsModel(100, model);\n    TestMgr.check(JsonUtils.writeValueAsString(model), JsonUtils.writeValueAsString(result));\n  }\n\n  private void testGenerics() {\n    List<List<String>> namesList = new ArrayList<>();\n    List<String> names = new ArrayList<>();\n    names.add(\"hello\");\n    namesList.add(names);\n    List<List<String>> nameListResult = generics.genericParams(100, namesList);\n    TestMgr.check(1, nameListResult.size());\n    TestMgr.check(1, nameListResult.get(0).size());\n    TestMgr.check(\"hello\", nameListResult.get(0).get(0));\n  }\n\n  private void testDiffName() {\n    TestMgr.check(7, diffNames.differentName(2, 3));\n    TestMgr.check(8, diffNames2.differentName(2, 3));\n    TestMgr.check(7, restTemplate.getForObject(\"cse://springmvc/weakSpringmvc/diffNames?x=2&y=3\", Integer.class));\n    TestMgr.check(7, restTemplate\n        .getForObject(\"cse://\" + applicationName + \":springmvc/weakSpringmvc/diffNames?x=2&y=3\",\n            Integer.class));\n    Map<String, Object> args = new HashMap<>();\n    args.put(\"x\", 2);\n    args.put(\"y\", 3);\n    TestMgr.check(7, InvokerUtils.syncInvoke(\"springmvc\",\n        \"weakSpringmvc\", \"differentName\", args, Integer.class));\n    TestMgr.check(7, InvokerUtils.syncInvoke(applicationName + \":springmvc\",\n        \"weakSpringmvc\", \"differentName\", args, Integer.class));\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/ThirdPartyService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.Date;\n\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.RequestAttribute;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\n\n@RequestMapping(path = \"/codeFirstSpringmvc\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic interface ThirdPartyService {\n  @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = Date.class))\n      , description = \"\",\n      headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n          @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n  @RequestMapping(path = \"/responseEntity\", method = RequestMethod.POST)\n  ResponseEntity<Date> responseEntity(@RequestAttribute(\"date\") Date date);\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/ThirdSvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.client;\n\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\n\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestAttribute;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\n\n@Configuration\npublic class ThirdSvc {\n  @Autowired\n  Environment environment;\n\n  @RequestMapping(path = \"/codeFirstSpringmvc\")\n  public interface ThirdSvcClient {\n    @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = Date.class))\n        , description = \"\",\n        headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n            @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n    @RequestMapping(path = \"/responseEntity\", method = RequestMethod.POST)\n    ResponseEntity<Date> responseEntity(@RequestAttribute(\"date\") Date date);\n\n    @GetMapping(value = \"/getAuthorization\", produces = {\"application/json\"})\n    String getAuthorization(\n        @RequestHeader(value = \"test\") String test,\n        @RequestParam(value = \"param\") String param,\n        @RequestHeader(\"Authorization\") String authorization);\n  }\n\n  @Bean\n  public RegistryBean thirdRegistryBean() {\n    String endpoint;\n    if (environment.getProperty(\"servicecomb.test.vert.transport\", boolean.class, true)) {\n      endpoint = \"rest://localhost:8080?sslEnabled=false&urlPrefix=%2Fapi\";\n    } else {\n      endpoint = \"rest://localhost:8080?sslEnabled=false\";\n    }\n\n    return new RegistryBean().addSchemaInterface(\"schema-1\", ThirdSvcClient.class)\n        .setAppId(\"springmvctest\")\n        .setServiceName(\"3rd-svc\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(new Instance().setEndpoints(List.of(endpoint)))));\n  }\n\n  @Bean\n  public ThirdSvcClient thirdSvcClient() {\n    return Invoker.createProxy(\"3rd-svc\", \"schema-1\", ThirdSvcClient.class);\n  }\n\n  @Bean\n  public RegistryBean thirdPartyServiceRegistryBean() {\n    List<String> endpoints = new ArrayList<>();\n    if (environment.getProperty(\"servicecomb.test.vert.transport\", boolean.class, true)) {\n      endpoints.add(\"rest://localhost:8080?sslEnabled=false&urlPrefix=%2Fapi\");\n    } else {\n      endpoints.add(\"rest://localhost:8080?sslEnabled=false\");\n    }\n\n    return new RegistryBean().addSchemaInterface(\"testServiceName\", ThirdPartyService.class)\n        .setAppId(\"springmvctest\")\n        .setServiceName(\"testServiceName\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(new Instance().setEndpoints(endpoints))));\n  }\n\n  @Bean\n  public ThirdPartyService thirdPartyService() {\n    return Invoker.createProxy(\"testServiceName\", \"testServiceName\", ThirdPartyService.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/factory/ServiceBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client.factory;\n\npublic class ServiceBean {\n  private final String name;\n\n  public ServiceBean(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/factory/ServiceFactoryBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client.factory;\n\nimport org.springframework.beans.factory.FactoryBean;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\n@Component(\"ServiceFactoryBean\")\npublic class ServiceFactoryBean implements FactoryBean<ServiceBean> {\n\n  ServiceWithReference serviceWithReference;\n\n  @Autowired\n  public ServiceFactoryBean(ServiceWithReference serviceWithReference) {\n    this.serviceWithReference = serviceWithReference;\n  }\n\n  @Override\n  public ServiceBean getObject() throws Exception {\n    return new ServiceBean(serviceWithReference.test(\"a\"));\n  }\n\n  @Override\n  public Class<?> getObjectType() {\n    return ServiceBean.class;\n  }\n\n  @Override\n  public boolean isSingleton() {\n    return true;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/factory/ServiceWithReference.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client.factory;\n\npublic interface ServiceWithReference {\n  String test(String name);\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/factory/ServiceWithReferenceImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.client.factory;\n\nimport org.apache.servicecomb.demo.springmvc.client.SchemeInterfaceSpringmvc;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ServiceWithReferenceImpl implements ServiceWithReference {\n  @RpcReference(schemaId = \"SchemeInterfaceSpringmvc\", microserviceName = \"springmvc\")\n  private SchemeInterfaceSpringmvc springmvc;\n\n  @Override\n  public String test(String name) {\n    return name + \"-\" + springmvc.add(1, 2);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/decoderesponse/DecodeTestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.decoderesponse;\n\nimport java.util.Date;\n\npublic class DecodeTestResponse {\n  private Date content;\n\n  public Date getContent() {\n    return content;\n  }\n\n  public void setContent(Date content) {\n    this.content = content;\n  }\n\n  @Override\n  public String toString() {\n    final StringBuilder sb = new StringBuilder(\"DecodeTestResponse{\");\n    sb.append(\"content=\").append(content);\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/resources/META-INF/spring/springmvc.client.bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:context=\"http://www.springframework.org/schema/context\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xmlns:cse=\"http://www.huawei.com/schema/paas/cse/rpc\"\n  xsi:schemaLocation=\"\n\t\thttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n\t\thttp://www.huawei.com/schema/paas/cse/rpc classpath:META-INF/spring/spring-paas-cse-rpc.xsd\n\t\thttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\">\n\n  <context:component-scan base-package=\"org.apache.servicecomb.demo.springmvc.client\"/>\n  <cse:rpc-reference id=\"controller\" microservice-name=\"springmvc\"\n    schema-id=\"controller\" interface=\"org.apache.servicecomb.demo.controller.Controller\"></cse:rpc-reference>\n</beans>\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/resources/SpringMVCSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n################################################################################\n################################################################################\n################################################################################\n################################################################################\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.springmvc.client.SpringMVCSchema\n  version: 1.0.0\nservers:\n- url: /springMvcSchema\npaths:\n  /testApiExample:\n    post:\n      operationId: testApiExample\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n        required: true\n        x-name: name\n      responses:\n        \"200\":\n          description: success\n          headers: {}\n          content:\n            application/json:\n              schema:\n                type: string\n                description: \"\"\n                nullable: false\n                example: wget http://localhost/springMvcSchema/testApiExample\n  /testDefaultGetApiExample:\n    get:\n      operationId: testDefaultGetApiExample\n      parameters:\n      - name: name\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: success\n          headers: {}\n          content:\n            application/json:\n              schema:\n                type: string\n                description: \"\"\n                nullable: false\n                example: \"\"\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: springmvctest\n    name: springmvcClient\n    version: 0.0.1\n  registry:\n    sc:\n      address: http://127.0.0.1:30100\n      autodiscovery: true\n      healthCheckIntervalInSeconds: 3\n      pollIntervalInMillis: 90000\n      watch: true\n\n  rest:\n    client:\n      connection:\n        compression: true\n  references:\n    version-rule: 0+\n  request:\n    clientRequestHeaderFilterEnabled:\n      # Do not copy cse-context to target for microservice(testServiceName)\n      testServiceName: true\n  invocation:\n    timeout:\n      check:\n        enabled: true\n        strategy: processing-time\n    springmvc:\n      SpringMVCCommonSchemaInterface:\n        testInvocationTimeoutInClientWait:\n          timeout: 300\n  tracing:\n    enabled: true\n    samplingRate: 0.5\n  loadbalance:\n    userDefinedEndpoint.enabled: true\n    strategy:\n      name: WeightedResponse\n    filter.status.enabled: false\n  fallbackpolicy:\n    Consumer:\n      springmvc:\n        codeFirst:\n          fallbackFromCache:\n            policy: fromCache\n          fallbackReturnNull:\n            policy: returnNull\n          fallbackThrowException:\n            policy: throwException\n          fallbackForce:\n            policy: mycustom\n  fallback:\n    Consumer:\n      springmvc:\n        codeFirst:\n          fallbackForce:\n            force: true\n  datacenter:\n    name: myDC\n    region: my-Region\n    availableZone: my-Zone\n\n  faultInjection:\n    enabled: true\n\n  governance:\n    Consumer:\n      springmvc:\n        schemas:\n          codeFirst:\n            operations:\n              testDelay:\n                policy:\n                  fault:\n                    protocols:\n                      rest:\n                        delay:\n                          fixedDelay: 10\n                          percent: 50\n              testAbort:\n                policy:\n                  fault:\n                    protocols:\n                      rest:\n                        abort:\n                          httpStatus: 421\n                          percent: 50\n\n  # test governance retry\n  matchGroup:\n    retry-governance: |\n      matches:\n        - apiPath:\n            prefix: \"/retry/governance/\"\n    retry-success: |\n      matches:\n        - apiPath:\n            prefix: \"/codeFirstSpringmvc/retrySuccess\"\n  retry:\n    retry-governance: |\n      maxAttempts: 2\n      retryOnResponseStatus: [500]\n    retry-success: |\n      maxAttempts: 2\n      retryOnResponseStatus: [503]\n\n#########SSL options\n# open jdk 8 now TLSv1.3 not available\n# ssl.protocols: TLSv1.3\n# ssl.ciphers: TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384\nssl.protocols: TLSv1.2\nssl.authPeer: true\nssl.checkCN.host: false\n\n#########certificates config\nssl.trustStore: trust.jks\nssl.trustStoreType: JKS\nssl.trustStoreValue: Changeme_123\nssl.keyStore: server.p12\nssl.keyStoreType: PKCS12\nssl.keyStoreValue: Changeme_123\nssl.crl: revoke.crl\nssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-client/src/test/java/org/apache/servicecomb/demo/springmvc/SpringMvcIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = SpringmvcClient.class)\npublic class SpringMvcIT {\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() {\n    SpringmvcClient.run();\n    Assertions.assertTrue(TestMgr.isSuccess());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-springmvc</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>springmvc-server</artifactId>\n  <name>Java Chassis::Demo::Spring MVC::Server</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-prometheus</artifactId>\n    </dependency>\n  </dependencies>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.springmvc.SpringmvcServer</demo.main>\n  </properties>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/SpringmvcServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class SpringmvcServer {\n  public static void main(String[] args) throws Exception {\n    new SpringApplicationBuilder(SpringmvcServer.class).web(WebApplicationType.NONE).run(args);\n\n    runTests();\n\n    TestMgr.summary();\n    if (!TestMgr.isSuccess()) {\n      System.exit(1);\n    }\n  }\n\n  private static void runTests() {\n    try {\n      CategorizedTestCaseRunner.runCategorizedTestCase(\"springmvc\");\n    } catch (Exception e) {\n      TestMgr.failed(\"runCategorizedTestCase failed\", e);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/decoderesponse/DecodeTestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.decoderesponse;\n\npublic class DecodeTestResponse {\n  private String content;\n\n  public String getContent() {\n    return content;\n  }\n\n  public void setContent(String content) {\n    this.content = content;\n  }\n\n  @Override\n  public String toString() {\n    final StringBuilder sb = new StringBuilder(\"DecodeTestResponse{\");\n    sb.append(\"content='\").append(content).append('\\'');\n    sb.append('}');\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/filter/ProviderTestFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.filter;\n\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ProviderTestFilter extends AbstractFilter implements ProviderFilter {\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 1800;\n  }\n\n  @Override\n  public String getName() {\n    return \"test-provider\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    invocation.addContext(\"k\", \"v\");\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/AnnotationsSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.Parameters;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"annotations\")\n@RequestMapping(path = \"/springmvc/annotations\", produces = MediaType.APPLICATION_JSON)\npublic class AnnotationsSchema {\n  @GetMapping(path = \"/add\")\n  public int add(@RequestParam(name = \"a\", defaultValue = \"10\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"10\") int b) {\n    return a + b;\n  }\n\n  @RequestMapping(path = \"/sayhei\", method = RequestMethod.GET)\n  public String sayHei(@RequestHeader(name = \"name\", defaultValue = \"test\") String name) {\n    return \"hei \" + name;\n  }\n\n  @GetMapping(path = \"/sayhi\")\n  @Parameters({\n      @Parameter(name = \"name\", in = ParameterIn.QUERY, schema = @Schema(type = \"string\", defaultValue = \"test\")),\n      @Parameter(name = \"age\", in = ParameterIn.QUERY, schema = @Schema(type = \"integer\", defaultValue = \"20\"))\n  })\n  public String sayHi(String name, int age) {\n    return \"hi \" + name + \" your age is : \" + age;\n  }\n\n  @RequestMapping(path = \"/saysomething\", method = RequestMethod.POST)\n  public String saySomething(String prefix, @RequestBody(required = false) Person user) {\n    if (user == null || user.getName() == null || user.getName().isEmpty()) {\n      return \"No user data found\";\n    }\n    return prefix + \" \" + user.getName();\n  }\n\n  @RequestMapping(path = \"/say\", method = RequestMethod.POST)\n  public String say(@RequestBody(required = false) String user) {\n    if (user == null || user.isEmpty()) {\n      return \"No user name found\";\n    }\n    return user;\n  }\n\n  @RequestMapping(path = \"/testRequiredBody\", method = RequestMethod.POST)\n  public String testRequiredBody(@RequestBody(required = true) Person user) {\n    if (user == null) {\n      return \"Should not happen\";\n    }\n    return user.getName();\n  }\n\n  @RequestMapping(path = \"/testRegExpPath/{path: .+}\", method = RequestMethod.GET)\n  public String testRegExpPath(@RequestParam(\"name\") String name) {\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/BigNumberSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestAttribute;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"BigNumberSchema\")\n@RequestMapping(\"/bigNumber\")\npublic class BigNumberSchema {\n  @PostMapping(path = \"/integer\", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)\n  public BigInteger bigInteger(@RequestHeader(\"intHeader\") BigInteger intHeader,\n      @RequestParam(\"intQuery\") BigInteger intQuery, @RequestAttribute(\"intForm\") BigInteger intForm) {\n    return intHeader.add(intQuery).add(intForm);\n  }\n\n  @PostMapping(path = \"/decimal\", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)\n  public BigDecimal bigDecimal(@RequestHeader(\"decimalHeader\") BigDecimal decimalHeader,\n      @RequestParam(\"decimalQuery\") BigDecimal decimalQuery, @RequestAttribute(\"decimalForm\") BigDecimal decimalForm) {\n    return decimalHeader.add(decimalQuery).add(decimalForm);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/BizkeeperTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"codeFirstBizkeeperTest\")\n@RequestMapping(path = \"/codeFirstBizkeeperTest\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class BizkeeperTest {\n  @GetMapping(path = \"/testTimeout\")\n  public String testTimeout(@RequestParam(\"name\") String name, @RequestParam(\"delaytime\") long delaytime) {\n    try {\n      Thread.sleep(delaytime);\n    } catch (InterruptedException e) {\n      e.printStackTrace();\n    }\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.demo.EmptyObject;\nimport org.apache.servicecomb.demo.Generic;\nimport org.apache.servicecomb.demo.compute.GenericParam;\nimport org.apache.servicecomb.demo.compute.GenericParamExtended;\nimport org.apache.servicecomb.demo.compute.GenericParamWithJsonIgnore;\nimport org.apache.servicecomb.demo.compute.Person;\nimport org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;\nimport org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.demo.springmvc.decoderesponse.DecodeTestResponse;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.metrics.core.MetricsBootListener;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.util.Assert;\nimport org.springframework.web.bind.annotation.CookieValue;\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestAttribute;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.bind.annotation.ResponseBody;\nimport org.springframework.web.client.RestTemplate;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.Parameters;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport io.vertx.core.json.JsonObject;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.Response.Status;\n\n@RestSchema(schemaId = \"codeFirst\")\n@RequestMapping(path = \"/codeFirstSpringmvc\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class CodeFirstSpringmvc {\n  private static final Logger LOGGER = LoggerFactory.getLogger(CodeFirstSpringmvc.class);\n\n  private AtomicInteger invocationCounter = new AtomicInteger(0);\n\n  private String _fileUpload(MultipartFile file1, Part file2) {\n    try (InputStream is1 = file1.getInputStream(); InputStream is2 = file2.getInputStream()) {\n      String content1 = IOUtils.toString(is1, StandardCharsets.UTF_8);\n      String content2 = IOUtils.toString(is2, StandardCharsets.UTF_8);\n      return String.format(\"%s:%s:%s\\n\"\n              + \"%s:%s:%s\",\n          file1.getOriginalFilename(),\n          file1.getContentType(),\n          content1,\n          file2.getSubmittedFileName(),\n          file2.getContentType(),\n          content2);\n    } catch (IOException e) {\n      throw new IllegalArgumentException(e);\n    }\n  }\n\n  @GetMapping(path = \"/retrySuccess\")\n  public int retrySuccess(@RequestParam(\"a\") int a, @RequestParam(\"b\") int b) {\n    if (invocationCounter.getAndIncrement() % 3 != 0) {\n      throw new InvocationException(Status.SERVICE_UNAVAILABLE, \"try again later.\");\n    }\n    return a + b;\n  }\n\n  @PostMapping(path = \"/upload1\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String fileUpload1(@RequestPart(name = \"file1\") MultipartFile file1) throws IOException {\n    try (InputStream is = file1.getInputStream()) {\n      return IOUtils.toString(is, StandardCharsets.UTF_8);\n    }\n  }\n\n  @PostMapping(path = \"/upload\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String fileUpload(@RequestPart(name = \"file1\") MultipartFile file1,\n      @RequestPart(name = \"someFile\") Part file2) {\n    return _fileUpload(file1, file2);\n  }\n\n  @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = Date.class))\n      , description = \"\",\n      headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n          @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n  @RequestMapping(path = \"/responseEntity\", method = RequestMethod.POST)\n  public ResponseEntity<Date> responseEntity(InvocationContext c1, @RequestAttribute(\"date\") Date date) {\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"h1\", \"h1v \" + c1.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    InvocationContext c2 = ContextUtils.getInvocationContext();\n    headers.add(\"h2\", \"h2v \" + c2.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    return new ResponseEntity<>(date, headers, HttpStatus.ACCEPTED);\n  }\n\n  @GetMapping(value = \"/getAuthorization\", produces = {\"application/json\"})\n  public String getAuthorization(\n      @RequestHeader(value = \"test\") String test,\n      @RequestParam(value = \"param\") String param,\n      @Parameter(description = \"Authorization header\", required = true, in = ParameterIn.HEADER,\n          name = \"Authorization\") @RequestHeader(\"Authorization\") String authorization) {\n    return test + param + authorization;\n  }\n\n  @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = Date.class))\n      , description = \"\",\n      headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n          @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n  @RequestMapping(path = \"/responseEntity\", method = RequestMethod.PATCH)\n  public ResponseEntity<Date> responseEntityPATCH(InvocationContext c1, @RequestAttribute(\"date\") Date date) {\n    return responseEntity(c1, date);\n  }\n\n  // This definition is not correct, response type is not\n  // same as the actual one. May be not support in future.\n  @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = User.class))\n      , description = \"\",\n      headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n          @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n  @RequestMapping(path = \"/cseResponse\", method = RequestMethod.GET)\n  public Response cseResponse(InvocationContext c1) {\n    Response response = Response.createSuccess(Status.ACCEPTED, new User());\n    response.addHeader(\"h1\", \"h1v \" + c1.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    InvocationContext c2 = ContextUtils.getInvocationContext();\n    response.addHeader(\"h2\", \"h2v \" + c2.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    return response;\n  }\n\n  // This definition is correct, but not supported by highway.\n  // highway do not support define code other than 200\n  @ApiResponse(responseCode = \"202\", content = @Content(schema = @Schema(implementation = User.class))\n      , description = \"\",\n      headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class)),\n          @Header(name = \"h2\", schema = @Schema(implementation = String.class))})\n  @RequestMapping(path = \"/cseResponseCorrect\", method = RequestMethod.GET)\n  public Response cseResponseCorrect(InvocationContext c1) {\n    Response response = Response.createSuccess(Status.ACCEPTED, new User());\n    response.addHeader(\"h1\", \"h1v \" + c1.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    InvocationContext c2 = ContextUtils.getInvocationContext();\n    response.addHeader(\"h2\", \"h2v \" + c2.getContext().get(CoreConst.SRC_MICROSERVICE));\n\n    return response;\n  }\n\n  @PostMapping(path = \"/testUserMap\")\n  public Map<String, User> testUserMap(@RequestBody Map<String, User> userMap) {\n    return userMap;\n  }\n\n  @RequestMapping(path = \"/textPlain\", method = RequestMethod.POST, consumes = MediaType.TEXT_PLAIN_VALUE)\n  public String textPlain(@RequestBody String body) {\n    return body;\n  }\n\n  @RequestMapping(path = \"/bytes\", method = RequestMethod.POST)\n  public byte[] bytes(@RequestBody byte[] input) {\n    input[0] = (byte) (input[0] + 1);\n    return input;\n  }\n\n  @RequestMapping(path = \"/addDate\", method = RequestMethod.POST)\n  public Date addDate(@RequestAttribute(\"date\") Date date, @QueryParam(\"seconds\") long seconds) {\n    return new Date(date.getTime() + seconds * 1000);\n  }\n\n  // this should be ignored as it's hidden\n  @Operation(summary = \"\", hidden = true, method = \"POST\")\n  public int add(@RequestParam(\"a\") int a) {\n    return a;\n  }\n\n  @RequestMapping(path = \"/add\", method = RequestMethod.POST)\n  public int add(@RequestAttribute(\"a\") int a, @RequestAttribute(\"b\") int b) {\n    return a + b;\n  }\n\n  @GetMapping(path = \"/reduce\")\n  @Parameters({@Parameter(name = \"a\", schema = @Schema(implementation = int.class), in = ParameterIn.QUERY)})\n  public int reduce(HttpServletRequest request, @CookieValue(name = \"b\") int b) {\n    int a = Integer.parseInt(request.getParameter(\"a\"));\n    return a - b;\n  }\n\n  @RequestMapping(path = \"/sayhello\", method = RequestMethod.POST)\n  public Person sayHello(@RequestBody Person user) {\n    user.setName(\"hello \" + user.getName());\n    return user;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @RequestMapping(path = \"/testrawjson\", method = RequestMethod.POST)\n  public String testRawJsonString(String jsonInput) {\n    Map<String, String> person;\n    try {\n      person = RestObjectMapperFactory.getRestObjectMapper()\n          .readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);\n    } catch (Exception e) {\n      e.printStackTrace();\n      return null;\n    }\n    return \"hello \" + person.get(\"name\");\n  }\n\n  @RequestMapping(path = \"/saysomething\", method = RequestMethod.POST)\n  public String saySomething(@RequestHeader(name = \"prefix\") String prefix, @RequestBody Person user) {\n    return prefix + \" \" + user.getName();\n  }\n\n  @PutMapping(path = \"/sayhi/{name}\")\n  public String sayHi(@PathVariable(name = \"name\") String name) {\n    ContextUtils.getInvocationContext().setStatus(202);\n    return name + \" sayhi\";\n  }\n\n  @RequestMapping(path = \"/sayhi/compressed/{name}/v2\", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)\n  public String sayHiForCompressed(@PathVariable(name = \"name\") String name) {\n    String bigText =\n        \"This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,\"\n            + \"This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,\"\n            + \"This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,\"\n            + \"This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,\"\n            + \"This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,\"\n            + \"This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text,This is a big text!\";\n    return name + \" sayhi compressed:\" + bigText;\n  }\n\n  @RequestMapping(path = \"/sayhi/{name}/v2\", method = RequestMethod.PUT)\n  public String sayHi2(@PathVariable(name = \"name\") String name) {\n    return name + \" sayhi 2\";\n  }\n\n  @RequestMapping(path = \"/istrue\", method = RequestMethod.GET)\n  public boolean isTrue() {\n    return true;\n  }\n\n  @DeleteMapping(path = \"/addstring\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String addString(@RequestParam(name = \"s\") List<String> s) {\n    StringBuilder result = new StringBuilder();\n    for (String x : s) {\n      result.append(x);\n    }\n    return result.toString();\n  }\n\n  // Using 490, 590 error code, the response type should be CommonExceptionData. Or we need\n  // complex ExceptionConverters to deal with exceptions thrown by Handlers, etc.\n  @RequestMapping(path = \"/fallback/returnnull/{name}\", method = RequestMethod.GET)\n  @ApiResponses(value = {@ApiResponse(responseCode = \"200\",\n      content = @Content(schema = @Schema(implementation = String.class)), description = \"xxx\"),\n      @ApiResponse(responseCode = \"490\", content = @Content(schema = @Schema(implementation = CommonExceptionData.class)), description = \"xxx\")})\n  public String fallbackReturnNull(@PathVariable(name = \"name\") String name) {\n    if (\"throwexception\".equals(name)) {\n      throw new InvocationException(490, \"490\", new CommonExceptionData(\"xxx\"));\n    }\n    return name;\n  }\n\n  @RequestMapping(path = \"/fallback/throwexception/{name}\", method = RequestMethod.GET)\n  @ApiResponses(value = {\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class))\n          , description = \"xxx\"),\n      @ApiResponse(responseCode = \"490\", content = @Content(schema = @Schema(implementation = CommonExceptionData.class))\n          , description = \"xxx\")})\n  public String fallbackThrowException(@PathVariable(name = \"name\") String name) {\n    if (\"throwexception\".equals(name)) {\n      throw new InvocationException(490, \"490\", new CommonExceptionData(\"xxx\"));\n    }\n    return name;\n  }\n\n  @RequestMapping(path = \"/fallback/fromcache/{name}\", method = RequestMethod.GET)\n  @ApiResponses(value = {\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class))\n          , description = \"xxx\"),\n      @ApiResponse(responseCode = \"490\", content = @Content(schema = @Schema(implementation = CommonExceptionData.class))\n          , description = \"xxx\")})\n  public String fallbackFromCache(@PathVariable(name = \"name\") String name) {\n    if (\"throwexception\".equals(name)) {\n      throw new InvocationException(490, \"490\", new CommonExceptionData(\"xxx\"));\n    }\n    return name;\n  }\n\n  @RequestMapping(path = \"/fallback/force/{name}\", method = RequestMethod.GET)\n  @ApiResponses(value = {\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class))\n          , description = \"xxx\"),\n      @ApiResponse(responseCode = \"490\", content = @Content(schema = @Schema(implementation = CommonExceptionData.class))\n          , description = \"xxx\")})\n  public String fallbackForce(@PathVariable(name = \"name\") String name) {\n    if (\"throwexception\".equals(name)) {\n      throw new InvocationException(490, \"490\", new CommonExceptionData(\"xxx\"));\n    }\n    return name;\n  }\n\n  public enum NameType {\n    abc,\n    def\n  }\n\n  @RequestMapping(path = \"/testenum/{name}\", method = RequestMethod.GET)\n  @ApiResponses(value = {\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class))\n          , description = \"xxx\"),\n      @ApiResponse(responseCode = \"490\", content = @Content(schema = @Schema(implementation = CommonExceptionData.class))\n          , description = \"xxx\")})\n  public String testEnum(@RequestParam(name = \"username\") String username,\n      @PathVariable(value = \"name\") NameType nameType) {\n    return nameType.toString();\n  }\n\n  @RequestMapping(method = RequestMethod.POST, value = \"/ignore\")\n  @ResponseBody\n  public OutputModelForTestIgnore testModelWithIgnoreField(@RequestBody InputModelForTestIgnore input) {\n    return new OutputModelForTestIgnore(\"output_id\", input.getInputId(), input.getContent(), input.getInputObject(),\n        input.getInputJsonObject(), input.getInputIgnoreInterface(),\n        new Person(\"outputSomeone\"), new JsonObject(\"{\\\"OutputJsonKey\\\" : \\\"OutputJsonValue\\\"}\"), () -> {\n    });\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @RequestMapping(method = RequestMethod.POST, value = \"/rawJsonAnnotation\")\n  @ResponseBody\n  public String testRawJsonAnnotation(@RawJsonRequestBody String jsonInput) {\n    Map<String, String> person;\n    try {\n      person = RestObjectMapperFactory.getRestObjectMapper()\n          .readValue(jsonInput.getBytes(StandardCharsets.UTF_8), Map.class);\n    } catch (Exception e) {\n      e.printStackTrace();\n      return null;\n    }\n    return \"hello \" + person.get(\"name\");\n  }\n\n  @PostMapping(path = \"/testform\")\n  @io.swagger.v3.oas.annotations.parameters.RequestBody(\n      content = {@Content(mediaType = SwaggerConst.FORM_MEDIA_TYPE,\n          schema = @Schema(name = \"form1\", implementation = String.class,\n              nullable = false, description = \"a required form param\")),\n          @Content(mediaType = SwaggerConst.FORM_MEDIA_TYPE,\n              schema = @Schema(name = \"form2\", implementation = String.class,\n                  nullable = true, description = \"an optional form param\"))})\n  public String testform(HttpServletRequest request) {\n    String form1 = request.getParameter(\"form1\");\n    String form2 = request.getParameter(\"form2\");\n    Assert.notNull(form1, \"from1 is null\");\n    return form1 + form2;\n  }\n\n  @Autowired\n  MetricsBootListener metricsBootListener;\n\n  //Only for Prometheus integration test\n  @RequestMapping(path = \"/prometheusForTest\", method = RequestMethod.GET)\n  public String prometheusForTest() {\n    // just for test, this makes client always can got latest metrics\n    metricsBootListener.getMetricsBootstrap().pollMeters();\n\n    RestTemplate defaultRestTemplate = new RestTemplate();\n    return defaultRestTemplate.getForObject(\"http://localhost:9696/metrics\", String.class);\n  }\n\n  @GetMapping(path = \"/traceId\")\n  public String getTraceId() {\n    return ContextUtils.getInvocationContext().getContext(CoreConst.TRACE_ID_NAME);\n  }\n\n  @PostMapping(path = \"/emptyObject\")\n  public EmptyObject testEmpty(@RequestBody EmptyObject input) {\n    return input;\n  }\n\n  @PostMapping(path = \"/object\")\n  public Object testObject(@RequestBody Object input) {\n    return input;\n  }\n\n  @PostMapping(path = \"/mapObject\")\n  public Map<String, Object> testMapObject(@RequestBody Map<String, Object> input) {\n    return input;\n  }\n\n  @PostMapping(path = \"/listObject\")\n  public List<Object> testListObject(@RequestBody List<Object> input) {\n    return input;\n  }\n\n  @PostMapping(path = \"/holderObject\")\n  public Holder<Object> testHolderObject(@RequestBody Holder<Object> input) {\n    return input;\n  }\n\n  @PostMapping(path = \"/holderUser\")\n  public Holder<User> testHolderUser(@RequestBody Holder<User> input) {\n    Assert.isInstanceOf(Holder.class, input);\n    Assert.isInstanceOf(User.class, input.value);\n    return input;\n  }\n\n  @PostMapping(path = \"/genericUser\")\n  public Generic<User> testGenericUser(@RequestBody Generic<User> input) {\n    Assert.isInstanceOf(Generic.class, input);\n    Assert.isInstanceOf(User.class, input.value);\n    return input;\n  }\n\n  @PostMapping(path = \"/genericLong\")\n  public Generic<Long> testGenericLong(@RequestBody Generic<Long> input) {\n    Assert.isInstanceOf(Generic.class, input);\n    Assert.isInstanceOf(Long.class, input.value);\n    return input;\n  }\n\n  @PostMapping(path = \"/genericDate\")\n  public Generic<Date> testGenericDate(@RequestBody Generic<Date> input) {\n    Assert.isInstanceOf(Generic.class, input);\n    Assert.isInstanceOf(Date.class, input.value);\n    System.out.println(input.value);\n    return input;\n  }\n\n  @PostMapping(path = \"/genericEnum\")\n  public Generic<HttpStatus> testGenericEnum(@RequestBody Generic<HttpStatus> input) {\n    Assert.isInstanceOf(Generic.class, input);\n    Assert.isInstanceOf(HttpStatus.class, input.value);\n    return input;\n  }\n\n  @PostMapping(path = \"/genericGenericUser\")\n  public Generic<Generic<User>> testGenericGenericUser(@RequestBody Generic<Generic<User>> input) {\n    Assert.isInstanceOf(Generic.class, input);\n    Assert.isInstanceOf(Generic.class, input.value);\n    Assert.isInstanceOf(User.class, input.value.value);\n    return input;\n  }\n\n  private volatile boolean testvoidInRPCSuccess = false;\n\n  @GetMapping(path = \"/testvoidInRPC\")\n  public void testvoidInRPC() {\n    LOGGER.info(\"testvoidInRPC() is called!\");\n    testvoidInRPCSuccess = true;\n  }\n\n  private volatile boolean testVoidInRPCSuccess = false;\n\n  @GetMapping(path = \"/testVoidInRPC\")\n  public Void testVoidInRPC() {\n    LOGGER.info(\"testVoidInRPC() is called!\");\n    testVoidInRPCSuccess = true;\n    return null;\n  }\n\n  private volatile boolean testvoidInRestTemplateSuccess = false;\n\n  @GetMapping(path = \"/testvoidInRestTemplate\")\n  public void testvoidInRestTemplate() {\n    LOGGER.info(\"testvoidInRestTemplate() is called!\");\n    testvoidInRestTemplateSuccess = true;\n  }\n\n  private volatile boolean testVoidInRestTemplateSuccess = false;\n\n  @GetMapping(path = \"/testVoidInRestTemplate\")\n  public Void testVoidInRestTemplate() {\n    LOGGER.info(\"testVoidInRestTemplate() is called!\");\n    testVoidInRestTemplateSuccess = true;\n    return null;\n  }\n\n  @GetMapping(path = \"/checkVoidResult\")\n  public boolean checkVoidResult() {\n    LOGGER.info(\"checkVoidResult() is called!\");\n    return testvoidInRPCSuccess && testVoidInRPCSuccess && testvoidInRestTemplateSuccess\n        && testVoidInRestTemplateSuccess;\n  }\n\n  /**\n   * Simple query object test, users can use it mixed with InvocationContext and plain query param, RequestBody\n   */\n  @PostMapping(path = \"/checkQueryObject\")\n  public String checkQueryObject(Person person, @RequestParam(name = \"otherName\") String otherName,\n      InvocationContext invocationContext, @RequestBody Person requestBody) {\n    LOGGER.info(\"checkQueryObject() is called!\");\n    return \"invocationContext_is_null=\" + (null == invocationContext) + \",person=\"\n        + person + \",otherName=\" + otherName + \",name=\" + person.getName() + \",requestBody=\" + requestBody;\n  }\n\n  /**\n   * For the nesting object params, including the generic params whose generic field is an object,\n   * the inner object field is not supported.\n   */\n  @PutMapping(path = \"/checkQueryGenericObject\")\n  public String checkQueryGenericObject(@RequestBody GenericParam<Person> requestBody,\n      GenericParamWithJsonIgnore<Person> generic) {\n    LOGGER.info(\"checkQueryGenericObject() is called!\");\n    return \"str=\" + generic.getStr() + \",generic=\" + generic + \",requestBody=\" + requestBody;\n  }\n\n  /**\n   * If the generic field is simple type, it's supported to be deserialized.\n   * The same for those simple type field inherited from the parent class.\n   */\n  @PutMapping(path = \"/checkQueryGenericString\")\n  public String checkQueryGenericString(@RequestBody GenericParam<Person> requestBody,\n      GenericParamExtended<String> generic) {\n    LOGGER.info(\"checkQueryGenericObject() is called!\");\n    return \"str=\" + generic.getStr() + \",generic=\" + generic + \",requestBody=\" + requestBody;\n  }\n\n  @GetMapping(path = \"/testDelay\")\n  public String testDelay() {\n    LOGGER.info(\"testDelay() is called!\");\n    return \"OK\";\n  }\n\n  @GetMapping(path = \"/testAbort\")\n  public String testAbort() {\n    LOGGER.info(\"testAbort() is called!\");\n    return \"OK\";\n  }\n\n  @GetMapping(path = \"/testDecodeResponseError\")\n  public DecodeTestResponse testDecodeResponseError() {\n    DecodeTestResponse response = new DecodeTestResponse();\n    response.setContent(\"returnOK\");\n    return response;\n  }\n\n  @RequestMapping(path = \"/testDefaultGetApiExample\")\n  public void testDefaultGetApiExample() {\n    LOGGER.info(\"testDefaultGetApiExample() is called!\");\n  }\n\n  @RequestMapping(path = \"/testHolder\")\n  public void testHolder(@RequestBody Holder name) {\n    LOGGER.info(\"testDefaultGetApiExample() is called!\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvcForSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.bind.annotation.ResponseBody;\nimport org.springframework.web.multipart.MultipartFile;\n\n/**\n * Created for testing schema to accommodate swagger api specification. When change this class, please use\n * http://editor.swagger.io/ to validate the generated schema and should not give any errors. In test case,\n * only checksum is validated to make sure schema is not changed.\n */\n@RestSchema(schemaId = \"CodeFirstSpringmvcForSchema\")\n@RequestMapping(path = \"/forSchema\")\npublic class CodeFirstSpringmvcForSchema {\n  /*\n   * Using http://editor.swagger.io/ . Listing errors not handled:\n   *\n   * #1. Should NOT have additional properties additionalProperty: type, format, name, in, required\n   /reduce:\n    get:\n      operationId: \"reduce\"\n      parameters:\n      - name: \"b\"\n        in: \"cookie\"\n        required: false\n   This schema gives error, but according to https://swagger.io/docs/specification/describing-parameters/#cookie-parameters\n   This should supported.\n\n\n   * #2. Operations with Parameters of \"in: formData\" must include \"application/x-www-form-urlencoded\" or \"multipart/form-data\" in their \"consumes\" property\n   This error can be fixed by user code.\n\n\n   *\n   */\n\n\n  @RequestMapping(path = \"/uploadFile\", method = RequestMethod.POST,\n      consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)\n  @ResponseBody\n  public boolean uploadAwardFile(@RequestParam(\"fileType\") String fileType, @RequestParam(\"zoneId\") String zoneId,\n      @RequestPart(\"file\") MultipartFile file) {\n    throw new UnsupportedOperationException(\"only for testing schema\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/Compatible1xTestSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"Compatible1xTestSchema\")\n@RequestMapping(path = \"/compatible\", produces = MediaType.APPLICATION_JSON)\npublic class Compatible1xTestSchema {\n  @GetMapping(path = \"/parameterName\")\n  public String parameterName(@RequestParam(name = \"a\", defaultValue = \"10\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"10\") int b) {\n    return ContextUtils.getInvocationContext().getContext(CoreConst.SRC_MICROSERVICE) + a + b * 2;\n  }\n\n  @GetMapping(path = \"/parameterNameServerContext\")\n  public String parameterNameServerContext(InvocationContext context,\n      @RequestParam(name = \"a\", defaultValue = \"10\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"10\") int b) {\n    return context.getContext(CoreConst.SRC_MICROSERVICE) + a + b * 2;\n  }\n\n  @GetMapping(path = \"/beanParameter\")\n  public String beanParameter(CompatibleQueryBean bean) {\n    return bean.getName() + bean.getAge();\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CompatibleQueryBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\npublic class CompatibleQueryBean {\n  private String name;\n\n  private int age;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ConfigurationProblemsCollectorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.core.bootup.ConfigurationProblemsAlarmEvent;\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.springframework.stereotype.Component;\n\nimport com.google.common.eventbus.Subscribe;\n\n@Component\npublic class ConfigurationProblemsCollectorTest implements CategorizedTestCase {\n  private ConfigurationProblemsAlarmEvent event;\n\n  public ConfigurationProblemsCollectorTest() {\n    EventManager.register(this);\n  }\n\n  @Subscribe\n  public void onConfigurationProblemsAlarmEvent(ConfigurationProblemsAlarmEvent event) {\n    this.event = event;\n  }\n\n  @Override\n  public void testRestTransport() throws Exception {\n    TestMgr.check(event != null, true);\n    TestMgr.check(event.getProblems(), \"[WARN]Configurations warnings:\\n\" +\n        \"Configurations with prefix `service_description` is deprecated, \"\n        + \"use `servicecomb.service` instead. Find keys [service_description.initialStatus]\\n\"\n        + \"Configuration `servicecomb.loadbalance.isolation.*` is removed, use governance instead. \"\n        + \"See https://servicecomb.apache.org/references/java-chassis/zh_CN/references-handlers/governance-best-practise.html\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ContentTypeSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.demo.server.User;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"contentTypeSpringmvc\")\n@RequestMapping(value = \"/contentTypeSpringmvc\", consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_PLAIN)\npublic class ContentTypeSpringmvc {\n  @RequestMapping(path = \"/testGlobalSetting\", method = RequestMethod.POST)\n  public String testGlobalSetting(@RequestBody String name, HttpServletRequest request) {\n    return String.format(\"testGlobalSetting: name=[%s], request content-type=[%s]\", name, request.getContentType());\n  }\n\n  @RequestMapping(path = \"/testApiOperation\", method = RequestMethod.POST)\n  public String testApiOperation(@RequestBody String name, HttpServletRequest request) {\n    return String.format(\"testApiOperation: name=[%s], request content-type=[%s]\", name, request.getContentType());\n  }\n\n  @RequestMapping(path = \"/testRequestMapping\", method = RequestMethod.POST,\n      consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)\n  public String testRequestMapping(@RequestBody String name, HttpServletRequest request) {\n    return String.format(\"testRequestMapping: name=[%s], request content-type=[%s]\", name, request.getContentType());\n  }\n\n  @RequestMapping(path = \"/testProtoBuffer\", method = RequestMethod.POST,\n      consumes = SwaggerConst.PROTOBUF_TYPE, produces = SwaggerConst.PROTOBUF_TYPE)\n  public String testProtoBuffer(@RequestBody User user, HttpServletRequest request) {\n    return String.format(\"testRequestMapping: name=[%s], request content-type=[%s]\",\n        user.getName() + \":\" + user.getIndex() + \":\" +\n            Arrays.toString(user.getNames()), request.getContentType());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ContentTypeSpringmvcOverwrite.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"contentTypeSpringmvcOverwrite\")\n@RequestMapping(value = \"/contentTypeSpringmvcOverwrite\", produces = MediaType.TEXT_PLAIN)\npublic class ContentTypeSpringmvcOverwrite {\n  @RequestMapping(value = \"/testResponseTypeOverwrite\", method = RequestMethod.GET)\n  public String testResponseTypeOverwrite() {\n    return \"testResponseTypeOverwrite: OK\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ControllerImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.demo.controller.Person;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.validation.constraints.Min;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\n// This class tests \"contract first\", the controller.yaml will override annotations defined in class.\n\n@RestSchema(schemaId = \"controller\")\n@RequestMapping(path = \"/springmvc/controller\", produces = MediaType.APPLICATION_JSON)\npublic class ControllerImpl {\n  @GetMapping(path = \"/add\")\n  public int add(@Min(1) @RequestParam(\"a\") int a, @Min(1) @RequestParam(\"b\") int b) {\n    return a + b;\n  }\n\n  @PostMapping(path = \"/sayhello/{name}\")\n  public String sayHello(@PathVariable(\"name\") String name) {\n    if (\"exception\".equals(name)) {\n      throw new InvocationException(Status.SERVICE_UNAVAILABLE, \"\");\n    }\n    return \"hello \" + name;\n  }\n\n  @RequestMapping(path = \"/saysomething\", method = RequestMethod.POST)\n  public String saySomething(String prefix, @RequestBody Person user) {\n    return prefix + \" \" + user.getName();\n  }\n\n  @Transport(name = CoreConst.RESTFUL)\n  @RequestMapping(path = \"/sayhi\", method = RequestMethod.GET)\n  public String sayHi(HttpServletRequest request) throws Exception {\n    String addr = request.getRemoteAddr();\n    if (addr == null || addr.isEmpty()) {\n      throw new Exception(\"Can't get remote addr!\");\n    }\n    String[] values = request.getParameterValues(\"name\");\n    if (values != null && values.length > 0 && values[0].equals(\"throwexception\")) {\n      throw new RuntimeException();\n    }\n    return \"hi \" + request.getParameter(\"name\") + \" \" + Arrays.toString(values);\n  }\n\n  @RequestMapping(path = \"/sayhei\", method = RequestMethod.GET)\n  public String sayHei(@RequestHeader(\"name\") String name) {\n    return \"hei \" + name;\n  }\n\n  @RequestMapping(path = \"/sayHello1\", method = RequestMethod.GET)\n  public String sayHello1(@RequestParam(\"name\") String name) {\n    return \"Hello \" + name + \",\" + ContextUtils.getInvocationContext().getContext(\"k\");\n  }\n\n  @RequestMapping(path = \"/testResponseModel\", method = RequestMethod.GET)\n  public Person testResponseModel() {\n    Person person = new Person();\n    person.setName(\"jack\");\n    return person;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DataTypesAnnotationsSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"DataTypesAnnotationsSchema\")\n@RequestMapping(path = \"/dataTypes\")\npublic class DataTypesAnnotationsSchema {\n  @GetMapping(path = \"/testIntArrayQuery\")\n  public int[] testIntArrayQuery(@RequestParam(\"param\") int[] param) {\n    return param;\n  }\n\n  @GetMapping(path = \"/testIntegerArrayQuery\")\n  public Integer[] testIntegerArrayQuery(@RequestParam(\"param\") Integer[] param) {\n    return param;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DateTimeSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.util.Date;\n\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"DateTimeSchema\")\n@RequestMapping(path = \"/dateTime\", produces = MediaType.APPLICATION_JSON)\npublic class DateTimeSchema {\n  @GetMapping(path = \"/getDate\")\n  public Date getDate(@RequestParam(\"date\") Date date) {\n    return date;\n  }\n\n  @GetMapping(path = \"/getDatePath/{date}\")\n  public Date getDatePath(@PathParam(\"date\") Date date) {\n    return date;\n  }\n\n  @PostMapping(path = \"/postDate\")\n  public Date postDate(@RequestBody Date date) {\n    return date;\n  }\n\n  @GetMapping(path = \"/getLocalDate\")\n  public LocalDate getLocalDate(@RequestParam(\"date\") LocalDate date) {\n    return date;\n  }\n\n  @GetMapping(path = \"/getLocalDate/{date}\")\n  public LocalDate getLocalDatePath(@PathParam(\"date\") LocalDate date) {\n    return date;\n  }\n\n  @PostMapping(path = \"/postLocalDate\")\n  public LocalDate postLocalDate(@RequestBody LocalDate date) {\n    return date;\n  }\n\n  @GetMapping(path = \"/getLocalDateTime\")\n  public LocalDateTime getLocalDateTime(@RequestParam(\"date\") LocalDateTime date) {\n    return date;\n  }\n\n  @GetMapping(path = \"/getLocalDateTime/{date}\")\n  public LocalDateTime getLocalDateTimePath(@PathParam(\"date\") LocalDateTime date) {\n    return date;\n  }\n\n  @PostMapping(path = \"/postLocalDateTime\")\n  public LocalDateTime postLocalDateTime(@RequestBody LocalDateTime date) {\n    return date;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/DownloadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.UUID;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.servlet.http.Part;\n\n@RestSchema(schemaId = \"DownloadSchema\")\n@RequestMapping(path = \"/download\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class DownloadSchema {\n  private File tempDir = new File(\"target/downloadTemp\");\n\n  private File lastFile;\n\n  private File createTempFile(String content) throws IOException {\n    return createTempFile(null, content);\n  }\n\n  private File createTempFile(String name, String content) throws IOException {\n    if (name == null) {\n      name = \"download-\" + UUID.randomUUID() + \".txt\";\n    }\n    File file = new File(tempDir, name);\n    FileUtils.write(file, content, StandardCharsets.UTF_8, false);\n    lastFile = file;\n    return file;\n  }\n\n  @GetMapping(path = \"/deleteAfterFinished\")\n  public ResponseEntity<Part> deleteAfterFinished(@RequestParam(\"content\") String content,\n      @RequestParam(value = \"fileName\", required = false) String fileName) throws IOException {\n    File file;\n\n    if (StringUtils.isNotEmpty(fileName)) {\n      file = createTempFile(fileName, content);\n    } else {\n      file = createTempFile(content);\n    }\n\n    return ResponseEntity\n        .ok()\n        .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=tempFileEntity.txt\")\n        .body(new FilePart(null, file)\n            .setDeleteAfterFinished(true));\n  }\n\n  @GetMapping(path = \"/partIsNull\")\n  public ResponseEntity<Part> partIsNull(@RequestParam(\"content\") String content) throws IOException {\n    if (StringUtils.isEmpty(content)) {\n      return ResponseEntity\n          .ok()\n          .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=tempFileEntity.txt\")\n          .body(null);\n    }\n    File file = createTempFile(content);\n    return ResponseEntity\n        .ok()\n        .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=tempFileEntity.txt\")\n        .body(new FilePart(null, file));\n  }\n\n  @GetMapping(path = \"/notDeleteAfterFinished\")\n  public ResponseEntity<Part> notDeleteAfterFinished(@RequestParam(\"content\") String content) throws IOException {\n    File file = createTempFile(content);\n\n    return ResponseEntity\n        .ok()\n        .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=tempFileEntity.txt\")\n        .body(new FilePart(null, file));\n  }\n\n  @GetMapping(path = \"/setContentTypeByResponseEntity\")\n  public ResponseEntity<Part> setContentTypeByResponseEntity(@RequestParam(\"content\") String content,\n      @RequestParam(\"contentType\") String contentType) throws IOException {\n    File file = createTempFile(content);\n\n    return ResponseEntity\n        .ok()\n        .header(HttpHeaders.CONTENT_TYPE, contentType)\n        .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=tempFileEntity.txt\")\n        .body(new FilePart(null, file));\n  }\n\n  @GetMapping(path = \"/assertLastFileDeleted\")\n  public boolean assertLastFileDeleted() {\n    return lastFile.exists();\n  }\n\n  @GetMapping(path = \"/testResponseOKExceptionDownload\")\n  public ResponseEntity<Part> testResponseOKExceptionDownload(\n      @RequestParam(\"exception\") boolean exception,\n      @RequestParam(\"content\") String content,\n      @RequestParam(\"contentType\") String contentType) throws IOException {\n    if (exception) {\n      throw new ResponseOKException();\n    }\n\n    File file = createTempFile(content);\n\n    return ResponseEntity\n        .ok()\n        .header(HttpHeaders.CONTENT_TYPE, contentType)\n        .header(HttpHeaders.CONTENT_DISPOSITION, \"attachment;filename=tempFileEntity.txt\")\n        .body(new FilePart(null, file));\n  }\n\n  @GetMapping(path = \"/testResponseOKExceptionBean\")\n  public boolean testResponseOKExceptionBean(@RequestParam(\"exception\") boolean exception) {\n    if (exception) {\n      throw new ResponseOKException();\n    }\n    return true;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/MyStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.qps.strategy.AbstractQpsStrategy;\n\npublic class MyStrategy extends AbstractQpsStrategy {\n\n  @Override\n  public boolean isLimitNewRequest() {\n    return false;\n  }\n\n  @Override\n  public String name() {\n    return \"MyStrategy\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/MyStrategyFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.qps.strategy.AbstractQpsStrategy;\nimport org.apache.servicecomb.qps.strategy.IStrategyFactory;\n\npublic class MyStrategyFactory implements IStrategyFactory {\n\n  @Override\n  public AbstractQpsStrategy createStrategy(String strategyName) {\n    if (strategyName.equals(\"MyStrategy\")) {\n      return new MyStrategy();\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectWriter;\n\nimport io.swagger.v3.core.util.Yaml;\nimport io.swagger.v3.oas.models.OpenAPI;\n\n/**\n * Testing after bootup.\n */\n@Component\npublic class ProducerTestsAfterBootup implements BootListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProducerTestsAfterBootup.class);\n\n  private ObjectWriter writer = Yaml.pretty();\n\n  public void testSchemaNotChange(SCBEngine scbEngine) {\n    LOGGER.info(\"ProducerTestsAfterBootup testing start\");\n    SchemaMeta meta = scbEngine.getProducerMicroserviceMeta().findSchemaMeta(\"CodeFirstSpringmvcForSchema\");\n    String codeFirst = getSwaggerContent(meta.getSwagger());\n\n    String expectSchema = UnitTestSwaggerUtils.loadExpect(\"schemas/CodeFirstSpringmvcForSchema.yaml\")\n        .replace(\"\\r\\n\", \"\\n\").trim();\n    int offset = expectSchema.indexOf(\"---\\nopenapi: 3.0.1\");\n    if (offset > 0) {\n      expectSchema = expectSchema.substring(offset + 4);\n    }\n\n    TestMgr.check(expectSchema.trim(), codeFirst.trim());\n  }\n\n  private String getSwaggerContent(OpenAPI swagger) {\n    try {\n      return writer.writeValueAsString(swagger);\n    } catch (JsonProcessingException e) {\n      throw new Error(e);\n    }\n  }\n\n  @Override\n  public void onBootEvent(BootEvent event) {\n    if (event.getEventType() == BootListener.EventType.AFTER_REGISTRY) {\n      testSchemaNotChange(event.getScbEngine());\n      if (!TestMgr.isSuccess()) {\n        TestMgr.summary();\n        throw new IllegalStateException(\"some tests are failed. \");\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ReadFileSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"testFileSource\")\n@RequestMapping(path = \"/springmvc/fileSource\")\npublic class ReadFileSource {\n  @Value(\"${int:-1}\")\n  public int testInt;\n\n  @GetMapping(path = \"/int\")\n  public int getTestInt() {\n    return testInt;\n  }\n\n  @Value(\"${String:error}\")\n  public String testString;\n\n  @GetMapping(path = \"/String\")\n  public String getTestString() {\n    return testString;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ResponseOKData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\npublic class ResponseOKData {\n  private String errorCode;\n\n  private String errorMessage;\n\n  public ResponseOKData(String errorCode, String errorMessage) {\n    this.errorCode = errorCode;\n    this.errorMessage = errorMessage;\n  }\n\n  public String getErrorCode() {\n    return errorCode;\n  }\n\n  public void setErrorCode(String errorCode) {\n    this.errorCode = errorCode;\n  }\n\n  public String getErrorMessage() {\n    return errorMessage;\n  }\n\n  public void setErrorMessage(String errorMessage) {\n    this.errorMessage = errorMessage;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ResponseOKException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\npublic class ResponseOKException extends RuntimeException {\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ResponseOKExceptionConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.ExceptionConverter;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class ResponseOKExceptionConverter implements\n    ExceptionConverter<ResponseOKException> {\n\n  @Override\n  public boolean canConvert(Throwable throwable) {\n    return throwable instanceof ResponseOKException;\n  }\n\n  @Override\n  public InvocationException convert(Invocation invocation, ResponseOKException throwable, StatusType genericStatus) {\n    // This is for compatible usage. For best practise, any status code\n    // should have only one type of response.\n    return new InvocationException(Status.OK, new ResponseOKData(\"code-005\", \"error-005\"));\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/RestProducersCustomized.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestProducers;\nimport org.springframework.context.annotation.Primary;\nimport org.springframework.stereotype.Component;\n\n@Component\n@Primary\n// This example shows user's how to customize RestProducers by @Primary annotation\npublic class RestProducersCustomized extends RestProducers {\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/RetrySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n// test cases for retry\n@RestSchema(schemaId = \"RetrySchema\")\n@RequestMapping(path = \"/retry\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class RetrySchema {\n  private AtomicLong counter = new AtomicLong(0);\n\n  @GetMapping(path = \"/governance/successWhenRetry\")\n  public boolean successWhenRetry() {\n    if (counter.getAndIncrement() % 3 != 0) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR, \"try again later.\");\n    }\n    return true;\n  }\n\n  @GetMapping(path = \"/governance/successWhenRetryAsync\")\n  public CompletableFuture<Boolean> successWhenRetryAsync() {\n    CompletableFuture<Boolean> result = new CompletableFuture<>();\n    if (counter.getAndIncrement() % 2 == 0) {\n      result.completeExceptionally(new InvocationException(Status.INTERNAL_SERVER_ERROR, \"try again later.\"));\n    } else {\n      result.complete(true);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SchemeInterfaceSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.validation.constraints.Min;\nimport jakarta.ws.rs.core.MediaType;\n\n@RequestMapping(path = \"/springmvc/schemaInterface\", produces = MediaType.APPLICATION_JSON)\npublic interface SchemeInterfaceSpringmvc {\n  @GetMapping(path = \"/add\")\n  int add(@Min(1) @RequestParam(\"a\") int a, @Min(1) @RequestParam(\"b\") int b);\n\n  @GetMapping(path = \"/tailingSlash/\")\n  String tailingSlash(HttpServletRequest request, @Min(1) @RequestParam(\"a\") int a, @Min(1) @RequestParam(\"b\") int b);\n\n  @GetMapping(path = \"/nonTailingSlash\")\n  String nonTailingSlash(HttpServletRequest request, @Min(1) @RequestParam(\"a\") int a, @Min(1) @RequestParam(\"b\") int b);\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SchemeInterfaceSpringmvcImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.validation.constraints.Min;\n\n@RestSchema(schemaId = \"SchemeInterfaceSpringmvc\", schemaInterface = SchemeInterfaceSpringmvc.class)\npublic class SchemeInterfaceSpringmvcImpl implements SchemeInterfaceSpringmvc {\n  @Override\n  public int add(@Min(1) int a, @Min(1) int b) {\n    return a + b;\n  }\n\n  @Override\n  public String tailingSlash(HttpServletRequest request, int a, int b) {\n    StringBuilder sb = new StringBuilder();\n    sb.append(request.getRequestURI()).append(\";\")\n        .append(request.getRequestURL()).append(\";\")\n        .append(request.getPathInfo()).append(\";\")\n        .append(a - b);\n    return sb.toString();\n  }\n\n  @Override\n  public String nonTailingSlash(HttpServletRequest request, int a, int b) {\n    StringBuilder sb = new StringBuilder();\n    sb.append(request.getRequestURI()).append(\";\")\n        .append(request.getRequestURL()).append(\";\")\n        .append(request.getPathInfo()).append(\";\")\n        .append(a - b);\n    return sb.toString();\n  }\n\n  public int reduce(int a, int b) {\n    return a - b;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMVCCommonSchemaInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.demo.CommonSchemaInterface;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\n@RestSchema(schemaId = \"SpringMVCCommonSchemaInterface\", schemaInterface = CommonSchemaInterface.class)\npublic class SpringMVCCommonSchemaInterface implements CommonSchemaInterface {\n  @Override\n  public String testInvocationTimeout(long timeout, String name) {\n    try {\n      Thread.sleep(timeout);\n    } catch (InterruptedException e) {\n\n    }\n\n    return name;\n  }\n\n  @Override\n  public String testInvocationTimeout(InvocationContext context, long timeout,\n      String name) {\n\n    if (\"customized\".equals(name)) {\n      try {\n        Thread.sleep(timeout);\n      } catch (InterruptedException e) {\n\n      }\n\n      Invocation invocation = (Invocation) context;\n      invocation.ensureInvocationNotTimeout();\n\n      throw new InvocationException(Status.BAD_REQUEST, \"not expected result\");\n    }\n\n    return testInvocationTimeout(timeout, name);\n  }\n\n  @Override\n  public String testInvocationTimeoutInClientWait(long timeout, String name) {\n    return testInvocationTimeout(timeout, name);\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"SpringMvcDefaultValues\")\n@RequestMapping(path = \"/springmvc/SpringMvcDefaultValues\", produces = MediaType.APPLICATION_JSON)\npublic class SpringMvcDefaultValues {\n\n  @PostMapping(path = \"/form\", consumes = MediaType.APPLICATION_FORM_URLENCODED)\n  public String form(@RequestParam(name = \"a\", defaultValue = \"20\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"bobo\") String b) {\n    return \"Hello \" + a + b;\n  }\n\n  @PostMapping(path = \"/header\")\n  public String header(@RequestHeader(name = \"a\", defaultValue = \"20\") int a,\n      @RequestHeader(name = \"b\", defaultValue = \"bobo\") String b,\n      @RequestHeader(name = \"c\", defaultValue = \"30\") Integer c) {\n    return \"Hello \" + a + b + c;\n  }\n\n  @GetMapping(\"/query\")\n  public String query(@RequestParam(name = \"a\", defaultValue = \"20\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"bobo\") String b,\n      @RequestParam(name = \"c\", defaultValue = \"40\") Integer c, @RequestParam(name = \"d\") int d) {\n    return \"Hello \" + a + b + c + d;\n  }\n\n  @GetMapping(\"/query2\")\n  public String query2(@RequestParam(name = \"e\", required = false) int e,\n      @RequestParam(name = \"a\", defaultValue = \"20\") int a,\n      @RequestParam(name = \"b\", defaultValue = \"bobo\") String b,\n      @RequestParam(name = \"c\", defaultValue = \"40\") Integer c,\n      @Min(value = 20) @Max(value = 30) @RequestParam(name = \"d\", required = false) int d) {\n    return \"Hello \" + a + b + c + d + e;\n  }\n\n  @GetMapping(\"/query3\")\n  public String query3(@RequestParam(\"a\") @Min(value = 20) int a, @RequestParam(name = \"b\", required = false) String b) {\n    return \"Hello \" + a + b;\n  }\n\n  @PostMapping(\"/javaprimitiveint\")\n  public String springJavaPrimitiveInt(@RequestParam(name = \"a\", required = false) int a,\n      @RequestParam(name = \"b\", defaultValue = \"bobo\") String b) {\n    return \"Hello \" + a + b;\n  }\n\n  @PostMapping(\"/javaprimitivenumber\")\n  public String springJavaPrimitiveNumber(@RequestParam(name = \"a\", required = false) float a,\n      @RequestParam(name = \"b\", required = false) boolean b) {\n    return \"Hello \" + a + b;\n  }\n\n  @PostMapping(\"/javaprimitivestr\")\n  public String springJavaPrimitiveStr(@RequestParam(name = \"a\", required = false) int a,\n      @RequestParam(name = \"b\", required = false) String b) {\n    if (b == null || b.equals(\"\")) {\n      return \"Hello\";\n    }\n    return \"Hello \" + b + a;\n  }\n\n  @PostMapping(\"/javaprimitivecomb\")\n  public String springJavaPrimitiveCombination(@RequestParam(name = \"a\", required = false) Integer a,\n      @RequestParam(name = \"b\", required = false) Float b) {\n    return \"Hello \" + a + b;\n  }\n\n  @PostMapping(\"/allprimitivetypes\")\n  public String allprimitivetypes(@RequestParam(name = \"pBoolean\", required = false) boolean pBoolean,\n      @RequestParam(name = \"pChar\", required = false) char pChar,\n      @RequestParam(name = \"pByte\", required = false) byte pByte,\n      @RequestParam(name = \"pShort\", required = false) short pShort,\n      @RequestParam(name = \"pInt\", required = false) int pInt,\n      @RequestParam(name = \"pLong\", required = false) long pLong,\n      @RequestParam(name = \"pFloat\", required = false) float pFloat,\n      @RequestParam(name = \"pDouble\", required = false) double pDouble,\n      @RequestParam(name = \"pDoubleWrap\", required = false) Double pDoubleWrap) {\n    return \"Hello \" + pBoolean + \",\"\n        + pChar + \",\"\n        + pByte + \",\"\n        + pShort + \",\"\n        + pInt + \",\"\n        + pLong + \",\"\n        + pFloat + \",\"\n        + pDouble + \",\"\n        + pDoubleWrap;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/TransportSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"TransportSchema\")\n@RequestMapping(path = \"/transport\")\npublic class TransportSchema {\n  @GetMapping(path = \"/restTransport\")\n  @Transport(name = CoreConst.RESTFUL)\n  public boolean restTransport(InvocationContext invocation) {\n    return CoreConst.RESTFUL.equals(((Invocation) invocation).getTransportName());\n  }\n\n  @GetMapping(path = \"/highwayTransport\")\n  @Transport(name = CoreConst.HIGHWAY)\n  public boolean highwayTransport(InvocationContext invocation) {\n    return CoreConst.HIGHWAY.equals(((Invocation) invocation).getTransportName());\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/UploadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestAttribute;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.multipart.MultipartFile;\n\n@RestSchema(schemaId = \"UploadSchema\")\n@RequestMapping(path = \"/upload\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class UploadSchema {\n  @PostMapping(path = \"/fileUpload\", produces = MediaType.TEXT_PLAIN_VALUE,\n      consumes = MediaType.MULTIPART_FORM_DATA_VALUE)\n  public String fileUpload(@RequestPart(name = \"files\") List<MultipartFile> files) {\n    try {\n      String fileName = UUID.randomUUID().toString();\n      List<File> savedFiles = new ArrayList<>();\n      int index = 0;\n      for (MultipartFile file : files) {\n        File tempFile = new File(\"random-server-\" + fileName + index);\n        savedFiles.add(tempFile);\n        file.transferTo(tempFile);\n        index++;\n      }\n      savedFiles.forEach(File::delete);\n      return \"success\";\n    } catch (IOException e) {\n      return \"failed\";\n    }\n  }\n\n  @GetMapping(path = \"/isServerStartUpSuccess\")\n  public boolean isServerStartUpSuccess() {\n    return TestMgr.isSuccess();\n  }\n\n  @PostMapping(path = \"/fileUploadMultiRpc\", produces = MediaType.TEXT_PLAIN_VALUE,\n      consumes = MediaType.MULTIPART_FORM_DATA_VALUE)\n  public String fileUploadMultiRpc(@RequestPart(name = \"files\") MultipartFile[] files) {\n    return \"fileUploadMulti success, and fileNum is \" + files.length;\n  }\n\n  @PostMapping(path = \"/uploadFileRequestPartAttribute\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String uploadFileRequestPartAttribute(@RequestPart(name = \"file\") MultipartFile file,\n      @RequestPart(name = \"attribute\") String attribute) throws IOException {\n    try (InputStream is = file.getInputStream()) {\n      return attribute + \" \" + IOUtils.toString(is, StandardCharsets.UTF_8);\n    }\n  }\n\n  @PostMapping(path = \"/uploadFileRequestPartAttributeList\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String uploadFileRequestPartAttributeList(@RequestPart(name = \"files\") List<MultipartFile> files,\n      @RequestPart(name = \"attributes\") List<String> attributes) throws IOException {\n    StringBuilder result = new StringBuilder();\n    for (MultipartFile file : files) {\n      try (InputStream is = file.getInputStream()) {\n        result.append(IOUtils.toString(is, StandardCharsets.UTF_8));\n      }\n    }\n    for (String attribute : attributes) {\n      result.append(attribute);\n    }\n    return result.toString();\n  }\n\n  @PostMapping(path = \"/uploadFileAndAttribute\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String uploadFileAndAttribute(@RequestPart(name = \"file\") MultipartFile file,\n      @RequestAttribute(name = \"attribute\") String attribute) throws IOException {\n    try (InputStream is = file.getInputStream()) {\n      return attribute + \" \" + IOUtils.toString(is, StandardCharsets.UTF_8);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/WeakSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.server;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.model.SpecialNameModel;\nimport org.apache.servicecomb.demo.server.GenericsModel;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\n@RestSchema(schemaId = \"weakSpringmvc\")\n@RequestMapping(path = \"/weakSpringmvc\", produces = MediaType.APPLICATION_JSON_VALUE)\npublic class WeakSpringmvc {\n  @GetMapping(path = \"/diffNames\")\n  @Operation(summary = \"differentName\", operationId = \"differentName\")\n  public int diffNames(@RequestParam(\"x\") int a, @RequestParam(\"y\") int b) {\n    return a * 2 + b;\n  }\n\n  @GetMapping(path = \"/genericParams\")\n  @Operation(summary = \"genericParams\", operationId = \"genericParams\")\n  public List<List<String>> genericParams(@RequestParam(\"code\") int code, @RequestBody List<List<String>> names) {\n    return names;\n  }\n\n  @GetMapping(path = \"/genericParamsModel\")\n  @Operation(summary = \"genericParamsModel\", operationId = \"genericParamsModel\")\n  public GenericsModel genericParamsModel(@RequestParam(\"code\") int code, @RequestBody GenericsModel model) {\n    return model;\n  }\n\n  @GetMapping(path = \"/specialNameModel\")\n  @Operation(summary = \"specialNameModel\", operationId = \"specialNameModel\")\n  public SpecialNameModel specialNameModel(@RequestParam(\"code\") int code, @RequestBody SpecialNameModel model) {\n    return model;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/third/EarlyConsumer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.third;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\n/**\n * see: https://github.com/apache/servicecomb-java-chassis/issues/2534\n */\n@Component\npublic class EarlyConsumer implements BootListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(EarlyConsumer.class);\n\n  @RpcReference(microserviceName = \"third\", schemaId = \"heartbeat\")\n  private HealthSchema healthSchema;\n\n  private volatile boolean stopped = false;\n\n  public EarlyConsumer() {\n    new Thread(() -> {\n      while (!stopped) {\n        LOGGER.info(\"calling service\");\n        try {\n          healthSchema.heartbeat();\n        } catch (Throwable e) {\n          // ignore error\n        }\n        try {\n          Thread.sleep(500);\n        } catch (Throwable e) {\n          // ignore error\n        }\n      }\n    }).start();\n  }\n\n  @Override\n  public void onAfterRegistry(BootEvent event) {\n    stopped = true;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/third/HealthSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.third;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping(\"/v1\")\npublic interface HealthSchema {\n  @GetMapping(value = \"/heartbeat\")\n  void heartbeat();\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/third/HeartBeatService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.third;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"health\", schemaInterface = HealthSchema.class)\npublic class HeartBeatService implements HealthSchema {\n  @Override\n  public void heartbeat() {\n\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/third/NormalConsumer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.third;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\n/**\n * see: https://github.com/apache/servicecomb-java-chassis/issues/2534\n */\n@Component\npublic class NormalConsumer implements BootListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(NormalConsumer.class);\n\n  @RpcReference(microserviceName = \"third\", schemaId = \"heartbeat\")\n  private HealthSchema healthSchema;\n\n  @Override\n  public void onAfterRegistry(BootListener.BootEvent event) {\n    try {\n      LOGGER.info(\"calling service after register\");\n\n      healthSchema.heartbeat();\n      LOGGER.info(\"heartbeat succ\");\n    } catch (Throwable e) {\n      TestMgr.failed(\"3rd invoke failed\", e);\n      throw e;\n    }\n  }\n\n\n  @Override\n  public int getOrder() {\n    // 比ThirdServiceRegister晚\n    return 0;\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/third/Register.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.springmvc.third;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n/**\n * see: https://github.com/apache/servicecomb-java-chassis/issues/2534\n */\n@Configuration\npublic class Register {\n  @Autowired\n  Environment environment;\n\n  @Bean\n  public RegistryBean thirdRegistryBean() {\n    String endpoint;\n    if (environment.getProperty(\"servicecomb.test.vert.transport\", boolean.class, true)) {\n      endpoint = \"rest://localhost:8080?sslEnabled=false&urlPrefix=%2Fapi\";\n    } else {\n      endpoint = \"rest://localhost:8080?sslEnabled=false\";\n    }\n\n    return new RegistryBean().addSchemaInterface(\"heartbeat\", HealthSchema.class)\n        .setAppId(\"springmvctest\")\n        .setServiceName(\"third\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(new Instance().setEndpoints(List.of(endpoint)))));\n  }\n}\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/resources/META-INF/services/org.apache.servicecomb.core.exception.ExceptionConverter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.springmvc.server.ResponseOKExceptionConverter\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/resources/META-INF/services/org.apache.servicecomb.qps.strategy.IStrategyFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.demo.springmvc.server.MyStrategyFactory\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# test not supported configuration\n# service_description.initialStatus\nservice_description:\n  initialStatus: TESTING\n\nservicecomb:\n  service:\n    application: springmvctest\n    name: springmvc\n    version: 0.0.3\n\n  registry:\n    sc:\n      address: http://127.0.0.1:9980,http://127.0.0.1:30100\n      autodiscovery: true\n      healthCheckIntervalInSeconds: 3\n      pollIntervalInMillis: 10000\n      watch: true\n\n  uploads:\n    directory: target\n  http:\n    dispatcher:\n      rest:\n        pattern: \"/api/(.*)\"\n  rest:\n    address: 0.0.0.0:8080?sslEnabled=false\n    server:\n      compression: true\n  highway:\n    address: 0.0.0.0:7070?sslEnabled=true\n  invocation:\n    timeout:\n      check:\n        enabled: true\n        strategy: processing-time\n    SpringMVCCommonSchemaInterface:\n      testInvocationTimeout:\n        timeout: 1000\n      testInvocationTimeoutWithInvocation:\n        timeout: 1000\n\n  flowcontrol:\n    strategy: MyStrategy\n    Provider:\n      qps:\n        enabled: true\n        global:\n          limit: 10\n          bucket: 30\n  tracing:\n    enabled: true\n    samplingRate: 0.5\n  datacenter:\n    name: myDC\n    region: my-Region\n    availableZone: my-Zone\n  codec.printErrorMessage: true\n\n  # For old testing\n  loadbalance:\n    isolation:\n      errorThresholdPercentage: 20\n#########SSL options\n# open jdk 8 now TLSv1.3 not available\n# ssl.protocols: TLSv1.3\n# ssl.ciphers: TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384\nssl.protocols: TLSv1.2\nssl.authPeer: true\nssl.checkCN.host: true\n\n#########certificates config\nssl.trustStore: trust.jks\nssl.trustStoreType: JKS\nssl.trustStoreValue: Changeme_123\nssl.keyStore: server.p12\nssl.keyStoreType: PKCS12\nssl.keyStoreValue: Changeme_123\nssl.crl: revoke.crl\nssl.sslCustomClass: org.apache.servicecomb.demo.DemoSSLCustom\n\nvertx.disableFileCPResolving: false  # false: create the .vertx directory, true: do not create\n"
  },
  {
    "path": "demo/demo-springmvc/springmvc-server/src/main/resources/schemas/CodeFirstSpringmvcForSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.springmvc.server.CodeFirstSpringmvcForSchema\n  version: 1.0.0\nservers:\n- url: /forSchema\npaths:\n  /uploadFile:\n    post:\n      operationId: uploadAwardFile\n      parameters:\n      - name: fileType\n        in: query\n        required: true\n        schema:\n          type: string\n      - name: zoneId\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                file:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: boolean\ncomponents: {}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/README.md",
    "content": "# Introduction\n\nThis demo tests zeroconfig.\n\n* server\n\n  run in docker\n\n* client\n\n  run in docker, and find server instances through zeroconfig, find schemas through\n  schema discovery\n\n* edge\n  run in docker, and find server instances through zeroconfig, find schemas through\n  schema discovery\n\n* tests\n\n  integration tests run in host machine, find client/edge instances through local,\n  and schemas from schema discovery.\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-zeroconfig-registry-client</artifactId>\n  <name>Java Chassis::Demo::ZeroConfig Registry Client</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zeroconfig-registry</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.zeroconfig.client.ClientApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zero-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/ClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.client;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ClientApplication {\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(ClientApplication.class).web(WebApplicationType.SERVLET)\n        .build().run(args);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/ClientModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.zeroconfig.client;\n\nimport java.util.Date;\n\npublic class ClientModel {\n  private Date updateDate;\n\n  public Date getUpdateDate() {\n    return updateDate;\n  }\n\n  public void setUpdateDate(Date updateDate) {\n    this.updateDate = updateDate;\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/ClientServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.client;\n\nimport java.util.Collections;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.vertx.core.json.JsonObject;\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ClientServerEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ClientServerEndpoint {\n  @RpcReference(microserviceName = \"demo-zeroconfig-registry-server\", schemaId = \"ServerEndpoint\")\n  private IServerEndpoint serverEndpoint;\n\n  @RpcReference(microserviceName = \"demo-zeroconfig-registry-server\", schemaId = \"RpcEndpoint\")\n  private IRpcEndpoint rpcEndpoint;\n\n  private DiscoveryManager discoveryManager;\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    return serverEndpoint.getName(name);\n  }\n\n  @GetMapping(path = \"/getRegisteredMicroservice\")\n  public Set<String> getRegisteredMicroservice() {\n    boolean result = true;\n    List<? extends DiscoveryInstance> microserviceList = discoveryManager\n        .findServiceInstances(\"demo-zeroconfig-registry\",\n            \"demo-zeroconfig-registry-client\");\n    if (microserviceList.size() != 2) { // local and zero config both have one instance\n      result = false;\n    }\n    microserviceList = discoveryManager\n        .findServiceInstances(\"demo-zeroconfig-registry\",\n            \"demo-zeroconfig-registry-server\");\n    if (microserviceList.size() != 1) {\n      result = false;\n    }\n\n    if (result) {\n      Set<String> names = new HashSet<>();\n      names.add(\"demo-zeroconfig-registry-client\");\n      names.add(\"demo-zeroconfig-registry-server\");\n      return names;\n    }\n\n    return Collections.emptySet();\n  }\n\n  @PostMapping(path = \"/jsonObject\")\n  public JsonObject jsonObject(@RequestBody JsonObject jsonObject) {\n    JsonObject param = new JsonObject();\n    param.put(\"map\", jsonObject);\n    JsonObject message = rpcEndpoint.getJsonObject(param);\n    JsonObject inner = new JsonObject();\n    inner.put(\"map\", message);\n    return inner;\n  }\n\n  @PostMapping(path = \"/getString\")\n  public String getString(@RawJsonRequestBody String jsonString) {\n    return jsonString;\n  }\n\n  @PostMapping(path = \"/postModel\")\n  public ClientModel postModel(@RequestBody ClientModel clientModel) {\n    return clientModel;\n  }\n\n  @GetMapping(path = \"/contextMapper\")\n  public String contextMapper(@RequestHeader(\"gatewayHeader\") String gatewayHeader,\n      @RequestHeader(\"clientHeader\") String clientHeader,\n      @RequestParam(\"gatewayQuery\") String gatewayQuery,\n      @RequestParam(\"clientQuery\") String clientQuery) {\n    InvocationContext context = ContextUtils.getInvocationContext();\n    if (gatewayHeader.equals(context.getContext(\"context-gateway-header\")) &&\n        clientHeader.equals(context.getContext(\"context-client-header\")) &&\n        gatewayQuery.equals(context.getContext(\"context-gateway-query\")) &&\n        clientQuery.equals(context.getContext(\"context-client-query\"))) {\n      return \"success\";\n    }\n    return \"fail\";\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.client;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.client.RestOperations;\n\nimport jakarta.ws.rs.core.Response.Status;\n\n@RestSchema(schemaId = \"GovernanceEndpoint\")\n@RequestMapping(\"/governance\")\npublic class GovernanceEndpoint {\n  private static final String SERVER = \"servicecomb://demo-zeroconfig-registry-server\";\n\n  private RestOperations restTemplate = RestTemplateBuilder.create();\n\n  private int count = 0;\n\n  @GetMapping(\"/hello\")\n  public String hello() {\n    return restTemplate.getForObject(SERVER + \"/governance/hello\", String.class);\n  }\n\n  @GetMapping(\"/helloRpc\")\n  public String helloRpc() {\n    return restTemplate.getForObject(SERVER + \"/governance/hello\", String.class);\n  }\n\n  @GetMapping(\"/noPrefixRetry\")\n  public String noPrefixRetry(@RequestParam(name = \"invocationID\") String invocationID) {\n    return restTemplate\n        .getForObject(SERVER + \"/noPrefixRetry?invocationID={1}\", String.class,\n            invocationID);\n  }\n\n  @GetMapping(\"/retry\")\n  public String retry(@RequestParam(name = \"invocationID\") String invocationID) {\n    return restTemplate\n        .getForObject(SERVER + \"/governance/retry?invocationID={1}\", String.class,\n            invocationID);\n  }\n\n  @GetMapping(\"/retryRpc\")\n  public String retryRpc(@RequestParam(name = \"invocationID\") String invocationID) {\n    return restTemplate\n        .getForObject(SERVER + \"/governance/retryRpc?invocationID={1}\", String.class,\n            invocationID);\n  }\n\n  @GetMapping(\"/circuitBreaker\")\n  public String circuitBreaker() throws Exception {\n    count++;\n    if (count % 3 == 0) {\n      return \"ok\";\n    }\n    throw new InvocationException(Status.SERVICE_UNAVAILABLE, \"test error\");\n  }\n\n  @GetMapping(\"/bulkhead\")\n  public String bulkhead() {\n    return restTemplate.getForObject(SERVER + \"/governance/hello\", String.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/IRpcEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.client;\n\nimport io.vertx.core.json.JsonObject;\n\npublic interface IRpcEndpoint {\n  JsonObject getJsonObject(JsonObject message);\n\n  String getString(String message);\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/IServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.client;\n\npublic interface IServerEndpoint {\n  String getName(String name);\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8082\n\nservicecomb:\n  service:\n    application: demo-zeroconfig-registry\n    name: demo-zeroconfig-registry-client\n    version: 0.0.2\n  rest:\n    address: 0.0.0.0:8082\n  highway:\n    address: 0.0.0.0:8084\n  config:\n    client:\n      # for testing dynamic configuration\n      # serverUri: http://127.0.0.1:30113\n      refreshMode: 0\n      # refresh_interval: 5000\n      # refreshPort: 30114\n  governance:\n    GovernanceEndpoint.helloRpc:\n      matchType: rpc\n    demo-zeroconfig-registry-server.GovernanceEndpoint.retryRpc:\n      matchType: rpc\n  matchGroup:\n    demo-rateLimiting: |\n      matches:\n        - apiPath:\n            exact: \"/governance/hello\"\n    demo-rateLimiting-rpc: |\n      matches:\n        - apiPath:\n            exact: \"GovernanceEndpoint.helloRpc\"\n    demo-retry: |\n      matches:\n        - apiPath:\n            exact: \"/governance/retry\"\n    demo-retry-no-prefix: |\n      matches:\n        - apiPath:\n            exact: \"/noPrefixRetry\"\n    demo-retry-rpc: |\n      matches:\n        - apiPath:\n            exact: \"demo-zeroconfig-registry-server.GovernanceEndpoint.retryRpc\"\n    demo-circuitBreaker: |\n      matches:\n        - apiPath:\n            exact: \"/governance/circuitBreaker\"\n    demo-bulkhead: |\n      matches:\n        - apiPath:\n            exact: \"/governance/bulkhead\"\n  rateLimiting:\n    demo-rateLimiting: |\n      rate: 10\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n    demo-rateLimiting-rpc: |\n      rate: 10\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n  retry:\n    demo-retry: |\n      maxAttempts: 3\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n    demo-retry-no-prefix: |\n      maxAttempts: 3\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n    demo-retry-rpc: |\n      maxAttempts: 3\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n  circuitBreaker:\n    demo-circuitBreaker: |\n      minimumNumberOfCalls: 10\n      slidingWindowSize: 10\n      failureRateThreshold: 20\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n  bulkhead:\n    demo-bulkhead: |\n      maxConcurrentCalls: 5\n      ## services is optional in configuration file\n      services: demo-zeroconfig-registry-client\n  context:\n    headerContextMapper: |\n      clientHeader: context-client-header\n    queryContextMapper: |\n      clientQuery: context-client-query\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-zeroconfig-registry-edge</artifactId>\n  <name>Java Chassis::Demo::ZeroConfig Registry Edge</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zeroconfig-registry</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.zeroconfig.edge.EdgeApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zero-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/EdgeApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.edge;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class EdgeApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(EdgeApplication.class).web(WebApplicationType.NONE).build().run(args);\n\n    SelfServiceInvoker invoker = BeanUtils.getBean(\"SelfServiceInvoker\");\n    invoker.latch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(invoker.result, \"hello\");\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      System.exit(1);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/SelfServiceInvoker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.edge;\n\nimport java.util.concurrent.CountDownLatch;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component(\"SelfServiceInvoker\")\npublic class SelfServiceInvoker implements BootListener {\n  interface IServerEndpoint {\n    String getName(String name);\n  }\n\n  @RpcReference(microserviceName = \"demo-zeroconfig-registry-edge\", schemaId = \"ServerEndpoint\")\n  IServerEndpoint endpoint;\n\n  public CountDownLatch latch = new CountDownLatch(1);\n\n  public String result = \"\";\n\n  public void onAfterRegistry(BootEvent event) {\n    result = endpoint.getName(\"hello\");\n    latch.countDown();\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/src/main/java/org/apache/servicecomb/demo/zeroconfig/edge/ServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.edge;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ServerEndpoint\")\n@RequestMapping(path = \"/edge/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ServerEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8888\n\nservicecomb:\n  service:\n    application: demo-zeroconfig-registry\n    name: demo-zeroconfig-registry-edge\n    version: 0.0.2\n  rest:\n    address: 0.0.0.0:8888\n  filter-chains:\n    enabled: true\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            client:\n              prefixSegmentCount: 0\n              path: \"/register/url/prefix/.*\"\n              microserviceName: demo-zeroconfig-registry-client\n              versionRule: 0+\n  references:\n    transport:\n      demo-zeroconfig-registry-client.ClientServerEndpoint.contextMapper: rest\n\n  context:\n    headerContextMapper: |\n      gatewayHeader: context-gateway-header\n    queryContextMapper: |\n      gatewayQuery: context-gateway-query\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-zeroconfig-registry-server</artifactId>\n  <name>Java Chassis::Demo::ZeroConfig Registry Server</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zeroconfig-registry</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.zeroconfig.server.ServerApplication</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zero-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n          <plugin>\n            <groupId>org.commonjava.maven.plugins</groupId>\n            <artifactId>directory-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.server;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport jakarta.ws.rs.core.Response.Status;\n\n@RestSchema(schemaId = \"GovernanceEndpoint\")\n@RequestMapping(\"/governance\")\npublic class GovernanceEndpoint {\n  private static final Logger LOGGER = LoggerFactory.getLogger(GovernanceEndpoint.class);\n\n  private Map<String, Integer> retryTimes = new HashMap<>();\n\n  @GetMapping(\"/hello\")\n  public String sayHello() {\n    return \"Hello world!\";\n  }\n\n  @GetMapping(\"/retry\")\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\"),\n      @ApiResponse(responseCode = \"502\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\")})\n  public String retry(@RequestParam(name = \"invocationID\") String invocationID) {\n    LOGGER.info(\"invoke service: {}\", invocationID);\n    retryTimes.putIfAbsent(invocationID, 0);\n    retryTimes.put(invocationID, retryTimes.get(invocationID) + 1);\n\n    int retry = retryTimes.get(invocationID);\n\n    if (retry == 3) {\n      return \"try times: \" + retry;\n    }\n    throw new InvocationException(502, \"retry\", \"retry\");\n  }\n\n  @GetMapping(\"/retryRpc\")\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\"),\n      @ApiResponse(responseCode = \"502\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\")})\n  public String retryRpc(@RequestParam(name = \"invocationID\") String invocationID) {\n    return retry(invocationID);\n  }\n\n  @GetMapping(\"/circuitBreaker\")\n  public String circuitBreaker() {\n    throw new InvocationException(Status.SERVICE_UNAVAILABLE, \"\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceNoPrefixEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.server;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\n\n@RestSchema(schemaId = \"GovernanceNoPrefixEndpoint\")\n@RequestMapping(\"/\")\npublic class GovernanceNoPrefixEndpoint {\n  private static final Logger LOGGER = LoggerFactory.getLogger(GovernanceNoPrefixEndpoint.class);\n\n  private Map<String, Integer> retryTimes = new HashMap<>();\n\n  @GetMapping(\"/noPrefixRetry\")\n  @ApiResponses({\n      @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\"),\n      @ApiResponse(responseCode = \"502\", content = @Content(schema = @Schema(implementation = String.class)), description = \"\")})\n  public String noPrefixRetry(@RequestParam(name = \"invocationID\") String invocationID) {\n    LOGGER.info(\"invoke service: {}\", invocationID);\n    retryTimes.putIfAbsent(invocationID, 0);\n    retryTimes.put(invocationID, retryTimes.get(invocationID) + 1);\n\n    int retry = retryTimes.get(invocationID);\n\n    if (retry == 3) {\n      return \"try times: \" + retry;\n    }\n    throw new InvocationException(502, \"retry\", \"retry\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/RpcEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.server;\n\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\n\nimport io.vertx.core.json.JsonObject;\n\n@RpcSchema(schemaId = \"RpcEndpoint\")\npublic class RpcEndpoint {\n  public JsonObject getJsonObject(JsonObject message) {\n    JsonObject inner = new JsonObject();\n    inner.put(\"map\", message);\n    return inner;\n  }\n\n  public String getString(String message) {\n    return message;\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/SelfServiceInvoker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.server;\n\nimport java.util.concurrent.CountDownLatch;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.stereotype.Component;\n\n@Component(\"SelfServiceInvoker\")\npublic class SelfServiceInvoker implements BootListener {\n  interface IServerEndpoint {\n    String getName(String name);\n  }\n\n  @RpcReference(microserviceName = \"demo-zeroconfig-registry-server\", schemaId = \"ServerEndpoint\")\n  IServerEndpoint endpoint;\n\n  public CountDownLatch latch = new CountDownLatch(1);\n\n  public String result = \"\";\n\n  public void onAfterRegistry(BootEvent event) {\n    result = endpoint.getName(\"hello\");\n    latch.countDown();\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/ServerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.server;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ServerApplication {\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(ServerApplication.class).web(WebApplicationType.SERVLET).build().run(args);\n\n    SelfServiceInvoker invoker = BeanUtils.getBean(\"SelfServiceInvoker\");\n    invoker.latch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(invoker.result, \"hello\");\n\n    TestMgr.summary();\n    if (!TestMgr.errors().isEmpty()) {\n      System.exit(1);\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/ServerEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.server;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestSchema(schemaId = \"ServerEndpoint\")\n@RequestMapping(path = \"/register/url/prefix\", produces = MediaType.APPLICATION_JSON)\npublic class ServerEndpoint {\n  @GetMapping(path = \"/getName\")\n  public String getName(@RequestParam(name = \"name\") String name) {\n    ((Invocation) ContextUtils.getInvocationContext()).getTraceIdLogger().info(\"get name invoked.\");\n    return name;\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nserver:\n  port: 8080\n\nservicecomb:\n  service:\n    application: demo-zeroconfig-registry\n    name: demo-zeroconfig-registry-server\n    version: 0.0.2\n\n  rest:\n    address: 0.0.0.0:8080\n  filter-chains:\n    enabled: true\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p]%m [%c:%L]%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>demo-zeroconfig-registry-tests</artifactId>\n  <name>Java Chassis::Demo::ZeroConfig Registry Tests</name>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zeroconfig-registry</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <properties>\n    <demo.main>org.apache.servicecomb.demo.zeroconfig.tests.Application</demo.main>\n  </properties>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>demo-zeroconfig-registry-server:${project.version}</name>\n                    <alias>demo-zeroconfig-registry-server</alias>\n                    <run>\n                      <env>\n                        <JAR_PATH>/maven/maven/demo-zeroconfig-registry-server-${project.version}.jar\n                        </JAR_PATH>\n                      </env>\n                      <wait>\n                        <log>Service information is shown below</log>\n                        <tcp>\n                          <ports>\n                            <port>8080</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8080:8080</port>\n                      </ports>\n                    </run>\n                  </image>\n\n                  <image>\n                    <name>demo-zeroconfig-registry-client:${project.version}</name>\n                    <alias>demo-zeroconfig-registry-client</alias>\n                    <run>\n                      <env>\n                        <JAR_PATH>/maven/maven/demo-zeroconfig-registry-client-${project.version}.jar\n                        </JAR_PATH>\n                      </env>\n                      <wait>\n                        <log>Service information is shown below</log>\n                        <tcp>\n                          <ports>\n                            <port>8082</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8082:8082</port>\n                      </ports>\n                    </run>\n                  </image>\n\n                  <image>\n                    <name>demo-zeroconfig-registry-edge:${project.version}</name>\n                    <alias>demo-zeroconfig-registry-edge</alias>\n                    <run>\n                      <env>\n                        <JAR_PATH>/maven/maven/demo-zeroconfig-registry-edge-${project.version}.jar\n                        </JAR_PATH>\n                      </env>\n                      <wait>\n                        <log>Service information is shown below</log>\n                        <tcp>\n                          <ports>\n                            <port>8888</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>8888:8888</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/Application.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.tests;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class Application {\n  private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);\n\n  public static void main(final String[] args) throws Exception {\n    new SpringApplicationBuilder().sources(Application.class).web(WebApplicationType.NONE)\n        .build().run(args);\n\n    runTest();\n\n    TestMgr.summary();\n\n    LOGGER.info(\"-------------- last time updated checks(maybe more/less): 662 -------------\");\n\n    if (!TestMgr.errors().isEmpty()) {\n      throw new IllegalStateException(\"tests failed\");\n    }\n  }\n\n  private static void runTest() throws Exception {\n    CategorizedTestCaseRunner\n        .runCategorizedTestCase(\"demo-zeroconfig-registry-server\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/ClientModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.demo.zeroconfig.tests;\n\nimport java.util.Date;\n\npublic class ClientModel {\n  private Date updateDate;\n\n  public Date getUpdateDate() {\n    return updateDate;\n  }\n\n  public void setUpdateDate(Date updateDate) {\n    this.updateDate = updateDate;\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.tests;\n\nimport java.util.UUID;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.client.RestOperations;\n\n@Component\npublic class GovernanceTest implements CategorizedTestCase {\n  String url = \"servicecomb://demo-zeroconfig-registry-client/governance\";\n\n  RestOperations template = RestTemplateBuilder.create();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testCircuitBreaker();\n    testBulkhead();\n    testRateLimitingRest();\n    testRateLimitingRpc();\n    testRetryRest();\n    testRetryRestNoPrefix();\n    testRetryRpc();\n  }\n\n  private void testRetryRestNoPrefix() {\n    testRetry(\"/noPrefixRetry\");\n  }\n\n  private void testRetryRest() {\n    testRetry(\"/retry\");\n  }\n\n  private void testRetryRpc() {\n    testRetry(\"/retryRpc\");\n  }\n\n  private void testRetry(String operation) {\n    String invocationID = UUID.randomUUID().toString();\n    String result = template.getForObject(url + operation + \"?invocationID={1}\", String.class, invocationID);\n    TestMgr.check(result, \"try times: 3\");\n  }\n\n  private void testCircuitBreaker() throws Exception {\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              String result = template.getForObject(url + \"/circuitBreaker\", String.class);\n              if (!\"ok\".equals(result)) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (\"InvocationException: code=429;msg=CommonExceptionData [message=circuitBreaker is open.]\"\n                  .equals(e.getMessage())) {\n                expectedFailed.set(true);\n              } else if (\"InvocationException: code=503;msg=CommonExceptionData [message=test error]\"\n                  .equals(e.getMessage())) {\n                // by pass\n              } else {\n                notExpectedFailed.set(true);\n              }\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(true, expectedFailed.get());\n    TestMgr.check(false, notExpectedFailed.get());\n  }\n\n  private void testBulkhead() throws Exception {\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              String result = template.getForObject(url + \"/bulkhead\", String.class);\n              if (!\"Hello world!\".equals(result)) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (!\"InvocationException: code=429;msg=CommonExceptionData [message=bulkhead is full and does not permit further calls.]\"\n                  .equals(e.getMessage())) {\n                notExpectedFailed.set(true);\n              }\n              expectedFailed.set(true);\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(true, expectedFailed.get());\n    TestMgr.check(false, notExpectedFailed.get());\n  }\n\n  private void testRateLimitingRest() throws Exception {\n    testRateLimiting(\"/hello\");\n  }\n\n  private void testRateLimitingRpc() throws Exception {\n    testRateLimiting(\"/helloRpc\");\n  }\n\n  private void testRateLimiting(String operation) throws Exception {\n    CountDownLatch latch = new CountDownLatch(100);\n    AtomicBoolean expectedFailed = new AtomicBoolean(false);\n    AtomicBoolean notExpectedFailed = new AtomicBoolean(false);\n\n    for (int i = 0; i < 10; i++) {\n      for (int j = 0; j < 10; j++) {\n        String name = \"t-\" + i + \"-\" + j;\n        new Thread(name) {\n          public void run() {\n            try {\n              String result = template.getForObject(url + operation, String.class);\n              if (!\"Hello world!\".equals(result)) {\n                notExpectedFailed.set(true);\n              }\n            } catch (Exception e) {\n              if (!\"InvocationException: code=429;msg=CommonExceptionData [message=rate limited.]\"\n                  .equals(e.getMessage())) {\n                notExpectedFailed.set(true);\n              }\n              expectedFailed.set(true);\n            }\n            latch.countDown();\n          }\n        }.start();\n      }\n      Thread.sleep(100);\n    }\n\n    latch.await(20, TimeUnit.SECONDS);\n    TestMgr.check(true, expectedFailed.get());\n    TestMgr.check(false, notExpectedFailed.get());\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/ServerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.tests;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.Date;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.CountDownLatch;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;\nimport org.springframework.core.ParameterizedTypeReference;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.RequestEntity;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\n\nimport io.vertx.core.json.JsonObject;\n\n@Component\npublic class ServerTest implements CategorizedTestCase {\n\n  RestOperations template = RestTemplateBuilder.create();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testServerGetName();\n    testGetAllMicroservice();\n    testJsonObject();\n    testString();\n    testDateForEdge();\n    testContextMapper();\n  }\n\n  private void testContextMapper() throws URISyntaxException {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"clientHeader\", \"v1\");\n    headers.add(\"gatewayHeader\", \"v2\");\n    RequestEntity<Void> requestEntity = new RequestEntity<>(headers, HttpMethod.GET,\n        new URI(\"cse://demo-zeroconfig-registry-edge/register/url/prefix/contextMapper?clientQuery=v3&\"\n            + \"gatewayQuery=v4\"));\n    // test two times to check different transport(only use rest)\n    ResponseEntity<String> response = template.exchange(requestEntity, String.class);\n    TestMgr.check(response.getBody(), \"success\");\n    response = template.exchange(requestEntity, String.class);\n    TestMgr.check(response.getBody(), \"success\");\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void testDateForEdge() {\n    for (int i = 0; i < 3; i++) {\n      ClientModel clientModelReq = new ClientModel();\n      Date date = new Date(1663590135202L);\n      clientModelReq.setUpdateDate(date);\n      Map<String, Object> response = template\n          .postForObject(\n              \"cse://demo-zeroconfig-registry-edge\"\n                  + \"/register/url/prefix/postModel\", clientModelReq,\n              Map.class);\n      Object result = response.get(\"updateDate\");\n      // TODO: highway and rest Date field will give different result\n      // we can not change this now, because it is incompatible\n      if (result instanceof Long) {\n        TestMgr.check(response.get(\"updateDate\"), 1663590135202L);\n      } else {\n        TestMgr.check(response.get(\"updateDate\"), \"2022-09-19T12:22:15.202+00:00\");\n      }\n    }\n  }\n\n  private void testServerGetName() throws Exception {\n    // invoke demo-zeroconfig-registry-client\n    TestMgr.check(\"world\", template\n        .getForObject(\n            \"cse://demo-zeroconfig-registry-client/register/url/prefix/getName?name=world\",\n            String.class));\n    // invoke demo-zeroconfig-registry-edge\n    // create many threads to test event-loop not blocking\n    int thread = 32;\n    CountDownLatch latch = new CountDownLatch(thread);\n    for (int i = 0; i < thread; i++) {\n      new Thread(() -> {\n        for (int j = 0; j < 20; j++) {\n          try {\n            TestMgr.check(\"world\", template\n                .getForObject(\n                    \"cse://demo-zeroconfig-registry-edge/register/url/prefix/getName?name=world\",\n                    String.class));\n          } catch (Exception e) {\n            TestMgr.failed(\"test failed\", e);\n          }\n        }\n        latch.countDown();\n      }).start();\n    }\n\n    latch.await();\n  }\n\n  @SuppressWarnings(\"rawTypes\")\n  private void testGetAllMicroservice() {\n    // invoke demo-zeroconfig-registry-client\n    TestMgr.check(\"2\", template\n        .exchange(\n            \"cse://demo-zeroconfig-registry-client\"\n                + \"/register/url/prefix/getRegisteredMicroservice\", HttpMethod.GET, null,\n            new ParameterizedTypeReference<Set<String>>() {\n\n            }).getBody().size());\n    // invoke demo-zeroconfig-registry-edge\n    TestMgr.check(\"2\", template\n        .exchange(\n            \"cse://demo-zeroconfig-registry-edge\"\n                + \"/register/url/prefix/getRegisteredMicroservice\", HttpMethod.GET, null,\n            new ParameterizedTypeReference<Set<String>>() {\n\n            }).getBody().size());\n  }\n\n  private void testJsonObject() {\n    JsonObject in = new JsonObject();\n    JsonObject inner = new JsonObject();\n    //调用者需要按照swagger传参\n    inner.put(\"hello\", \"world\");\n    in.put(\"map\", inner);\n\n    JsonObject result = template\n        .postForObject(\n            \"cse://demo-zeroconfig-registry-client\"\n                + \"/register/url/prefix/jsonObject\", in, JsonObject.class);\n    TestMgr.check(inner.toString(), result.toString());\n    TestMgr.check(result.getString(\"hello\"), \"world\");\n  }\n\n  private void testString() {\n    String in = \"{\\\"hello\\\":\\\"world\\\"}\";\n    String result = template\n        .postForObject(\n            \"cse://demo-zeroconfig-registry-client\"\n                + \"/register/url/prefix/getString\", in, String.class);\n    TestMgr.check(in, result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/application.yml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  service:\n    application: demo-zeroconfig-registry\n    name: demo-zeroconfig-registry-tests\n    version: 0.0.2\n  handler:\n    chain:\n      Consumer:\n        default: loadbalance\n  loadbalance:\n    filter:\n      isolation:\n        enabled: false\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<configuration scan=\"true\">\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n    <encoder>\n      <pattern>%d [%level] [%thread] - %msg (%F:%L\\)%n</pattern>\n    </encoder>\n  </appender>\n\n  <root level=\"info\">\n    <appender-ref ref=\"STDOUT\"/>\n  </root>\n</configuration>\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/microservices/demo-zeroconfig-registry-client/ClientServerEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.zeroconfig.client.ClientServerEndpoint\n  version: 1.0.0\nservers:\n- url: /register/url/prefix\npaths:\n  /contextMapper:\n    get:\n      operationId: contextMapper\n      parameters:\n      - name: gatewayHeader\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: clientHeader\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: gatewayQuery\n        in: query\n        required: true\n        schema:\n          type: string\n      - name: clientQuery\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /getName:\n    get:\n      operationId: getName\n      parameters:\n      - name: name\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /getRegisteredMicroservice:\n    get:\n      operationId: getRegisteredMicroservice\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                uniqueItems: true\n                type: array\n                items:\n                  type: string\n  /getString:\n    post:\n      operationId: getString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n        required: true\n        x-raw-json: true\n        x-name: jsonString\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /jsonObject:\n    post:\n      operationId: jsonObject\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/JsonObject'\n        required: true\n        x-name: jsonObject\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/JsonObject'\n  /postModel:\n    post:\n      operationId: postModel\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ClientModel'\n        required: true\n        x-name: clientModel\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ClientModel'\ncomponents:\n  schemas:\n    JsonObject:\n      type: object\n      properties:\n        map:\n          type: object\n          additionalProperties:\n            type: object\n        empty:\n          type: boolean\n      x-java-class: io.vertx.core.json.JsonObject\n    ClientModel:\n      type: object\n      properties:\n        updateDate:\n          type: string\n          format: date-time\n      x-java-class: org.apache.servicecomb.demo.zeroconfig.client.ClientModel\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/microservices/demo-zeroconfig-registry-client/GovernanceEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.zeroconfig.client.GovernanceEndpoint\n  version: 1.0.0\nservers:\n- url: /governance\npaths:\n  /bulkhead:\n    get:\n      operationId: bulkhead\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /circuitBreaker:\n    get:\n      operationId: circuitBreaker\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /hello:\n    get:\n      operationId: hello\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /helloRpc:\n    get:\n      operationId: helloRpc\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /noPrefixRetry:\n    get:\n      operationId: noPrefixRetry\n      parameters:\n      - name: invocationID\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /retry:\n    get:\n      operationId: retry\n      parameters:\n      - name: invocationID\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /retryRpc:\n    get:\n      operationId: retryRpc\n      parameters:\n      - name: invocationID\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/microservices/demo-zeroconfig-registry-client/SchemaDiscoveryEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.schemadiscovery.SchemaDiscoveryEndpoint\n  version: 1.0.0\nservers:\n- url: /v1/schema/discovery\npaths:\n  /getSchema:\n    get:\n      operationId: getSchema\n      parameters:\n      - name: schemaId\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/microservices/demo-zeroconfig-registry-edge/ClientServerEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.demo.zeroconfig.client.ClientServerEndpoint\n  version: 1.0.0\nservers:\n- url: /register/url/prefix\npaths:\n  /contextMapper:\n    get:\n      operationId: contextMapper\n      parameters:\n      - name: gatewayHeader\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: clientHeader\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: gatewayQuery\n        in: query\n        required: true\n        schema:\n          type: string\n      - name: clientQuery\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /getName:\n    get:\n      operationId: getName\n      parameters:\n      - name: name\n        in: query\n        required: true\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /getRegisteredMicroservice:\n    get:\n      operationId: getRegisteredMicroservice\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                uniqueItems: true\n                type: array\n                items:\n                  type: string\n  /getString:\n    post:\n      operationId: getString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n        required: true\n        x-raw-json: true\n        x-name: jsonString\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /jsonObject:\n    post:\n      operationId: jsonObject\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/JsonObject'\n        required: true\n        x-name: jsonObject\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/JsonObject'\n  /postModel:\n    post:\n      operationId: postModel\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ClientModel'\n        required: true\n        x-name: clientModel\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ClientModel'\ncomponents:\n  schemas:\n    JsonObject:\n      type: object\n      properties:\n        map:\n          type: object\n          additionalProperties:\n            type: object\n        empty:\n          type: boolean\n      x-java-class: io.vertx.core.json.JsonObject\n    ClientModel:\n      type: object\n      properties:\n        updateDate:\n          type: string\n          format: date-time\n      x-java-class: org.apache.servicecomb.demo.zeroconfig.client.ClientModel\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/microservices/demo-zeroconfig-registry-edge/SchemaDiscoveryEndpoint.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.schemadiscovery.SchemaDiscoveryEndpoint\n  version: 1.0.0\nservers:\n- url: /v1/schema/discovery\npaths:\n  /getSchema:\n    get:\n      operationId: getSchema\n      parameters:\n      - name: schemaId\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/main/resources/registry.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\ndemo-zeroconfig-registry-client:\n  - id: \"001\"\n    version: \"0.0.2\"\n    appid: demo-zeroconfig-registry\n    schemaIds:\n      - ClientServerEndpoint\n      - SchemaDiscoveryEndpoint\n      - GovernanceEndpoint\n    instances:\n      - endpoints:\n          - rest://localhost:8082\ndemo-zeroconfig-registry-edge:\n  - id: \"002\"\n    version: \"0.0.2\"\n    appid: demo-zeroconfig-registry\n    schemaIds:\n      - ClientServerEndpoint\n      - SchemaDiscoveryEndpoint\n    instances:\n      - endpoints:\n          - rest://localhost:8888\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/src/test/java/org/apache/servicecomb/demo/zeroconfig/tests/ZeroConfigRegistryIT.java",
    "content": "\n/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.demo.zeroconfig.tests;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class ZeroConfigRegistryIT {\n  @BeforeEach\n  public void setUp() throws Exception {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    Application.main(new String[0]);\n\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/demo-zeroconfig-registry/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-zeroconfig-registry</artifactId>\n  <name>Java Chassis::Demo::ZeroConfig Registry</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-zeroconfig-registry-server</module>\n    <module>demo-zeroconfig-registry-edge</module>\n    <module>demo-zeroconfig-registry-client</module>\n    <module>demo-zeroconfig-registry-tests</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "demo/demo-zookeeper/README.md",
    "content": "# Notice\n\nThis integration tests is designed for Zookeeper registry and configuration. And extra test cases include:\n\n* Test cases related to SpringMVC annotations that demo-springmvc can not cover.\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zookeeper</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>zookeeper-consumer</artifactId>\n  <name>Java Chassis::Demo::Zookeeper::CONSUMER</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zookeeper</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.ServerWebSocket;\nimport io.vertx.core.http.WebSocket;\n\n@RestSchema(schemaId = \"ClientWebsocketController\")\n@RequestMapping(path = \"/ws\")\npublic class ClientWebsocketController {\n  interface ProviderService {\n    WebSocket websocket();\n  }\n\n  @RpcReference(schemaId = \"WebsocketController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  @PostMapping(\"/websocket\")\n  @Transport(name = CoreConst.WEBSOCKET)\n  public void websocket(ServerWebSocket serverWebsocket) {\n    WebSocket providerWebSocket = providerService.websocket();\n    providerWebSocket.closeHandler(v -> serverWebsocket.close());\n    providerWebSocket.textMessageHandler(m -> {\n      System.out.println(\"send message \" + m);\n      serverWebsocket.writeTextMessage(m);\n    });\n    serverWebsocket.textMessageHandler(m -> {\n      System.out.println(\"receive message \" + m);\n      providerWebSocket.writeTextMessage(m);\n    });\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ConsumerApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsumerApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ConsumerController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerController {\n  @RpcReference(schemaId = \"ProviderController\", microserviceName = \"provider\")\n  private ProviderService providerService;\n\n  // consumer service which delegate the implementation to provider service.\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return providerService.sayHello(name);\n  }\n\n  @GetMapping(\"/getConfig\")\n  public String getConfig(@RequestParam(\"key\") String key) {\n    return providerService.getConfig(key);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"ConsumerHeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)\npublic class ConsumerHeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {\n  @RpcReference(microserviceName = \"provider\", schemaId = \"HeaderParamWithListSchema\")\n  private IHeaderParamWithListSchemaSpringMvc provider;\n\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return provider.headerListDefault(headerList);\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return provider.headerListCSV(headerList);\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return provider.headerListMULTI(headerList);\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return provider.headerListSSV(headerList);\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return provider.headerListPIPES(headerList);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\npublic class ConsumerReactiveStreamController {\n  interface ProviderReactiveStreamController {\n    Publisher<String> sseString();\n\n    Publisher<Model> sseModel();\n  }\n\n  @RpcReference(microserviceName = \"provider\", schemaId = \"ReactiveStreamController\")\n  ProviderReactiveStreamController controller;\n\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  @Transport(name = CoreConst.RESTFUL)\n  public Publisher<String> sseString() {\n    return controller.sseString();\n  }\n\n  @GetMapping(\"/sseModel\")\n  @Transport(name = CoreConst.RESTFUL)\n  public Publisher<Model> sseModel() {\n    return controller.sseModel();\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface ProviderService {\n  String sayHello(String name);\n\n  String getConfig(String key);\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-zookeeper\n    version: 0.0.1\n    name: consumer\n    properties:\n      group: red\n  registry:\n    zk:\n      enabled: true\n      connectString: 127.0.0.1:2181\n\n  rest:\n    address: 0.0.0.0:9092?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  highway:\n    address: 0.0.0.0:7092\n"
  },
  {
    "path": "demo/demo-zookeeper/consumer/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-zookeeper/gateway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zookeeper</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>zookeeper-gateway</artifactId>\n  <name>Java Chassis::Demo::Zookeeper::GATEWAY</name>\n  <packaging>jar</packaging>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zookeeper</artifactId>\n    </dependency>\n  </dependencies>\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zookeeper/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class GatewayApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/gateway/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-zookeeper\n    version: 0.0.1\n    name: gateway\n  registry:\n    zk:\n      enabled: true\n      connectString: 127.0.0.1:2181\n\n  rest:\n    address: 0.0.0.0:9090?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  http:\n    dispatcher:\n      edge:\n        default:\n          enabled: false\n        url:\n          enabled: true\n          pattern: /(.*)\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n        websocket:\n          mappings:\n            consumer:\n              prefixSegmentCount: 0\n              path: \"/ws/.*\"\n              microserviceName: consumer\n              versionRule: 0.0.0+\n"
  },
  {
    "path": "demo/demo-zookeeper/gateway/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-zookeeper/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>demo-zookeeper</artifactId>\n  <name>Java Chassis::Demo::Zookeeper</name>\n  <packaging>pom</packaging>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n    </dependency>\n  </dependencies>\n\n  <modules>\n    <module>provider</module>\n    <module>consumer</module>\n    <module>gateway</module>\n    <module>test-client</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zookeeper</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>zookeeper-provider</artifactId>\n  <name>Java Chassis::Demo::Zookeeper::PROVIDER</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zookeeper</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-zookeeper</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.reactivex.rxjava3</groupId>\n      <artifactId>rxjava</artifactId>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>${project.artifactId}:${project.version}</name>\n                    <alias>${project.artifactId}</alias>\n                    <build>\n                      <from>eclipse-temurin:17-jre-jammy</from>\n                      <ports>\n                        <port>7070</port>\n                        <port>8080</port>\n                      </ports>\n                      <assembly>\n                        <mode>tar</mode>\n                        <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>\n                      </assembly>\n                      <entryPoint>\n                        <shell>java -Xmx128m $JAVA_OPTS -jar $JAR_PATH</shell>\n                      </entryPoint>\n                    </build>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>build</id>\n                  <phase>package</phase>\n                  <goals>\n                    <goal>build</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = \"HeaderParamWithListSchema\", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class)\npublic class HeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc {\n  @Override\n  public String headerListDefault(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListCSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListMULTI(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListSSV(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n\n  @Override\n  public String headerListPIPES(List<String> headerList) {\n    return headerList == null ? \"null\" : headerList.size() + \":\" + headerList;\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/ProviderApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class ProviderApplication {\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ProviderApplication.class).run(args);\n    } catch (Exception e) {\n      e.printStackTrace();\n    }\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.curator.framework.CuratorFramework;\nimport org.apache.curator.framework.CuratorFrameworkFactory;\nimport org.apache.curator.retry.ExponentialBackoffRetry;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.zookeeper.ZookeeperClient;\nimport org.apache.servicecomb.config.zookeeper.ZookeeperConfig;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\n\n@RestSchema(schemaId = \"ProviderController\")\n@RequestMapping(path = \"/\")\npublic class ProviderController implements InitializingBean {\n  private Environment environment;\n\n  private ZookeeperConfig zookeeperConfig;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n    this.zookeeperConfig = new ZookeeperConfig(environment);\n  }\n\n  // a very simple service to echo the request parameter\n  @GetMapping(\"/sayHello\")\n  public String sayHello(@RequestParam(\"name\") String name) {\n    return \"Hello \" + name;\n  }\n\n  @GetMapping(\"/getConfig\")\n  public String getConfig(@RequestParam(\"key\") String key) {\n    return environment.getProperty(key);\n  }\n\n  @Override\n  public void afterPropertiesSet() throws Exception {\n    CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConfig.getConnectString(),\n        zookeeperConfig.getSessionTimeoutMillis(), zookeeperConfig.getConnectionTimeoutMillis(),\n        new ExponentialBackoffRetry(1000, 3));\n    client.start();\n    client.blockUntilConnected(10, TimeUnit.SECONDS);\n\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = ZookeeperConfig.ZOOKEEPER_DEFAULT_ENVIRONMENT;\n    }\n\n    String path = String.format(ZookeeperClient.PATH_ENVIRONMENT, env);\n    if (client.checkExists().forPath(path + \"/config.properties\") != null) {\n      client.delete().forPath(path + \"/config.properties\");\n    }\n    client.create().creatingParentsIfNeeded().\n        forPath(path + \"/config.properties\", \"key1=1\\nkey2=2\".getBytes(StandardCharsets.UTF_8));\n\n    path = String.format(ZookeeperClient.PATH_VERSION, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment));\n    if (client.checkExists().forPath(path + \"/config.properties\") != null) {\n      client.delete().forPath(path + \"/config.properties\");\n    }\n    client.create().creatingParentsIfNeeded().\n        forPath(path + \"/config.properties\", \"key2=3\\nkey3=4\".getBytes(StandardCharsets.UTF_8));\n\n    path = String.format(ZookeeperClient.PATH_TAG, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment),\n        zookeeperConfig.getInstanceTag());\n    if (client.checkExists().forPath(path + \"/config.properties\") != null) {\n      client.delete().forPath(path + \"/config.properties\");\n    }\n    client.create().creatingParentsIfNeeded().\n        forPath(path + \"/config.properties\", \"key2=3\\nkey3=5\".getBytes(StandardCharsets.UTF_8));\n\n    client.close();\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.samples;\n\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.reactivestreams.Publisher;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.reactivex.rxjava3.core.Flowable;\n\n@RestSchema(schemaId = \"ReactiveStreamController\")\n@RequestMapping(path = \"/\")\n@Transport(name = CoreConst.RESTFUL)\npublic class ReactiveStreamController {\n  public static class Model {\n    private String name;\n\n    private int age;\n\n    public Model() {\n\n    }\n\n    public Model(String name, int age) {\n      this.name = name;\n      this.age = age;\n    }\n\n    public int getAge() {\n      return age;\n    }\n\n    public Model setAge(int age) {\n      this.age = age;\n      return this;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public Model setName(String name) {\n      this.name = name;\n      return this;\n    }\n  }\n\n  @GetMapping(\"/sseString\")\n  public Publisher<String> sseString() {\n    return Flowable.fromArray(\"a\", \"b\", \"c\");\n  }\n\n  @GetMapping(\"/sseModel\")\n  public Publisher<Model> sseModel() {\n    return Flowable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)\n        .map(item -> new Model(\"jack\", item.intValue()));\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.ServerWebSocket;\n\n@RestSchema(schemaId = \"WebsocketController\")\n@RequestMapping(path = \"/ws\")\npublic class WebsocketController {\n  @PostMapping(\"/websocket\")\n  @Transport(name = CoreConst.WEBSOCKET)\n  public void websocket(ServerWebSocket serverWebsocket) {\n    AtomicInteger receiveCount = new AtomicInteger(0);\n    CountDownLatch startSend = new CountDownLatch(1);\n    serverWebsocket.textMessageHandler(s -> {\n      if (\"start\".equals(s)) {\n        startSend.countDown();\n        serverWebsocket.writeTextMessage(\"started\");\n        return;\n      }\n      receiveCount.getAndIncrement();\n    });\n    serverWebsocket.closeHandler((v) -> System.out.println(\"closed\"));\n\n    new Thread(() -> {\n      try {\n        startSend.await(30, TimeUnit.SECONDS);\n      } catch (InterruptedException e) {\n        e.printStackTrace();\n      }\n\n      serverWebsocket.writeTextMessage(\"hello\");\n\n      for (int i = 0; i < 5; i++) {\n        serverWebsocket.writeTextMessage(\"hello \" + i);\n        try {\n          Thread.sleep(500);\n        } catch (InterruptedException e) {\n          e.printStackTrace();\n        }\n      }\n      serverWebsocket.writeTextMessage(\"total \" + receiveCount.get());\n      serverWebsocket.close();\n    }).start();\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# spring boot configurations\nservicecomb:\n  service:\n    application: demo-zookeeper\n    version: 0.0.1\n    name: provider\n    properties:\n      group: green\n  registry:\n    zk:\n      connectString: 127.0.0.1:2181\n  config:\n    zk:\n      connectString: 127.0.0.1:2181\n      instance-tag: config-demo\n\n  rest:\n    address: 0.0.0.0:9094?websocketEnabled=true\n    server:\n      websocket-prefix: /ws\n\n  highway:\n    address: 0.0.0.0:7094\n\n  cors:\n    enabled: true\n    origin: \"*\"\n    allowCredentials: false\n    allowedMethod: \"*\"\n    maxAge: 3600\n"
  },
  {
    "path": "demo/demo-zookeeper/provider/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb.demo</groupId>\n    <artifactId>demo-zookeeper</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>zookeeper-test-client</artifactId>\n  <name>Java Chassis::Demo::Zookeeper::TEST-CLIENT</name>\n  <packaging>jar</packaging>\n\n  <properties>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb.demo</groupId>\n      <artifactId>demo-schema</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <images>\n                  <image>\n                    <name>zookeeper:3.8.3</name>\n                    <alias>zookeeper</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <wait>\n                        <log>binding to port</log>\n                        <tcp>\n                          <ports>\n                            <port>2181</port>\n                          </ports>\n                        </tcp>\n                        <time>60000</time>\n                      </wait>\n                      <ports>\n                        <port>zookeeper.port:2181</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>zookeeper-provider:${project.version}</name>\n                    <alias>zookeeper-provider</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.zk.connectString=zookeeper:2181 -Dservicecomb.config.zk.connectString=zookeeper:2181\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/zookeeper-provider-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>zookeeper:zookeeper</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9094</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9094:9094</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>zookeeper-consumer:${project.version}</name>\n                    <alias>zookeeper-consumer</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.zk.connectString=zookeeper:2181\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/zookeeper-consumer-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>zookeeper:zookeeper</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9092</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9092:9092</port>\n                      </ports>\n                    </run>\n                  </image>\n                  <image>\n                    <name>zookeeper-gateway:${project.version}</name>\n                    <alias>zookeeper-gateway</alias>\n                    <run>\n                      <namingStrategy>alias</namingStrategy>\n                      <env>\n                        <JAVA_OPTS>\n                          -Dservicecomb.registry.zk.connectString=zookeeper:2181\n                        </JAVA_OPTS>\n                        <JAR_PATH>/maven/maven/zookeeper-gateway-${project.version}.jar</JAR_PATH>\n                      </env>\n                      <links>\n                        <link>zookeeper:zookeeper</link>\n                      </links>\n                      <wait>\n                        <log>ServiceComb is ready</log>\n                        <tcp>\n                          <ports>\n                            <port>9090</port>\n                          </ports>\n                        </tcp>\n                        <time>120000</time>\n                      </wait>\n                      <ports>\n                        <port>9090:9090</port>\n                      </ports>\n                    </run>\n                  </image>\n                </images>\n              </configuration>\n              <executions>\n                <execution>\n                  <id>start</id>\n                  <phase>pre-integration-test</phase>\n                  <goals>\n                    <goal>start</goal>\n                  </goals>\n                </execution>\n                <execution>\n                  <id>stop</id>\n                  <phase>post-integration-test</phase>\n                  <goals>\n                    <goal>stop</goal>\n                  </goals>\n                </execution>\n              </executions>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n\n        <plugins>\n          <plugin>\n            <groupId>io.fabric8</groupId>\n            <artifactId>docker-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\npublic interface Config {\n  String GATEWAY_URL = \"http://localhost:9090\";\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HeaderParamWithListSchemaIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHeaderListDefault();\n    testHeaderListMulti();\n    testHeaderListCSV();\n    testHeaderListSSV();\n    testHeaderListPipes();\n  }\n\n  // default to multi\n  private void testHeaderListDefault() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListDefault\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListPipes() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a|b|c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListPIPES\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListSSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a b c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListSSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListCSV() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a,b,c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n\n    headers.add(\"headerList\", \"a, b, c\");\n    entity = new HttpEntity<>(headers);\n    result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListCSV\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n\n  private void testHeaderListMulti() {\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"headerList\", \"a\");\n    headers.add(\"headerList\", \"b\");\n    headers.add(\"headerList\", \"c\");\n    HttpEntity<Void> entity = new HttpEntity<>(headers);\n    String result = template\n        .exchange(Config.GATEWAY_URL + \"/headerList/headerListMULTI\", HttpMethod.GET, entity, String.class).getBody();\n    TestMgr.check(\"3:[a, b, c]\", result);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.MultiValueMap;\nimport org.springframework.web.client.RestOperations;\nimport org.springframework.web.client.RestTemplate;\n\n@Component\npublic class HelloWorldIT implements CategorizedTestCase {\n  RestOperations template = new RestTemplate();\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testHelloWorld();\n    testGetConfig();\n  }\n\n  private void testGetConfig() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key1\", String.class);\n    TestMgr.check(\"1\", result);\n    result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key2\", String.class);\n    TestMgr.check(\"3\", result);\n    result = template\n        .getForObject(Config.GATEWAY_URL + \"/getConfig?key=key3\", String.class);\n    TestMgr.check(\"5\", result);\n  }\n\n  private void testHelloWorld() {\n    String result = template\n        .getForObject(Config.GATEWAY_URL + \"/sayHello?name=World\", String.class);\n    TestMgr.check(\"Hello World\", result);\n\n    // test trace id added\n    MultiValueMap<String, String> headers = new HttpHeaders();\n    headers.add(\"X-B3-TraceId\", \"81de2eb7691c2bbb\");\n    HttpEntity<Object> entity = new HttpEntity(headers);\n    ResponseEntity<String> response =\n        template.exchange(Config.GATEWAY_URL + \"/sayHello?name=World\", HttpMethod.GET, entity, String.class);\n    TestMgr.check(1, response.getHeaders().get(\"X-B3-TraceId\").size());\n    TestMgr.check(\"81de2eb7691c2bbb\", response.getHeaders().getFirst(\"X-B3-TraceId\"));\n    TestMgr.check(\"Hello World\", response.getBody());\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/ReactiveStreamIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient.Model;\nimport org.reactivestreams.Publisher;\nimport org.reactivestreams.Subscriber;\nimport org.reactivestreams.Subscription;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ReactiveStreamIT implements CategorizedTestCase {\n  @Autowired\n  @Qualifier(\"reactiveStreamProvider\")\n  ReactiveStreamClient reactiveStreamProvider;\n\n  @Autowired\n  @Qualifier(\"reactiveStreamGateway\")\n  ReactiveStreamClient reactiveStreamGateway;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    testSseString(reactiveStreamProvider);\n    testSseModel(reactiveStreamProvider);\n    testSseString(reactiveStreamGateway);\n    testSseModel(reactiveStreamGateway);\n  }\n\n  private void testSseModel(ReactiveStreamClient client) throws Exception {\n    Publisher<Model> result = client.sseModel();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(Model s) {\n        buffer.append(s.getName()).append(s.getAge());\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"jack0jack1jack2jack3jack4\", buffer.toString());\n  }\n\n  private void testSseString(ReactiveStreamClient client) throws Exception {\n    Publisher<String> result = client.sseString();\n    StringBuilder buffer = new StringBuilder();\n    CountDownLatch countDownLatch = new CountDownLatch(1);\n    result.subscribe(new Subscriber<>() {\n      Subscription subscription;\n\n      @Override\n      public void onSubscribe(Subscription s) {\n        subscription = s;\n        subscription.request(1);\n      }\n\n      @Override\n      public void onNext(String s) {\n        buffer.append(s);\n        subscription.request(1);\n      }\n\n      @Override\n      public void onError(Throwable t) {\n        subscription.cancel();\n        countDownLatch.countDown();\n      }\n\n      @Override\n      public void onComplete() {\n        countDownLatch.countDown();\n      }\n    });\n    countDownLatch.await(10, TimeUnit.SECONDS);\n    TestMgr.check(\"abc\", buffer.toString());\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.CategorizedTestCaseRunner;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.WebApplicationType;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.builder.SpringApplicationBuilder;\n\n@SpringBootApplication\npublic class TestClientApplication {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class);\n\n  public static void main(String[] args) throws Exception {\n    try {\n      new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args);\n\n      run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n  }\n\n  public static void run() throws Exception {\n    CategorizedTestCaseRunner.runCategorizedTestCase(\"consumer\");\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/ThirdSvcConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.annotation.Transport;\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.reactivestreams.Publisher;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.vertx.core.http.WebSocket;\n\n@Configuration\npublic class ThirdSvcConfiguration {\n  @RequestMapping(path = \"/ws\")\n  public interface WebsocketClient {\n    @PostMapping(\"/websocket\")\n    @Transport(name = CoreConst.WEBSOCKET)\n    WebSocket websocket();\n  }\n\n  @RequestMapping(path = \"/\")\n  public interface ReactiveStreamClient {\n    class Model {\n      private String name;\n\n      private int age;\n\n      public Model() {\n\n      }\n\n      public Model(String name, int age) {\n        this.name = name;\n        this.age = age;\n      }\n\n      public int getAge() {\n        return age;\n      }\n\n      public Model setAge(int age) {\n        this.age = age;\n        return this;\n      }\n\n      public String getName() {\n        return name;\n      }\n\n      public Model setName(String name) {\n        this.name = name;\n        return this;\n      }\n    }\n\n    @GetMapping(\"/sseString\")\n    Publisher<String> sseString();\n\n    @GetMapping(\"/sseModel\")\n    Publisher<Model> sseModel();\n  }\n\n  @Bean\n  public RegistryBean providerServiceBean() {\n    return new RegistryBean()\n        .addSchemaInterface(\"ReactiveStreamController\", ReactiveStreamClient.class)\n        .setAppId(\"demo-zookeeper\")\n        .setServiceName(\"provider\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(\n            new Instance().setEndpoints(List.of(\"rest://localhost:9094\")))));\n  }\n\n  @Bean\n  public RegistryBean gatewayServiceBean() {\n    return new RegistryBean()\n        .addSchemaInterface(\"ReactiveStreamController\", ReactiveStreamClient.class)\n        .addSchemaInterface(\"WebsocketController\", WebsocketClient.class)\n        .setAppId(\"demo-zookeeper\")\n        .setServiceName(\"gateway\")\n        .setVersion(\"0.0.1\")\n        .setInstances(new Instances().setInstances(List.of(\n            new Instance().setEndpoints(List.of(\"rest://localhost:9090?websocketEnabled=true\")))));\n  }\n\n  @Bean(\"reactiveStreamProvider\")\n  public ReactiveStreamClient reactiveStreamProvider() {\n    return Invoker.createProxy(\"provider\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n\n  @Bean(\"reactiveStreamGateway\")\n  public ReactiveStreamClient reactiveStreamGateway() {\n    return Invoker.createProxy(\"gateway\", \"ReactiveStreamController\", ReactiveStreamClient.class);\n  }\n\n  @Bean\n  public WebsocketClient gatewayWebsocketClient() {\n    return Invoker.createProxy(\"gateway\", \"WebsocketController\", WebsocketClient.class);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.demo.CategorizedTestCase;\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.apache.servicecomb.samples.ThirdSvcConfiguration.WebsocketClient;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\nimport io.vertx.core.http.WebSocket;\n\n@Component\npublic class WebsocketIT implements CategorizedTestCase {\n  @Autowired\n  private WebsocketClient websocketClient;\n\n  @Override\n  public void testRestTransport() throws Exception {\n    StringBuffer sb = new StringBuffer();\n    AtomicBoolean closed = new AtomicBoolean(false);\n    CountDownLatch latchStarted = new CountDownLatch(1);\n    CountDownLatch latch = new CountDownLatch(1);\n\n    WebSocket webSocket = websocketClient.websocket();\n    webSocket.textMessageHandler(s -> {\n      if (\"started\".equals(s)) {\n        latchStarted.countDown();\n        return;\n      }\n      sb.append(s);\n      sb.append(\" \");\n      webSocket.writeTextMessage(s);\n    });\n    webSocket.closeHandler(v -> {\n      closed.set(true);\n      latch.countDown();\n    });\n\n    webSocket.writeTextMessage(\"start\");\n    int i = 0;\n    for (; i < 10; i++) {\n      if (!latchStarted.await(3, TimeUnit.SECONDS)) {\n        webSocket.writeTextMessage(\"start\");\n        continue;\n      }\n      break;\n    }\n    TestMgr.check(i < 10, true);\n    latch.await(30, TimeUnit.SECONDS);\n    TestMgr.check(sb.toString(), \"hello hello 0 hello 1 hello 2 hello 3 hello 4 total 6 \");\n    TestMgr.check(closed.get(), true);\n  }\n}\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/resources/application.yml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb:\n  service:\n    application: demo-zookeeper\n    name: test-client\n    version: 0.0.1\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/main/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<!--this is sample configuration, please modify as your wish-->\n<configuration>\n  <Appenders>\n    <!-- can use MarkerFilter to separate logs with trace id\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMatch=\"DENY\" onMismatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n    <Console name=\"Console-Tracing\" target=\"SYSTEM_OUT\">\n      <MarkerFilter marker=\"SERVICECOMB_MARKER\" onMismatch=\"DENY\" onMatch=\"ACCEPT\"/>\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n    -->\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L][%X{SERVICECOMB_TRACE_ID}] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"info\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</configuration>\n"
  },
  {
    "path": "demo/demo-zookeeper/test-client/src/test/java/org/apache/servicecomb/samples/ZookeeperIT.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.samples;\n\nimport org.apache.servicecomb.demo.TestMgr;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.junit.jupiter.SpringExtension;\n\n@ExtendWith(SpringExtension.class)\n@SpringBootTest(classes = TestClientApplication.class)\npublic class ZookeeperIT {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperIT.class);\n\n  @BeforeEach\n  public void setUp() {\n    TestMgr.errors().clear();\n  }\n\n  @Test\n  public void clientGetsNoError() throws Exception {\n    try {\n      TestClientApplication.run();\n    } catch (Exception e) {\n      TestMgr.failed(\"test case run failed\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n      LOGGER.error(\"\", e);\n      LOGGER.error(\"-------------- test failed -------------\");\n    }\n    TestMgr.summary();\n    Assertions.assertTrue(TestMgr.errors().isEmpty());\n  }\n}\n"
  },
  {
    "path": "demo/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <groupId>org.apache.servicecomb.demo</groupId>\n  <artifactId>demo-parent</artifactId>\n  <name>Java Chassis::Demo</name>\n\n  <properties>\n    <demo.main></demo.main>\n  </properties>\n\n  <packaging>pom</packaging>\n  <modules>\n    <module>demo-schema</module>\n    <module>demo-pojo</module>\n    <module>demo-filter</module>\n    <module>demo-jaxrs</module>\n    <module>demo-springmvc</module>\n    <module>demo-crossapp</module>\n    <module>demo-register-url-prefix</module>\n    <module>demo-local-registry</module>\n    <module>demo-multi-registries</module>\n    <module>demo-zeroconfig-registry</module>\n    <module>demo-spring-boot-transport</module>\n    <module>demo-edge</module>\n    <module>demo-multiple</module>\n    <module>demo-multi-service-center</module>\n    <module>demo-cse-v1</module>\n    <module>demo-cse-v2</module>\n    <module>demo-nacos</module>\n    <!-- TODO: etcd for vert.x 5.x is not released, after release will support it-->\n    <!-- <module>demo-etcd</module> -->\n    <module>demo-zookeeper</module>\n    <module>demo-consul</module>\n  </modules>\n\n  <dependencyManagement>\n    <dependencies>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>demo-schema</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>all-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>pojo-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>jaxrs-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>springmvc-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>crossapp-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>multiple-server</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>multiple-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>pojo-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>jaxrs-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>springmvc-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb.demo</groupId>\n        <artifactId>crossapp-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-test-scaffolding</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter</artifactId>\n      <scope>compile</scope>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <groupId>org.commonjava.maven.plugins</groupId>\n          <artifactId>directory-maven-plugin</artifactId>\n          <version>1.0</version>\n        </plugin>\n        <plugin>\n          <artifactId>maven-deploy-plugin</artifactId>\n          <configuration>\n            <skip>true</skip>\n          </configuration>\n        </plugin>\n        <plugin>\n          <artifactId>maven-install-plugin</artifactId>\n          <configuration>\n            <skip>false</skip>\n          </configuration>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-jar-plugin</artifactId>\n          <executions>\n            <execution>\n              <id>assembly</id>\n              <phase>package</phase>\n            </execution>\n          </executions>\n          <configuration>\n            <archive>\n              <manifest>\n                <addClasspath>true</addClasspath>\n                <classpathPrefix>lib/</classpathPrefix>\n                <mainClass>${demo.main}</mainClass>\n              </manifest>\n            </archive>\n          </configuration>\n        </plugin>\n        <plugin>\n          <groupId>org.commonjava.maven.plugins</groupId>\n          <artifactId>directory-maven-plugin</artifactId>\n          <executions>\n            <execution>\n              <id>directories</id>\n              <goals>\n                <goal>directory-of</goal>\n              </goals>\n              <phase>initialize</phase>\n              <configuration>\n                <property>root.basedir</property>\n                <project>\n                  <groupId>org.apache.servicecomb.demo</groupId>\n                  <artifactId>demo-parent</artifactId>\n                </project>\n              </configuration>\n            </execution>\n          </executions>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n    <plugins>\n      <plugin>\n        <groupId>org.commonjava.maven.plugins</groupId>\n        <artifactId>directory-maven-plugin</artifactId>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>docker</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-failsafe-plugin</artifactId>\n            <version>${maven-failsafe-plugin.version}</version>\n            <configuration>\n              <argLine>${jacoco.failsafe.argLine}</argLine>\n            </configuration>\n            <executions>\n              <execution>\n                <goals>\n                  <goal>integration-test</goal>\n                  <goal>verify</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "dependencies/bom/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-dependencies-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>java-chassis-bom</artifactId>\n  <name>Java Chassis::Bom</name>\n  <packaging>pom</packaging>\n\n  <dependencyManagement>\n    <dependencies>\n      <!-- Service Comb -->\n      <!-- sort by project directory name, easy to check if the module is missed -->\n      <!-- Service Comb : clients -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-center-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-clients-common</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-kie-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>dashboard-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>http-client-common</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>service-center-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- Service Comb : common -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>common-access-log</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>common-protobuf</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>common-rest</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- Service Comb : core -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>java-chassis-core</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- ServiceComb： dynamic-config -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-apollo</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-cc</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-kie</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-nacos</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-zookeeper</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\t  <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-consul</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- ServiceComb： edge -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>edge-core</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb： foundations -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-common</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-config</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-metrics</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-protobuf</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-registry</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-spi</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-ssl</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-test-scaffolding</artifactId>\n        <version>${project.version}</version>\n        <scope>test</scope>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>foundation-vertx</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- ServiceComb：governance -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>servicecomb-governance</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- ServiceComb： handlers -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-fault-injection</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-flowcontrol-qps</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-governance</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-loadbalance</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-publickey-auth</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-router</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>handler-tracing-zipkin</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\n      <!-- ServiceComb： metrics -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>metrics-core</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>metrics-prometheus</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb： providers -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>provider-jaxrs</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>provider-pojo</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>provider-rest-common</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>provider-springmvc</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb： service registry -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-lightweight</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-local</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-service-center</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-zero-config</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-nacos</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-zookeeper</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-etcd</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>config-etcd</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n\t  <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>registry-consul</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb： solutions -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>solution-basic</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb: spring boot -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb ServiceStage extension -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>servicestage</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>dashboard</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>darklaunch</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb: swagger -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-generator-core</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-generator-jaxrs</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-generator-spring-data</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-generator-springmvc</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-invocation-core</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-invocation-jaxrs</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-invocation-springmvc</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>swagger-invocation-validator</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb: tracing -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>tracing-common</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>tracing-zipkin</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <!-- ServiceComb: transports -->\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>transport-common</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>transport-highway</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>transport-rest-client</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>transport-rest-servlet</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>transport-rest-vertx</artifactId>\n        <version>${project.version}</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n</project>\n"
  },
  {
    "path": "dependencies/default/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-dependencies-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>java-chassis-dependencies</artifactId>\n  <name>Java Chassis::Dependencies::Default</name>\n  <packaging>pom</packaging>\n\n  <properties>\n    <!-- Dependency versions: sort by alphabetic order -->\n    <activation.version>1.2.2</activation.version>\n    <assertj.version>3.27.7</assertj.version>\n    <awaitility.version>4.3.0</awaitility.version>\n    <brave.version>6.3.0</brave.version>\n    <commons-beanutils.version>1.11.0</commons-beanutils.version>\n    <commons-io.version>2.21.0</commons-io.version>\n    <commons-lang.version>2.6</commons-lang.version>\n    <commons-lang3.version>3.20.0</commons-lang3.version>\n    <commons-logging.version>1.3.5</commons-logging.version>\n    <commons-text.version>1.15.0</commons-text.version>\n    <curator.version>5.9.0</curator.version>\n    <failureaccess.version>1.0.3</failureaccess.version>\n    <findbugs-jsr305.version>3.0.2</findbugs-jsr305.version>\n    <governator-annotations.version>1.17.12</governator-annotations.version>\n    <governator-api.version>1.17.13</governator-api.version>\n    <guava.version>33.5.0-jre</guava.version>\n    <guice.version>5.1.0</guice.version>\n    <hamcrest.version>1.3</hamcrest.version>\n    <hdr-histogram.version>2.2.2</hdr-histogram.version>\n    <hibernate-validator.version>9.1.0.Final</hibernate-validator.version>\n    <httpcomponents.version>4.5.14</httpcomponents.version>\n    <hystrix.version>1.5.18</hystrix.version>\n    <jackson.version>2.20.1</jackson.version>\n    <java-websocket.version>1.6.0</java-websocket.version>\n    <javax-annotation.version>1.3.2</javax-annotation.version>\n    <javax-inject.version>1</javax-inject.version>\n    <javax-resource.version>1.5</javax-resource.version>\n    <jersey.version>4.0.2</jersey.version>\n    <jmockit.version>1.34</jmockit.version>\n    <junit.version>4.13.2</junit.version>\n    <junit5.version>5.13.4</junit5.version>\n    <log4j.version>1.2.17</log4j.version>\n    <log4j2.version>2.25.3</log4j2.version>\n    <maven-model.version>3.9.12</maven-model.version>\n    <micrometer.version>1.16.4</micrometer.version>\n    <mockito.version>5.21.0</mockito.version>\n    <mockito-inline.version>5.2.0</mockito-inline.version>\n    <mock-server.version>5.15.0</mock-server.version>\n    <nacos-client.version>3.1.1</nacos-client.version>\n    <netflix-commons.version>0.3.0</netflix-commons.version>\n    <prometheus.version>0.16.0</prometheus.version>\n    <protobuf.version>3.23.4</protobuf.version>\n    <protostuff.version>1.8.0</protostuff.version>\n    <protostuff-parser.version>2.2.27</protostuff-parser.version>\n    <reactive-streams.version>1.0.4</reactive-streams.version>\n    <resilience4j.versioin>1.7.0</resilience4j.versioin>\n    <ribbon.version>2.7.18</ribbon.version>\n    <rxjava.version>3.1.12</rxjava.version>\n    <seanyinx.version>1.0.0</seanyinx.version>\n    <servo.version>0.13.2</servo.version>\n    <servlet-api.version>6.0.0</servlet-api.version>\n    <slf4j.version>1.7.36</slf4j.version>\n    <snakeyaml.version>2.5</snakeyaml.version>\n    <swagger.version>2.2.41</swagger.version>\n    <vertx.version>5.0.8</vertx.version>\n    <zipkin.version>3.5.1</zipkin.version>\n    <zipkin-reporter.version>3.4.0</zipkin-reporter.version>\n    <jetcd-core.version>0.8.6</jetcd-core.version>\n    <consul-client.version>1.8.0</consul-client.version>\n    <!-- Base dir of main -->\n    <main.basedir>${basedir}/../..</main.basedir>\n  </properties>\n\n  <dependencyManagement>\n    <dependencies>\n      <!-- Third Party -->\n      <dependency>\n        <groupId>com.fasterxml.jackson</groupId>\n        <artifactId>jackson-bom</artifactId>\n        <version>${jackson.version}</version>\n        <scope>import</scope>\n        <type>pom</type>\n      </dependency>\n\n      <dependency>\n        <groupId>org.mockito</groupId>\n        <artifactId>mockito-bom</artifactId>\n        <version>${mockito.version}</version>\n        <scope>import</scope>\n        <type>pom</type>\n      </dependency>\n      <dependency>\n        <groupId>org.mockito</groupId>\n        <artifactId>mockito-inline</artifactId>\n        <version>${mockito-inline.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>com.github.seanyinx</groupId>\n        <artifactId>unit-scaffolding</artifactId>\n        <version>${seanyinx.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.curator</groupId>\n        <artifactId>curator-x-discovery</artifactId>\n        <version>${curator.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.curator</groupId>\n        <artifactId>curator-framework</artifactId>\n        <version>${curator.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.curator</groupId>\n        <artifactId>curator-recipes</artifactId>\n        <version>${curator.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>com.google.code.findbugs</groupId>\n        <artifactId>jsr305</artifactId>\n        <version>${findbugs-jsr305.version}</version>\n        <scope>provided</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>guava</artifactId>\n        <version>${guava.version}</version>\n        <exclusions>\n          <exclusion>\n            <groupId>*</groupId>\n            <artifactId>*</artifactId>\n          </exclusion>\n        </exclusions>\n      </dependency>\n      <dependency>\n        <groupId>com.google.guava</groupId>\n        <artifactId>failureaccess</artifactId>\n        <version>${failureaccess.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>com.google.inject</groupId>\n        <artifactId>guice</artifactId>\n        <version>${guice.version}</version>\n        <exclusions>\n          <exclusion>\n            <groupId>aopalliance</groupId>\n            <artifactId>aopalliance</artifactId>\n          </exclusion>\n        </exclusions>\n      </dependency>\n      <dependency>\n        <groupId>com.google.inject.extensions</groupId>\n        <artifactId>guice-assistedinject</artifactId>\n        <version>${guice.version}</version>\n      </dependency>\n\n      <!-- will not update anymore, only for testing -->\n      <dependency>\n        <groupId>com.google.protobuf</groupId>\n        <artifactId>protobuf-java</artifactId>\n        <version>${protobuf.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>commons-beanutils</groupId>\n        <artifactId>commons-beanutils</artifactId>\n        <version>${commons-beanutils.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>commons-io</groupId>\n        <artifactId>commons-io</artifactId>\n        <version>${commons-io.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>commons-lang</groupId>\n        <artifactId>commons-lang</artifactId>\n        <version>${commons-lang.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>commons-logging</groupId>\n        <artifactId>commons-logging</artifactId>\n        <version>${commons-logging.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.maven</groupId>\n        <artifactId>maven-model</artifactId>\n        <version>${maven-model.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.micrometer</groupId>\n        <artifactId>micrometer-bom</artifactId>\n        <version>${micrometer.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n      <dependency>\n        <groupId>io.prometheus</groupId>\n        <artifactId>simpleclient_bom</artifactId>\n        <version>${prometheus.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>io.protostuff</groupId>\n        <artifactId>protostuff-core</artifactId>\n        <version>${protostuff.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>io.protostuff</groupId>\n        <artifactId>protostuff-parser</artifactId>\n        <version>${protostuff-parser.version}</version>\n        <exclusions>\n          <exclusion>\n            <groupId>org.abego.treelayout</groupId>\n            <artifactId>org.abego.treelayout.core</artifactId>\n          </exclusion>\n          <exclusion>\n            <groupId>com.google.inject.extensions</groupId>\n            <artifactId>guice-multibindings</artifactId>\n          </exclusion>\n        </exclusions>\n      </dependency>\n      <dependency>\n        <groupId>io.protostuff</groupId>\n        <artifactId>protostuff-runtime</artifactId>\n        <version>${protostuff.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.swagger.core.v3</groupId>\n        <artifactId>swagger-core-jakarta</artifactId>\n        <version>${swagger.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.reactivex.rxjava3</groupId>\n        <artifactId>rxjava</artifactId>\n        <version>${rxjava.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.reactivestreams</groupId>\n        <artifactId>reactive-streams</artifactId>\n        <version>${reactive-streams.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.zipkin.brave</groupId>\n        <artifactId>brave-bom</artifactId>\n        <version>${brave.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>io.zipkin.reporter2</groupId>\n        <artifactId>zipkin-reporter-bom</artifactId>\n        <version>${zipkin-reporter.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.zipkin.zipkin2</groupId>\n        <artifactId>zipkin</artifactId>\n        <version>${zipkin.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>jakarta.servlet</groupId>\n        <artifactId>jakarta.servlet-api</artifactId>\n        <version>${servlet-api.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>com.sun.activation</groupId>\n        <artifactId>jakarta.activation</artifactId>\n        <version>${activation.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>javax.annotation</groupId>\n        <artifactId>javax.annotation-api</artifactId>\n        <version>${javax-annotation.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>javax.inject</groupId>\n        <artifactId>javax.inject</artifactId>\n        <version>${javax-inject.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>javax.resource</groupId>\n        <artifactId>connector-api</artifactId>\n        <version>${javax-resource.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>junit</groupId>\n        <artifactId>junit</artifactId>\n        <version>${junit.version}</version>\n        <scope>test</scope>\n      </dependency>\n      <dependency>\n        <groupId>org.junit</groupId>\n        <artifactId>junit-bom</artifactId>\n        <version>${junit5.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.commons</groupId>\n        <artifactId>commons-lang3</artifactId>\n        <version>${commons-lang3.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.commons</groupId>\n        <artifactId>commons-text</artifactId>\n        <version>${commons-text.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.httpcomponents</groupId>\n        <artifactId>httpclient</artifactId>\n        <version>${httpcomponents.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.logging.log4j</groupId>\n        <artifactId>log4j-api</artifactId>\n        <version>${log4j2.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.logging.log4j</groupId>\n        <artifactId>log4j-core</artifactId>\n        <version>${log4j2.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.apache.logging.log4j</groupId>\n        <artifactId>log4j-slf4j-impl</artifactId>\n        <version>${log4j2.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.awaitility</groupId>\n        <artifactId>awaitility</artifactId>\n        <version>${awaitility.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.assertj</groupId>\n        <artifactId>assertj-core</artifactId>\n        <version>${assertj.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.glassfish.jersey.core</groupId>\n        <artifactId>jersey-common</artifactId>\n        <version>${jersey.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.glassfish.jersey.core</groupId>\n        <artifactId>jersey-client</artifactId>\n        <version>${jersey.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.hamcrest</groupId>\n        <artifactId>hamcrest-all</artifactId>\n        <version>${hamcrest.version}</version>\n        <scope>test</scope>\n      </dependency>\n      <dependency>\n        <groupId>org.hamcrest</groupId>\n        <artifactId>hamcrest-core</artifactId>\n        <version>${hamcrest.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.hibernate.validator</groupId>\n        <artifactId>hibernate-validator</artifactId>\n        <version>${hibernate-validator.version}</version>\n      </dependency>\n      <dependency>\n        <groupId>org.hibernate.validator</groupId>\n        <artifactId>hibernate-validator-annotation-processor</artifactId>\n        <version>${hibernate-validator.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.hdrhistogram</groupId>\n        <artifactId>HdrHistogram</artifactId>\n        <version>${hdr-histogram.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.jmockit</groupId>\n        <artifactId>jmockit</artifactId>\n        <version>${jmockit.version}</version>\n        <scope>test</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.slf4j</groupId>\n        <artifactId>slf4j-api</artifactId>\n        <version>${slf4j.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.vertx</groupId>\n        <artifactId>vertx-dependencies</artifactId>\n        <version>${vertx.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.springframework.boot</groupId>\n        <artifactId>spring-boot-dependencies</artifactId>\n        <version>${spring-boot.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.yaml</groupId>\n        <artifactId>snakeyaml</artifactId>\n        <version>${snakeyaml.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>com.alibaba.nacos</groupId>\n        <artifactId>nacos-client</artifactId>\n        <version>${nacos-client.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>io.github.resilience4j</groupId>\n        <artifactId>resilience4j-bom</artifactId>\n        <version>${resilience4j.versioin}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>org.java-websocket</groupId>\n        <artifactId>Java-WebSocket</artifactId>\n        <version>${java-websocket.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.apache.servicecomb</groupId>\n        <artifactId>java-chassis-bom</artifactId>\n        <version>${project.version}</version>\n        <type>pom</type>\n        <scope>import</scope>\n      </dependency>\n\n      <dependency>\n        <groupId>io.etcd</groupId>\n        <artifactId>jetcd-core</artifactId>\n        <version>${jetcd-core.version}</version>\n      </dependency>\n\n      <dependency>\n        <groupId>org.kiwiproject</groupId>\n        <artifactId>consul-client</artifactId>\n        <version>${consul-client.version}</version>\n      </dependency>\n    </dependencies>\n  </dependencyManagement>\n</project>\n"
  },
  {
    "path": "dependencies/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>java-chassis-dependencies-parent</artifactId>\n  <name>Java Chassis::Dependencies</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>bom</module>\n    <module>default</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "distribution/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>apache-servicecomb-java-chassis-distribution</artifactId>\n  <name>Java Chassis::Distribution</name>\n  <packaging>pom</packaging>\n  <dependencies>\n    <!-- sort by project directory name, easy to check if the module is missed -->\n    <!-- clients -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-center-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-clients-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-kie-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>dashboard-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>http-client-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>service-center-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-nacos</artifactId>\n    </dependency>\n\n    <!-- common -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-access-log</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-protobuf</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n\n    <!-- core -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n\n    <!-- dynamic-config -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-apollo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-cc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-kie</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-nacos</artifactId>\n    </dependency>\n\n    <!-- edge -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>edge-core</artifactId>\n    </dependency>\n\n    <!-- foundations -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-metrics</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-protobuf</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-spi</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-ssl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n\n    <!-- governance -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicecomb-governance</artifactId>\n    </dependency>\n\n    <!-- handlers -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-fault-injection</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-flowcontrol-qps</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-governance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-publickey-auth</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-router</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-tracing-zipkin</artifactId>\n    </dependency>\n\n    <!-- metrics -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-prometheus</artifactId>\n    </dependency>\n\n    <!-- providers -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-pojo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-rest-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-springmvc</artifactId>\n    </dependency>\n\n    <!-- service registry -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-lightweight</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-zero-config</artifactId>\n    </dependency>\n\n    <!-- solutions -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>solution-basic</artifactId>\n    </dependency>\n\n    <!-- spring boot -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n    </dependency>\n\n    <!-- ServiceComb ServiceStage extension -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicestage</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>dashboard</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>darklaunch</artifactId>\n    </dependency>\n    <!-- swagger -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-spring-data</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-springmvc</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-springmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-validator</artifactId>\n    </dependency>\n\n    <!-- tracing -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>tracing-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>tracing-zipkin</artifactId>\n    </dependency>\n\n    <!-- transports -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-highway</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-vertx</artifactId>\n    </dependency>\n  </dependencies>\n\n  <profiles>\n    <profile>\n      <id>release</id>\n      <build>\n        <plugins>\n          <plugin>\n            <artifactId>maven-assembly-plugin</artifactId>\n            <executions>\n              <execution>\n                <id>bin</id>\n                <phase>package</phase>\n                <goals>\n                  <goal>single</goal>\n                </goals>\n                <configuration>\n                  <descriptors>\n                    <descriptor>src/assembly/bin.xml</descriptor>\n                  </descriptors>\n                </configuration>\n              </execution>\n              <execution>\n                <id>src</id>\n                <phase>package</phase>\n                <goals>\n                  <goal>single</goal>\n                </goals>\n                <configuration>\n                  <descriptors>\n                    <descriptor>src/assembly/src.xml</descriptor>\n                  </descriptors>\n                </configuration>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "distribution/src/assembly/bin.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<assembly xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd\">\n  <includeBaseDirectory>true</includeBaseDirectory>\n  <baseDirectory>${project.build.finalName}-bin</baseDirectory>\n  <id>bin</id>\n  <formats>\n    <format>zip</format>\n  </formats>\n  <fileSets>\n    <fileSet>\n      <directory>../</directory>\n      <outputDirectory>./</outputDirectory>\n      <includes>\n        <include>README_ZH.md</include>\n        <include>README.md</include>\n      </includes>\n    </fileSet>\n    <fileSet>\n      <directory>src/release</directory>\n      <outputDirectory>./</outputDirectory>\n      <includes>\n        <include>NOTICE</include>\n        <include>LICENSE</include>\n        <include>licenses/**</include>\n      </includes>\n    </fileSet>\n  </fileSets>\n  <dependencySets>\n    <dependencySet>\n      <useProjectArtifact>true</useProjectArtifact>\n      <unpack>false</unpack>\n      <outputDirectory>./libs</outputDirectory>\n      <scope>runtime</scope>\n      <includes>\n        <include>org.apache.servicecomb:*</include>\n        <include>org.apache.servicecomb.archetypes:*</include>\n      </includes>\n    </dependencySet>\n  </dependencySets>\n</assembly>\n"
  },
  {
    "path": "distribution/src/assembly/src.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<assembly xmlns=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd\">\n  <id>src</id>\n  <includeBaseDirectory>true</includeBaseDirectory>\n  <baseDirectory>${project.build.finalName}-src</baseDirectory>\n  <formats>\n    <format>zip</format>\n  </formats>\n  <fileSets>\n    <fileSet>\n      <directory>..</directory>\n      <includes>\n        <include>**/*</include>\n      </includes>\n      <excludes>\n        <!--exclude the style files which use CC License from source distribution-->\n        <exclude>etc/eclipse-java-google-style.xml</exclude>\n        <exclude>etc/intellij-java-google-style.xml</exclude>\n        <!-- excludes the binary files -->\n        <exclude>**/eclipse-classes/**</exclude>\n        <exclude>**/target/**</exclude>\n        <exclude>**/build/**</exclude>\n        <exclude>**/eclipse-classes/**</exclude>\n        <exclude>**/.*</exclude>\n        <exclude>**/.*/**</exclude>\n        <exclude>*.enc</exclude>\n        <exclude>*.gpg</exclude>\n        <exclude>random_seed</exclude>\n        <exclude>**/surefire*</exclude>\n        <exclude>**/svn-commit*</exclude>\n\n        <exclude>**/.idea/**</exclude>\n        <exclude>**/*.iml</exclude>\n        <exclude>**/*.ipr</exclude>\n        <exclude>**/*.iws</exclude>\n\n        <exclude>**/cobertura.ser</exclude>\n\n        <exclude>**/node_modules/**</exclude>\n      </excludes>\n    </fileSet>\n  </fileSets>\n</assembly>\n"
  },
  {
    "path": "distribution/src/release/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n=======================================================================\nApache ServiceComb Java Chassis Subcomponents:\n\nThe Apache ServiceComb Java Chassis project contains subcomponents with\nseparate copyright notices and license terms. Your use of these\nsubcomponents is subject to the terms and conditions of the\nfollowing licenses.\n\n================================================================\nFor foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/common/utils/MimeTypesUtils.java\n    transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java\n================================================================\nThis product bundles files from vertx which is licensed under the Apache License v2.\nFor details, see https://github.com/vert-x3/vertx-web\n\n================================================================\nFor swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/AbstractBaseIntegerProperty.java\n================================================================\nThis product bundles files from swagger which is licensed under the Apache License v2.\nFor details, see https://github.com/swagger-api/swagger-core\n\n================================================================\nFor foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/ArrayFieldMapEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldMapEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldSchema.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldTypeUtils.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/HashFieldMapEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/ByteArrayInputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/InputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/OutputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/package-info.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaEx.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaReader.java\n    foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaWriter.java\n================================================================\nThis product bundles files from protostuff which is licensed under the Apache License v2.\nFor details, see  https://github.com/protostuff/protostuff\n"
  },
  {
    "path": "distribution/src/release/NOTICE",
    "content": "Apache ServiceComb Java Chassis\nCopyright 2017-2024 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-abego",
    "content": "[The \"BSD license\"]\nCopyright (c) 2011, abego Software GmbH, Germany (http://www.abego.org)\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n3. Neither the name of the abego Software GmbH nor the names of its\n   contributors may be used to endorse or promote products derived from this\n   software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-animalsniffer",
    "content": " The MIT License\n\n  Copyright (c) 2009 codehaus.org.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-antlr",
    "content": "[The \"BSD 3-clause license\"]\nCopyright (c) 2012-2017 The ANTLR Project. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n 1. Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n 2. Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n 3. Neither the name of the copyright holder nor the names of its contributors\n    may be used to endorse or promote products derived from this software\n    without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\nIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\nNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=====\n\nMIT License for codepointat.js from https://git.io/codepointat\nMIT License for fromcodepoint.js from https://git.io/vDW1m\n\nCopyright Mathias Bynens <https://mathiasbynens.be/>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-asm",
    "content": " ASM: a very small and fast Java bytecode manipulation framework\n Copyright (c) 2000-2011 INRIA, France Telecom\n All rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions\n are met:\n 1. Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n 2. Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n 3. Neither the name of the copyright holders nor the names of its\n    contributors may be used to endorse or promote products derived from\n    this software without specific prior written permission.\n\n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-bouncycastle",
    "content": "Copyright (c) 2000 - 2017 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-cc0",
    "content": "Statement of Purpose\nThe laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an \"owner\") of an original work of authorship and/or a database (each, a \"Work\").\n\nCertain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works (\"Commons\") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.\n\nFor these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the \"Affirmer\"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.\n\n1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights (\"Copyright and Related Rights\"). Copyright and Related Rights include, but are not limited to, the following:\n\nthe right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;\nmoral rights retained by the original author(s) and/or performer(s);\npublicity and privacy rights pertaining to a person's image or likeness depicted in a Work;\nrights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;\nrights protecting the extraction, dissemination, use and reuse of data in a Work;\ndatabase rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and\nother similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.\n2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the \"Waiver\"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.\n\n3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the \"License\"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.\n\n4. Limitations and Disclaimers.\n\nNo trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.\nAffirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.\nAffirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.\nAffirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-cddl",
    "content": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1\n\n1. Definitions.\n\n    1.1. \"Contributor\" means each individual or entity that creates or\n    contributes to the creation of Modifications.\n\n    1.2. \"Contributor Version\" means the combination of the Original\n    Software, prior Modifications used by a Contributor (if any), and\n    the Modifications made by that particular Contributor.\n\n    1.3. \"Covered Software\" means (a) the Original Software, or (b)\n    Modifications, or (c) the combination of files containing Original\n    Software with files containing Modifications, in each case including\n    portions thereof.\n\n    1.4. \"Executable\" means the Covered Software in any form other than\n    Source Code.\n\n    1.5. \"Initial Developer\" means the individual or entity that first\n    makes Original Software available under this License.\n\n    1.6. \"Larger Work\" means a work which combines Covered Software or\n    portions thereof with code not governed by the terms of this License.\n\n    1.7. \"License\" means this document.\n\n    1.8. \"Licensable\" means having the right to grant, to the maximum\n    extent possible, whether at the time of the initial grant or\n    subsequently acquired, any and all of the rights conveyed herein.\n\n    1.9. \"Modifications\" means the Source Code and Executable form of\n    any of the following:\n\n    A. Any file that results from an addition to, deletion from or\n    modification of the contents of a file containing Original Software\n    or previous Modifications;\n\n    B. Any new file that contains any part of the Original Software or\n    previous Modification; or\n\n    C. Any new file that is contributed or otherwise made available\n    under the terms of this License.\n\n    1.10. \"Original Software\" means the Source Code and Executable form\n    of computer software code that is originally released under this\n    License.\n\n    1.11. \"Patent Claims\" means any patent claim(s), now owned or\n    hereafter acquired, including without limitation, method, process,\n    and apparatus claims, in any patent Licensable by grantor.\n\n    1.12. \"Source Code\" means (a) the common form of computer software\n    code in which modifications are made and (b) associated\n    documentation included in or with such code.\n\n    1.13. \"You\" (or \"Your\") means an individual or a legal entity\n    exercising rights under, and complying with all of the terms of,\n    this License. For legal entities, \"You\" includes any entity which\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants.\n\n    2.1. The Initial Developer Grant.\n\n    Conditioned upon Your compliance with Section 3.1 below and subject\n    to third party intellectual property claims, the Initial Developer\n    hereby grants You a world-wide, royalty-free, non-exclusive license:\n\n    (a) under intellectual property rights (other than patent or\n    trademark) Licensable by Initial Developer, to use, reproduce,\n    modify, display, perform, sublicense and distribute the Original\n    Software (or portions thereof), with or without Modifications,\n    and/or as part of a Larger Work; and\n\n    (b) under Patent Claims infringed by the making, using or selling of\n    Original Software, to make, have made, use, practice, sell, and\n    offer for sale, and/or otherwise dispose of the Original Software\n    (or portions thereof).\n\n    (c) The licenses granted in Sections 2.1(a) and (b) are effective on\n    the date Initial Developer first distributes or otherwise makes the\n    Original Software available to a third party under the terms of this\n    License.\n\n    (d) Notwithstanding Section 2.1(b) above, no patent license is\n    granted: (1) for code that You delete from the Original Software, or\n    (2) for infringements caused by: (i) the modification of the\n    Original Software, or (ii) the combination of the Original Software\n    with other software or devices.\n\n    2.2. Contributor Grant.\n\n    Conditioned upon Your compliance with Section 3.1 below and subject\n    to third party intellectual property claims, each Contributor hereby\n    grants You a world-wide, royalty-free, non-exclusive license:\n\n    (a) under intellectual property rights (other than patent or\n    trademark) Licensable by Contributor to use, reproduce, modify,\n    display, perform, sublicense and distribute the Modifications\n    created by such Contributor (or portions thereof), either on an\n    unmodified basis, with other Modifications, as Covered Software\n    and/or as part of a Larger Work; and\n\n    (b) under Patent Claims infringed by the making, using, or selling\n    of Modifications made by that Contributor either alone and/or in\n    combination with its Contributor Version (or portions of such\n    combination), to make, use, sell, offer for sale, have made, and/or\n    otherwise dispose of: (1) Modifications made by that Contributor (or\n    portions thereof); and (2) the combination of Modifications made by\n    that Contributor with its Contributor Version (or portions of such\n    combination).\n\n    (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective\n    on the date Contributor first distributes or otherwise makes the\n    Modifications available to a third party.\n\n    (d) Notwithstanding Section 2.2(b) above, no patent license is\n    granted: (1) for any code that Contributor has deleted from the\n    Contributor Version; (2) for infringements caused by: (i) third\n    party modifications of Contributor Version, or (ii) the combination\n    of Modifications made by that Contributor with other software\n    (except as part of the Contributor Version) or other devices; or (3)\n    under Patent Claims infringed by Covered Software in the absence of\n    Modifications made by that Contributor.\n\n3. Distribution Obligations.\n\n    3.1. Availability of Source Code.\n\n    Any Covered Software that You distribute or otherwise make available\n    in Executable form must also be made available in Source Code form\n    and that Source Code form must be distributed only under the terms\n    of this License. You must include a copy of this License with every\n    copy of the Source Code form of the Covered Software You distribute\n    or otherwise make available. You must inform recipients of any such\n    Covered Software in Executable form as to how they can obtain such\n    Covered Software in Source Code form in a reasonable manner on or\n    through a medium customarily used for software exchange.\n\n    3.2. Modifications.\n\n    The Modifications that You create or to which You contribute are\n    governed by the terms of this License. You represent that You\n    believe Your Modifications are Your original creation(s) and/or You\n    have sufficient rights to grant the rights conveyed by this License.\n\n    3.3. Required Notices.\n\n    You must include a notice in each of Your Modifications that\n    identifies You as the Contributor of the Modification. You may not\n    remove or alter any copyright, patent or trademark notices contained\n    within the Covered Software, or any notices of licensing or any\n    descriptive text giving attribution to any Contributor or the\n    Initial Developer.\n\n    3.4. Application of Additional Terms.\n\n    You may not offer or impose any terms on any Covered Software in\n    Source Code form that alters or restricts the applicable version of\n    this License or the recipients' rights hereunder. You may choose to\n    offer, and to charge a fee for, warranty, support, indemnity or\n    liability obligations to one or more recipients of Covered Software.\n    However, you may do so only on Your own behalf, and not on behalf of\n    the Initial Developer or any Contributor. You must make it\n    absolutely clear that any such warranty, support, indemnity or\n    liability obligation is offered by You alone, and You hereby agree\n    to indemnify the Initial Developer and every Contributor for any\n    liability incurred by the Initial Developer or such Contributor as a\n    result of warranty, support, indemnity or liability terms You offer.\n\n    3.5. Distribution of Executable Versions.\n\n    You may distribute the Executable form of the Covered Software under\n    the terms of this License or under the terms of a license of Your\n    choice, which may contain terms different from this License,\n    provided that You are in compliance with the terms of this License\n    and that the license for the Executable form does not attempt to\n    limit or alter the recipient's rights in the Source Code form from\n    the rights set forth in this License. If You distribute the Covered\n    Software in Executable form under a different license, You must make\n    it absolutely clear that any terms which differ from this License\n    are offered by You alone, not by the Initial Developer or\n    Contributor. You hereby agree to indemnify the Initial Developer and\n    every Contributor for any liability incurred by the Initial\n    Developer or such Contributor as a result of any such terms You offer.\n\n    3.6. Larger Works.\n\n    You may create a Larger Work by combining Covered Software with\n    other code not governed by the terms of this License and distribute\n    the Larger Work as a single product. In such a case, You must make\n    sure the requirements of this License are fulfilled for the Covered\n    Software.\n\n4. Versions of the License.\n\n    4.1. New Versions.\n\n    Oracle is the initial license steward and may publish revised and/or\n    new versions of this License from time to time. Each version will be\n    given a distinguishing version number. Except as provided in Section\n    4.3, no one other than the license steward has the right to modify\n    this License.\n\n    4.2. Effect of New Versions.\n\n    You may always continue to use, distribute or otherwise make the\n    Covered Software available under the terms of the version of the\n    License under which You originally received the Covered Software. If\n    the Initial Developer includes a notice in the Original Software\n    prohibiting it from being distributed or otherwise made available\n    under any subsequent version of the License, You must distribute and\n    make the Covered Software available under the terms of the version\n    of the License under which You originally received the Covered\n    Software. Otherwise, You may also choose to use, distribute or\n    otherwise make the Covered Software available under the terms of any\n    subsequent version of the License published by the license steward.\n\n    4.3. Modified Versions.\n\n    When You are an Initial Developer and You want to create a new\n    license for Your Original Software, You may create and use a\n    modified version of this License if You: (a) rename the license and\n    remove any references to the name of the license steward (except to\n    note that the license differs from this License); and (b) otherwise\n    make it clear that the license contains terms which differ from this\n    License.\n\n5. DISCLAIMER OF WARRANTY.\n\n    COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS,\n    WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\n    INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE\n    IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR\n    NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF\n    THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE\n    DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY\n    OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,\n    REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN\n    ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS\n    AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\n\n6. TERMINATION.\n\n    6.1. This License and the rights granted hereunder will terminate\n    automatically if You fail to comply with terms herein and fail to\n    cure such breach within 30 days of becoming aware of the breach.\n    Provisions which, by their nature, must remain in effect beyond the\n    termination of this License shall survive.\n\n    6.2. If You assert a patent infringement claim (excluding\n    declaratory judgment actions) against Initial Developer or a\n    Contributor (the Initial Developer or Contributor against whom You\n    assert such claim is referred to as \"Participant\") alleging that the\n    Participant Software (meaning the Contributor Version where the\n    Participant is a Contributor or the Original Software where the\n    Participant is the Initial Developer) directly or indirectly\n    infringes any patent, then any and all rights granted directly or\n    indirectly to You by such Participant, the Initial Developer (if the\n    Initial Developer is not the Participant) and all Contributors under\n    Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice\n    from Participant terminate prospectively and automatically at the\n    expiration of such 60 day notice period, unless if within such 60\n    day period You withdraw Your claim with respect to the Participant\n    Software against such Participant either unilaterally or pursuant to\n    a written agreement with Participant.\n\n    6.3. If You assert a patent infringement claim against Participant\n    alleging that the Participant Software directly or indirectly\n    infringes any patent where such claim is resolved (such as by\n    license or settlement) prior to the initiation of patent\n    infringement litigation, then the reasonable value of the licenses\n    granted by such Participant under Sections 2.1 or 2.2 shall be taken\n    into account in determining the amount or value of any payment or\n    license.\n\n    6.4. In the event of termination under Sections 6.1 or 6.2 above,\n    all end user licenses that have been validly granted by You or any\n    distributor hereunder prior to termination (excluding licenses\n    granted to You by any distributor) shall survive termination.\n\n7. LIMITATION OF LIABILITY.\n\n    UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\n    (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE\n    INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF\n    COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE\n    TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR\n    CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT\n    LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER\n    FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR\n    LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE\n    POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT\n    APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH\n    PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH\n    LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR\n    LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION\n    AND LIMITATION MAY NOT APPLY TO YOU.\n\n8. U.S. GOVERNMENT END USERS.\n\n    The Covered Software is a \"commercial item,\" as that term is defined\n    in 48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer\n    software\" (as that term is defined at 48 C.F.R. §\n    252.227-7014(a)(1)) and \"commercial computer software documentation\"\n    as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent\n    with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4\n    (June 1995), all U.S. Government End Users acquire Covered Software\n    with only those rights set forth herein. This U.S. Government Rights\n    clause is in lieu of, and supersedes, any other FAR, DFAR, or other\n    clause or provision that addresses Government rights in computer\n    software under this License.\n\n9. MISCELLANEOUS.\n\n    This License represents the complete agreement concerning subject\n    matter hereof. If any provision of this License is held to be\n    unenforceable, such provision shall be reformed only to the extent\n    necessary to make it enforceable. This License shall be governed by\n    the law of the jurisdiction specified in a notice contained within\n    the Original Software (except to the extent applicable law, if any,\n    provides otherwise), excluding such jurisdiction's conflict-of-law\n    provisions. Any litigation relating to this License shall be subject\n    to the jurisdiction of the courts located in the jurisdiction and\n    venue specified in a notice contained within the Original Software,\n    with the losing party responsible for costs, including, without\n    limitation, court costs and reasonable attorneys' fees and expenses.\n    The application of the United Nations Convention on Contracts for\n    the International Sale of Goods is expressly excluded. Any law or\n    regulation which provides that the language of a contract shall be\n    construed against the drafter shall not apply to this License. You\n    agree that You alone are responsible for compliance with the United\n    States export administration regulations (and the export control\n    laws and regulation of any other countries) when You use, distribute\n    or otherwise make available any Covered Software.\n\n10. RESPONSIBILITY FOR CLAIMS.\n\n    As between Initial Developer and the Contributors, each party is\n    responsible for claims and damages arising, directly or indirectly,\n    out of its utilization of rights under this License and You agree to\n    work with Initial Developer and Contributors to distribute such\n    responsibility on an equitable basis. Nothing herein is intended or\n    shall be deemed to constitute any admission of liability.\n\n------------------------------------------------------------------------\n\nNOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION\nLICENSE (CDDL)\n\nThe code released under the CDDL shall be governed by the laws of the\nState of California (excluding conflict-of-law provisions). Any\nlitigation relating to this License shall be subject to the jurisdiction\nof the Federal Courts of the Northern District of California and the\nstate courts of the State of California, with venue lying in Santa Clara\nCounty, California.\n\n\n\n  The GNU General Public License (GPL) Version 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n51 Franklin Street, Fifth Floor\nBoston, MA 02110-1335\nUSA\n\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away your freedom to\nshare and change it. By contrast, the GNU General Public License is\nintended to guarantee your freedom to share and change free software--to\nmake sure the software is free for all its users. This General Public\nLicense applies to most of the Free Software Foundation's software and\nto any other program whose authors commit to using it. (Some other Free\nSoftware Foundation software is covered by the GNU Library General\nPublic License instead.) You can apply it to your programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price.\nOur General Public Licenses are designed to make sure that you have the\nfreedom to distribute copies of free software (and charge for this\nservice if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs; and that you know you can do these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone\nto deny you these rights or to ask you to surrender the rights. These\nrestrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis\nor for a fee, you must give the recipients all the rights that you have.\nYou must make sure that they, too, receive or can get the source code.\nAnd you must show them these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\nAlso, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware. If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\nFinally, any free program is threatened constantly by software patents.\nWe wish to avoid the danger that redistributors of a free program will\nindividually obtain patent licenses, in effect making the program\nproprietary. To prevent this, we have made it clear that any patent must\nbe licensed for everyone's free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and\nmodification follow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License applies to any program or other work which contains a\nnotice placed by the copyright holder saying it may be distributed under\nthe terms of this General Public License. The \"Program\", below, refers\nto any such program or work, and a \"work based on the Program\" means\neither the Program or any derivative work under copyright law: that is\nto say, a work containing the Program or a portion of it, either\nverbatim or with modifications and/or translated into another language.\n(Hereinafter, translation is included without limitation in the term\n\"modification\".) Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope. The act of running\nthe Program is not restricted, and the output from the Program is\ncovered only if its contents constitute a work based on the Program\n(independent of having been made by running the Program). Whether that\nis true depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the Program's source\ncode as you receive it, in any medium, provided that you conspicuously\nand appropriately publish on each copy an appropriate copyright notice\nand disclaimer of warranty; keep intact all the notices that refer to\nthis License and to the absence of any warranty; and give any other\nrecipients of the Program a copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any portion of\nit, thus forming a work based on the Program, and copy and distribute\nsuch modifications or work under the terms of Section 1 above, provided\nthat you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any part\n    thereof, to be licensed as a whole at no charge to all third parties\n    under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a notice\n    that there is no warranty (or else, saying that you provide a\n    warranty) and that users may redistribute the program under these\n    conditions, and telling the user how to view a copy of this License.\n    (Exception: if the Program itself is interactive but does not\n    normally print such an announcement, your work based on the Program\n    is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole. If\nidentifiable sections of that work are not derived from the Program, and\ncan be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works. But when you\ndistribute the same sections as part of a whole which is a work based on\nthe Program, the distribution of the whole must be on the terms of this\nLicense, whose permissions for other licensees extend to the entire\nwhole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of a\nstorage or distribution medium does not bring the other work under the\nscope of this License.\n\n3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your cost\n    of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer to\n    distribute corresponding source code. (This alternative is allowed\n    only for noncommercial distribution and only if you received the\n    program in object code or executable form with such an offer, in\n    accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it. For an executable work, complete source code\nmeans all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to control\ncompilation and installation of the executable. However, as a special\nexception, the source code distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies the\nexecutable.\n\nIf distribution of executable or object code is made by offering access\nto copy from a designated place, then offering equivalent access to copy\nthe source code from the same place counts as distribution of the source\ncode, even though third parties are not compelled to copy the source\nalong with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License. Any attempt otherwise\nto copy, modify, sublicense or distribute the Program is void, and will\nautomatically terminate your rights under this License. However, parties\nwho have received copies, or rights, from you under this License will\nnot have their licenses terminated so long as such parties remain in\nfull compliance.\n\n5. You are not required to accept this License, since you have not\nsigned it. However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works. These actions are\nprohibited by law if you do not accept this License. Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and all\nits terms and conditions for copying, distributing or modifying the\nProgram or works based on it.\n\n6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions. You may not impose any further restrictions\non the recipients' exercise of the rights granted herein. You are not\nresponsible for enforcing compliance by third parties to this License.\n\n7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License. If you cannot distribute\nso as to satisfy simultaneously your obligations under this License and\nany other pertinent obligations, then as a consequence you may not\ndistribute the Program at all. For example, if a patent license would\nnot permit royalty-free redistribution of the Program by all those who\nreceive copies directly or indirectly through you, then the only way you\ncould satisfy both it and this License would be to refrain entirely from\ndistribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is implemented\nby public license practices. Many people have made generous\ncontributions to the wide range of software distributed through that\nsystem in reliance on consistent application of that system; it is up to\nthe author/donor to decide if he or she is willing to distribute\nsoftware through any other system and a licensee cannot impose that choice.\n\nThis section is intended to make thoroughly clear what is believed to be\na consequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License may\nadd an explicit geographical distribution limitation excluding those\ncountries, so that distribution is permitted only in or among countries\nnot thus excluded. In such case, this License incorporates the\nlimitation as if written in the body of this License.\n\n9. The Free Software Foundation may publish revised and/or new\nversions of the General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number. If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation. If the Program does not specify a version\nnumber of this License, you may choose any version ever published by the\nFree Software Foundation.\n\n10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the\nauthor to ask for permission. For software which is copyrighted by the\nFree Software Foundation, write to the Free Software Foundation; we\nsometimes make exceptions for this. Our decision will be guided by the\ntwo goals of preserving the free status of all derivatives of our free\nsoftware and of promoting the sharing and reuse of software generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND,\nEITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE\nENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH\nYOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL\nNECESSARY SERVICING, REPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR\nDAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL\nDAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM\n(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED\nINACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF\nTHE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR\nOTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is safest to\nattach them to the start of each source file to most effectively convey\nthe exclusion of warranty; and each file should have at least the\n\"copyright\" line and a pointer to where the full notice is found.\n\n    One line to give the program's name and a brief idea of what it does.\n    Copyright (C) <year> <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful, but\n    WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n    General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type\n    `show w'. This is free software, and you are welcome to redistribute\n    it under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the\nappropriate parts of the General Public License. Of course, the commands\nyou use may be called something other than `show w' and `show c'; they\ncould even be mouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary. Here is a sample; alter the names:\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the\n    program `Gnomovision' (which makes passes at compilers) written by\n    James Hacker.\n\n    signature of Ty Coon, 1 April 1989\n    Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program\ninto proprietary programs. If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications\nwith the library. If this is what you want to do, use the GNU Library\nGeneral Public License instead of this License.\n\n#\n\nCertain source files distributed by Oracle America, Inc. and/or its\naffiliates are subject to the following clarification and special\nexception to the GPLv2, based on the GNU Project exception for its\nClasspath libraries, known as the GNU Classpath Exception, but only\nwhere Oracle has expressly included in the particular source file's\nheader the words \"Oracle designates this particular file as subject to\nthe \"Classpath\" exception as provided by Oracle in the LICENSE file\nthat accompanied this code.\"\n\nYou should also note that Oracle includes multiple, independent\nprograms in this software package. Some of those programs are provided\nunder licenses deemed incompatible with the GPLv2 by the Free Software\nFoundation and others.  For example, the package includes programs\nlicensed under the Apache License, Version 2.0.  Such programs are\nlicensed to you under their original licenses.\n\nOracle facilitates your further distribution of this package by adding\nthe Classpath Exception to the necessary parts of its GPLv2 code, which\npermits you to use that code in combination with other independent\nmodules not licensed under the GPLv2.  However, note that this would\nnot permit you to commingle code under an incompatible license with\nOracle's GPLv2 licensed code by, for example, cutting and pasting such\ncode into a file also containing Oracle's GPLv2 licensed code and then\ndistributing the result.  Additionally, if you were to remove the\nClasspath Exception from any of the files to which it applies and\ndistribute the result, you would likely be required to license some or\nall of the other code in that distribution under the GPLv2 as well, and\nsince the GPLv2 is incompatible with the license terms of some items\nincluded in the distribution by Oracle, removing the Classpath\nException could therefore effectively compromise your ability to\nfurther distribute the package.\n\nProceed with caution and we recommend that you obtain the advice of a\nlawyer skilled in open source matters before removing the Classpath\nException or making modifications to this package which may\nsubsequently be redistributed and/or involve the use of third party\nsoftware.\n\nCLASSPATH EXCEPTION\nLinking this library statically or dynamically with other modules is\nmaking a combined work based on this library.  Thus, the terms and\nconditions of the GNU General Public License version 2 cover the whole\ncombination.\n\nAs a special exception, the copyright holders of this library give you\npermission to link this library with independent modules to produce an\nexecutable, regardless of the license terms of these independent\nmodules, and to copy and distribute the resulting executable under\nterms of your choice, provided that you also meet, for each linked\nindependent module, the terms and conditions of the license of that\nmodule.  An independent module is a module which is not derived from or\nbased on this library.  If you modify this library, you may extend this\nexception to your version of the library, but you are not obligated to\ndo so.  If you do not wish to do so, delete this exception statement\nfrom your version.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-checkerqual",
    "content": "MIT License:\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-edl-v10",
    "content": "Eclipse Distribution License - v 1.0\n\nCopyright (c) 2007, Eclipse Foundation, Inc. and its licensors.\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\nRedistributions 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.\nNeither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\nTHIS 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.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-epl-v10",
    "content": "Eclipse Public License - v 1.0\nTHE 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.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and\n\nb) in the case of each subsequent Contributor:\n\ni) changes to the Program, and\n\nii) additions to the Program;\n\nwhere such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"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.\n\n\"Program\" means the Contributions distributed in accordance with this Agreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement, including all Contributors.\n\n2. GRANT OF RIGHTS\n\na) 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.\n\nb) 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.\n\nc) 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.\n\nd) 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.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:\n\na) it complies with the terms and conditions of this Agreement; and\n\nb) its license agreement:\n\ni) 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;\n\nii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;\n\niii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and\n\niv) 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.\n\nWhen the Program is made available in source code form:\n\na) it must be made available under this Agreement; and\n\nb) a copy of this Agreement must be included with each copy of the Program.\n\nContributors may not remove or alter any copyright notices contained within the Program.\n\nEach 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.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial 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.\n\nFor 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.\n\n5. NO WARRANTY\n\nEXCEPT 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.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT 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.\n\n7. GENERAL\n\nIf 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.\n\nIf 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.\n\nAll 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.\n\nEveryone 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.\n\nThis 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.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-epl-v20",
    "content": "Eclipse Public License - v 2.0\n\nTHE 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.\n\n1. DEFINITIONS\n“Contribution” means:\n\na) in the case of the initial Contributor, the initial content Distributed under this Agreement, and\nb) in the case of each subsequent Contributor:\ni) changes to the Program, and\nii) additions to the Program;\nwhere 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.\n“Contributor” means any person or entity that Distributes the Program.\n\n“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.\n\n“Program” means the Contributions Distributed in accordance with this Agreement.\n\n“Recipient” means anyone who receives the Program under this Agreement or any Secondary License (as applicable), including Contributors.\n\n“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.\n\n“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.\n\n“Distribute” means the acts of a) distributing or b) making available in any manner that enables the transfer of a copy.\n\n“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.\n\n“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.\n\n2. GRANT OF RIGHTS\na) 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.\nb) 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.\nc) 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.\nd) 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.\ne) 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).\n3. REQUIREMENTS\n3.1 If a Contributor Distributes the Program in any form, then:\n\na) 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\nb) the Contributor may Distribute the Program under a license different than this Agreement, provided that such license:\ni) 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;\nii) effectively excludes on behalf of all other Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;\niii) does not attempt to limit or alter the recipients' rights in the Source Code under section 3.2; and\niv) requires any subsequent distribution of the Program by any party to be under a license that satisfies the requirements of this section 3.\n3.2 When the Program is Distributed as Source Code:\n\na) 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\nb) a copy of this Agreement must be included with each copy of the Program.\n3.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.\n\n4. COMMERCIAL DISTRIBUTION\nCommercial 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.\n\nFor 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.\n\n5. NO WARRANTY\nEXCEPT 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.\n\n6. DISCLAIMER OF LIABILITY\nEXCEPT 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.\n\n7. GENERAL\nIf 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.\n\nIf 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.\n\nAll 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.\n\nEveryone 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.\n\nExcept 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.\n\nExhibit A – Form of Secondary Licenses Notice\n“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}.”\n\nSimply including a copy of this Agreement, including this Exhibit A is not sufficient to license the Source Code under Secondary Licenses.\n\nIf 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.\n\nYou may add additional accurate notices of copyright ownership.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-hamcrest",
    "content": "BSD License\n\nCopyright (c) 2000-2015 www.hamcrest.org\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this list of\nconditions and the following disclaimer. Redistributions in binary form must reproduce\nthe above copyright notice, this list of conditions and the following disclaimer in\nthe documentation and/or other materials provided with the distribution.\n\nNeither the name of Hamcrest nor the names of its contributors may be used to endorse\nor promote products derived from this software without specific prior written\npermission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\nSHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY\nWAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-hdrhistogram",
    "content": "The code in this repository code was Written by Gil Tene, Michael Barker,\nand Matt Warren, and released to the public domain, as explained at\nhttp://creativecommons.org/publicdomain/zero/1.0/\n\nFor users of this code who wish to consume it under the \"BSD\" license\nrather than under the public domain or CC0 contribution text mentioned\nabove, the code found under this directory is *also* provided under the\nfollowing license (commonly referred to as the BSD 2-Clause License). This\nlicense does not detract from the above stated release of the code into\nthe public domain, and simply represents an additional license granted by\nthe Author.\n\n-----------------------------------------------------------------------------\n** Beginning of \"BSD 2-Clause License\" text. **\n\n Copyright (c) 2012, 2013, 2014, 2015, 2016 Gil Tene\n Copyright (c) 2014 Michael Barker\n Copyright (c) 2014 Matt Warren\n All rights reserved.\n\n Redistribution and use in source and binary forms, with or without\n modification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\n THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-icu4j",
    "content": "COPYRIGHT AND PERMISSION NOTICE (ICU 58 and later)\n\nCopyright © 1991-2018 Unicode, Inc. All rights reserved.\nDistributed under the Terms of Use in http://www.unicode.org/copyright.html.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Unicode data files and any associated documentation\n(the \"Data Files\") or Unicode software and any associated documentation\n(the \"Software\") to deal in the Data Files or Software\nwithout restriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, and/or sell copies of\nthe Data Files or Software, and to permit persons to whom the Data Files\nor Software are furnished to do so, provided that either\n(a) this copyright and permission notice appear with all copies\nof the Data Files or Software, or\n(b) this copyright and permission notice appear in associated\nDocumentation.\n\nTHE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT OF THIRD PARTY RIGHTS.\nIN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS\nNOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL\nDAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\nDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\nTORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THE DATA FILES OR SOFTWARE.\n\nExcept as contained in this notice, the name of a copyright holder\nshall not be used in advertising or otherwise to promote the sale,\nuse or other dealings in these Data Files or Software without prior\nwritten authorization of the copyright holder.\n\n---------------------\n\nThird-Party Software Licenses\n\nThis section contains third-party software notices and/or additional\nterms for licensed third-party software components included within ICU\nlibraries.\n\n1. ICU License - ICU 1.8.1 to ICU 57.1\n\nCOPYRIGHT AND PERMISSION NOTICE\n\nCopyright (c) 1995-2016 International Business Machines Corporation and others\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, and/or sell copies of the Software, and to permit persons\nto whom the Software is furnished to do so, provided that the above\ncopyright notice(s) and this permission notice appear in all copies of\nthe Software and that both the above copyright notice(s) and this\npermission notice appear in supporting documentation.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\nHOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY\nSPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER\nRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF\nCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\nCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\nExcept as contained in this notice, the name of a copyright holder\nshall not be used in advertising or otherwise to promote the sale, use\nor other dealings in this Software without prior written authorization\nof the copyright holder.\n\nAll trademarks and registered trademarks mentioned herein are the\nproperty of their respective owners.\n\n2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt)\n\n #     The Google Chrome software developed by Google is licensed under\n # the BSD license. Other software included in this distribution is\n # provided under other licenses, as set forth below.\n #\n #  The BSD License\n #  http://opensource.org/licenses/bsd-license.php\n #  Copyright (C) 2006-2008, Google Inc.\n #\n #  All rights reserved.\n #\n #  Redistribution and use in source and binary forms, with or without\n # modification, are permitted provided that the following conditions are met:\n #\n #  Redistributions of source code must retain the above copyright notice,\n # this list of conditions and the following disclaimer.\n #  Redistributions in binary form must reproduce the above\n # copyright notice, this list of conditions and the following\n # disclaimer in the documentation and/or other materials provided with\n # the distribution.\n #  Neither the name of  Google Inc. nor the names of its\n # contributors may be used to endorse or promote products derived from\n # this software without specific prior written permission.\n #\n #\n #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n # CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n #\n #\n #  The word list in cjdict.txt are generated by combining three word lists\n # listed below with further processing for compound word breaking. The\n # frequency is generated with an iterative training against Google web\n # corpora.\n #\n #  * Libtabe (Chinese)\n #    - https://sourceforge.net/project/?group_id=1519\n #    - Its license terms and conditions are shown below.\n #\n #  * IPADIC (Japanese)\n #    - http://chasen.aist-nara.ac.jp/chasen/distribution.html\n #    - Its license terms and conditions are shown below.\n #\n #  ---------COPYING.libtabe ---- BEGIN--------------------\n #\n #  /*\n #   * Copyright (c) 1999 TaBE Project.\n #   * Copyright (c) 1999 Pai-Hsiang Hsiao.\n #   * All rights reserved.\n #   *\n #   * Redistribution and use in source and binary forms, with or without\n #   * modification, are permitted provided that the following conditions\n #   * are met:\n #   *\n #   * . Redistributions of source code must retain the above copyright\n #   *   notice, this list of conditions and the following disclaimer.\n #   * . Redistributions in binary form must reproduce the above copyright\n #   *   notice, this list of conditions and the following disclaimer in\n #   *   the documentation and/or other materials provided with the\n #   *   distribution.\n #   * . Neither the name of the TaBE Project nor the names of its\n #   *   contributors may be used to endorse or promote products derived\n #   *   from this software without specific prior written permission.\n #   *\n #   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n #   * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n #   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n #   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n #   * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n #   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n #   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n #   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n #   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n #   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n #   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n #   * OF THE POSSIBILITY OF SUCH DAMAGE.\n #   */\n #\n #  /*\n #   * Copyright (c) 1999 Computer Systems and Communication Lab,\n #   *                    Institute of Information Science, Academia\n #       *                    Sinica. All rights reserved.\n #   *\n #   * Redistribution and use in source and binary forms, with or without\n #   * modification, are permitted provided that the following conditions\n #   * are met:\n #   *\n #   * . Redistributions of source code must retain the above copyright\n #   *   notice, this list of conditions and the following disclaimer.\n #   * . Redistributions in binary form must reproduce the above copyright\n #   *   notice, this list of conditions and the following disclaimer in\n #   *   the documentation and/or other materials provided with the\n #   *   distribution.\n #   * . Neither the name of the Computer Systems and Communication Lab\n #   *   nor the names of its contributors may be used to endorse or\n #   *   promote products derived from this software without specific\n #   *   prior written permission.\n #   *\n #   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n #   * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n #   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n #   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n #   * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n #   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n #   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n #   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n #   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n #   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n #   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n #   * OF THE POSSIBILITY OF SUCH DAMAGE.\n #   */\n #\n #  Copyright 1996 Chih-Hao Tsai @ Beckman Institute,\n #      University of Illinois\n #  c-tsai4@uiuc.edu  http://casper.beckman.uiuc.edu/~c-tsai4\n #\n #  ---------------COPYING.libtabe-----END--------------------------------\n #\n #\n #  ---------------COPYING.ipadic-----BEGIN-------------------------------\n #\n #  Copyright 2000, 2001, 2002, 2003 Nara Institute of Science\n #  and Technology.  All Rights Reserved.\n #\n #  Use, reproduction, and distribution of this software is permitted.\n #  Any copy of this software, whether in its original form or modified,\n #  must include both the above copyright notice and the following\n #  paragraphs.\n #\n #  Nara Institute of Science and Technology (NAIST),\n #  the copyright holders, disclaims all warranties with regard to this\n #  software, including all implied warranties of merchantability and\n #  fitness, in no event shall NAIST be liable for\n #  any special, indirect or consequential damages or any damages\n #  whatsoever resulting from loss of use, data or profits, whether in an\n #  action of contract, negligence or other tortuous action, arising out\n #  of or in connection with the use or performance of this software.\n #\n #  A large portion of the dictionary entries\n #  originate from ICOT Free Software.  The following conditions for ICOT\n #  Free Software applies to the current dictionary as well.\n #\n #  Each User may also freely distribute the Program, whether in its\n #  original form or modified, to any third party or parties, PROVIDED\n #  that the provisions of Section 3 (\"NO WARRANTY\") will ALWAYS appear\n #  on, or be attached to, the Program, which is distributed substantially\n #  in the same form as set out herein and that such intended\n #  distribution, if actually made, will neither violate or otherwise\n #  contravene any of the laws and regulations of the countries having\n #  jurisdiction over the User or the intended distribution itself.\n #\n #  NO WARRANTY\n #\n #  The program was produced on an experimental basis in the course of the\n #  research and development conducted during the project and is provided\n #  to users as so produced on an experimental basis.  Accordingly, the\n #  program is provided without any warranty whatsoever, whether express,\n #  implied, statutory or otherwise.  The term \"warranty\" used herein\n #  includes, but is not limited to, any warranty of the quality,\n #  performance, merchantability and fitness for a particular purpose of\n #  the program and the nonexistence of any infringement or violation of\n #  any right of any third party.\n #\n #  Each user of the program will agree and understand, and be deemed to\n #  have agreed and understood, that there is no warranty whatsoever for\n #  the program and, accordingly, the entire risk arising from or\n #  otherwise connected with the program is assumed by the user.\n #\n #  Therefore, neither ICOT, the copyright holder, or any other\n #  organization that participated in or was otherwise related to the\n #  development of the program and their respective officials, directors,\n #  officers and other employees shall be held liable for any and all\n #  damages, including, without limitation, general, special, incidental\n #  and consequential damages, arising out of or otherwise in connection\n #  with the use or inability to use the program or any product, material\n #  or result produced or otherwise obtained by using the program,\n #  regardless of whether they have been advised of, or otherwise had\n #  knowledge of, the possibility of such damages at any time during the\n #  project or thereafter.  Each user will be deemed to have agreed to the\n #  foregoing by his or her commencement of use of the program.  The term\n #  \"use\" as used herein includes, but is not limited to, the use,\n #  modification, copying and distribution of the program and the\n #  production of secondary products from the program.\n #\n #  In the case where the program, whether in its original form or\n #  modified, was distributed or delivered to or received by a user from\n #  any person, organization or entity other than ICOT, unless it makes or\n #  grants independently of ICOT any specific warranty to the user in\n #  writing, such person, organization or entity, will also be exempted\n #  from and not be held liable to the user for any such damages as noted\n #  above as far as the program is concerned.\n #\n #  ---------------COPYING.ipadic-----END----------------------------------\n\n3. Lao Word Break Dictionary Data (laodict.txt)\n\n #  Copyright (c) 2013 International Business Machines Corporation\n #  and others. All Rights Reserved.\n #\n # Project: http://code.google.com/p/lao-dictionary/\n # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt\n # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt\n #              (copied below)\n #\n #  This file is derived from the above dictionary, with slight\n #  modifications.\n #  ----------------------------------------------------------------------\n #  Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell.\n #  All rights reserved.\n #\n #  Redistribution and use in source and binary forms, with or without\n #  modification,\n #  are permitted provided that the following conditions are met:\n #\n #\n # Redistributions of source code must retain the above copyright notice, this\n #  list of conditions and the following disclaimer. Redistributions in\n #  binary form must reproduce the above copyright notice, this list of\n #  conditions and the following disclaimer in the documentation and/or\n #  other materials provided with the distribution.\n #\n #\n # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n # \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n # OF THE POSSIBILITY OF SUCH DAMAGE.\n #  --------------------------------------------------------------------------\n\n4. Burmese Word Break Dictionary Data (burmesedict.txt)\n\n #  Copyright (c) 2014 International Business Machines Corporation\n #  and others. All Rights Reserved.\n #\n #  This list is part of a project hosted at:\n #    github.com/kanyawtech/myanmar-karen-word-lists\n #\n #  --------------------------------------------------------------------------\n #  Copyright (c) 2013, LeRoy Benjamin Sharon\n #  All rights reserved.\n #\n #  Redistribution and use in source and binary forms, with or without\n #  modification, are permitted provided that the following conditions\n #  are met: Redistributions of source code must retain the above\n #  copyright notice, this list of conditions and the following\n #  disclaimer.  Redistributions in binary form must reproduce the\n #  above copyright notice, this list of conditions and the following\n #  disclaimer in the documentation and/or other materials provided\n #  with the distribution.\n #\n #    Neither the name Myanmar Karen Word Lists, nor the names of its\n #    contributors may be used to endorse or promote products derived\n #    from this software without specific prior written permission.\n #\n #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n #  CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n #  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n #  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n #  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS\n #  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n #  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n #  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n #  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n #  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n #  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n #  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n #  SUCH DAMAGE.\n #  --------------------------------------------------------------------------\n\n5. Time Zone Database\n\n  ICU uses the public domain data and code derived from Time Zone\nDatabase for its time zone support. The ownership of the TZ database\nis explained in BCP 175: Procedure for Maintaining the Time Zone\nDatabase section 7.\n\n # 7.  Database Ownership\n #\n #    The TZ database itself is not an IETF Contribution or an IETF\n #    document.  Rather it is a pre-existing and regularly updated work\n #    that is in the public domain, and is intended to remain in the\n #    public domain.  Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do\n #    not apply to the TZ Database or contributions that individuals make\n #    to it.  Should any claims be made and substantiated against the TZ\n #    Database, the organization that is providing the IANA\n #    Considerations defined in this RFC, under the memorandum of\n #    understanding with the IETF, currently ICANN, may act in accordance\n #    with all competent court orders.  No ownership claims will be made\n #    by ICANN or the IETF Trust on the database or the code.  Any person\n #    making a contribution to the database or code waives all rights to\n #    future claims in that contribution or in the TZ Database.\n\n6. Google double-conversion\n\nCopyright 2006-2011, the V8 project authors. All rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\n      copyright notice, this list of conditions and the following\n      disclaimer in the documentation and/or other materials provided\n      with the distribution.\n    * Neither the name of Google Inc. nor the names of its\n      contributors may be used to endorse or promote products derived\n      from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-jcodings",
    "content": "Permission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-joni",
    "content": "MIT License\n\nCopyright (c) 2017 JRuby Team\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-jopt",
    "content": "The MIT License\n\n Copyright (c) 2004-2016 Paul R. Holser, Jr.\n\n Permission is hereby granted, free of charge, to any person obtaining\n a copy of this software and associated documentation files (the\n \"Software\"), to deal in the Software without restriction, including\n without limitation the rights to use, copy, modify, merge, publish,\n distribute, sublicense, and/or sell copies of the Software, and to\n permit persons to whom the Software is furnished to do so, subject to\n the following conditions:\n\n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-jsonp",
    "content": "1. Definitions.\n\n  1.1. \"Contributor\" means each individual or entity that creates or\n  contributes to the creation of Modifications.\n\n  1.2. \"Contributor Version\" means the combination of the Original\n  Software, prior Modifications used by a Contributor (if any), and\n  the Modifications made by that particular Contributor.\n\n  1.3. \"Covered Software\" means (a) the Original Software, or (b)\n  Modifications, or (c) the combination of files containing Original\n  Software with files containing Modifications, in each case including\n  portions thereof.\n\n  1.4. \"Executable\" means the Covered Software in any form other than\n  Source Code.\n\n  1.5. \"Initial Developer\" means the individual or entity that first\n  makes Original Software available under this License.\n\n  1.6. \"Larger Work\" means a work which combines Covered Software or\n  portions thereof with code not governed by the terms of this License.\n\n  1.7. \"License\" means this document.\n\n  1.8. \"Licensable\" means having the right to grant, to the maximum\n  extent possible, whether at the time of the initial grant or\n  subsequently acquired, any and all of the rights conveyed herein.\n\n  1.9. \"Modifications\" means the Source Code and Executable form of\n  any of the following:\n\n  A. Any file that results from an addition to, deletion from or\n  modification of the contents of a file containing Original Software\n  or previous Modifications;\n\n  B. Any new file that contains any part of the Original Software or\n  previous Modification; or\n\n  C. Any new file that is contributed or otherwise made available\n  under the terms of this License.\n\n  1.10. \"Original Software\" means the Source Code and Executable form\n  of computer software code that is originally released under this\n  License.\n\n  1.11. \"Patent Claims\" means any patent claim(s), now owned or\n  hereafter acquired, including without limitation, method, process,\n  and apparatus claims, in any patent Licensable by grantor.\n\n  1.12. \"Source Code\" means (a) the common form of computer software\n  code in which modifications are made and (b) associated\n  documentation included in or with such code.\n\n  1.13. \"You\" (or \"Your\") means an individual or a legal entity\n  exercising rights under, and complying with all of the terms of,\n  this License. For legal entities, \"You\" includes any entity which\n  controls, is controlled by, or is under common control with You. For\n  purposes of this definition, \"control\" means (a) the power, direct\n  or indirect, to cause the direction or management of such entity,\n  whether by contract or otherwise, or (b) ownership of more than\n  fifty percent (50%) of the outstanding shares or beneficial\n  ownership of such entity.\n\n2. License Grants.\n\n  2.1. The Initial Developer Grant.\n\n  Conditioned upon Your compliance with Section 3.1 below and subject\n  to third party intellectual property claims, the Initial Developer\n  hereby grants You a world-wide, royalty-free, non-exclusive license:\n\n  (a) under intellectual property rights (other than patent or\n  trademark) Licensable by Initial Developer, to use, reproduce,\n  modify, display, perform, sublicense and distribute the Original\n  Software (or portions thereof), with or without Modifications,\n  and/or as part of a Larger Work; and\n\n  (b) under Patent Claims infringed by the making, using or selling of\n  Original Software, to make, have made, use, practice, sell, and\n  offer for sale, and/or otherwise dispose of the Original Software\n  (or portions thereof).\n\n  (c) The licenses granted in Sections 2.1(a) and (b) are effective on\n  the date Initial Developer first distributes or otherwise makes the\n  Original Software available to a third party under the terms of this\n  License.\n\n  (d) Notwithstanding Section 2.1(b) above, no patent license is\n  granted: (1) for code that You delete from the Original Software, or\n  (2) for infringements caused by: (i) the modification of the\n  Original Software, or (ii) the combination of the Original Software\n  with other software or devices.\n\n  2.2. Contributor Grant.\n\n  Conditioned upon Your compliance with Section 3.1 below and subject\n  to third party intellectual property claims, each Contributor hereby\n  grants You a world-wide, royalty-free, non-exclusive license:\n\n  (a) under intellectual property rights (other than patent or\n  trademark) Licensable by Contributor to use, reproduce, modify,\n  display, perform, sublicense and distribute the Modifications\n  created by such Contributor (or portions thereof), either on an\n  unmodified basis, with other Modifications, as Covered Software\n  and/or as part of a Larger Work; and\n\n  (b) under Patent Claims infringed by the making, using, or selling\n  of Modifications made by that Contributor either alone and/or in\n  combination with its Contributor Version (or portions of such\n  combination), to make, use, sell, offer for sale, have made, and/or\n  otherwise dispose of: (1) Modifications made by that Contributor (or\n  portions thereof); and (2) the combination of Modifications made by\n  that Contributor with its Contributor Version (or portions of such\n  combination).\n\n  (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective\n  on the date Contributor first distributes or otherwise makes the\n  Modifications available to a third party.\n\n  (d) Notwithstanding Section 2.2(b) above, no patent license is\n  granted: (1) for any code that Contributor has deleted from the\n  Contributor Version; (2) for infringements caused by: (i) third\n  party modifications of Contributor Version, or (ii) the combination\n  of Modifications made by that Contributor with other software\n  (except as part of the Contributor Version) or other devices; or (3)\n  under Patent Claims infringed by Covered Software in the absence of\n  Modifications made by that Contributor.\n\n3. Distribution Obligations.\n\n  3.1. Availability of Source Code.\n\n  Any Covered Software that You distribute or otherwise make available\n  in Executable form must also be made available in Source Code form\n  and that Source Code form must be distributed only under the terms\n  of this License. You must include a copy of this License with every\n  copy of the Source Code form of the Covered Software You distribute\n  or otherwise make available. You must inform recipients of any such\n  Covered Software in Executable form as to how they can obtain such\n  Covered Software in Source Code form in a reasonable manner on or\n  through a medium customarily used for software exchange.\n\n  3.2. Modifications.\n\n  The Modifications that You create or to which You contribute are\n  governed by the terms of this License. You represent that You\n  believe Your Modifications are Your original creation(s) and/or You\n  have sufficient rights to grant the rights conveyed by this License.\n\n  3.3. Required Notices.\n\n  You must include a notice in each of Your Modifications that\n  identifies You as the Contributor of the Modification. You may not\n  remove or alter any copyright, patent or trademark notices contained\n  within the Covered Software, or any notices of licensing or any\n  descriptive text giving attribution to any Contributor or the\n  Initial Developer.\n\n  3.4. Application of Additional Terms.\n\n  You may not offer or impose any terms on any Covered Software in\n  Source Code form that alters or restricts the applicable version of\n  this License or the recipients' rights hereunder. You may choose to\n  offer, and to charge a fee for, warranty, support, indemnity or\n  liability obligations to one or more recipients of Covered Software.\n  However, you may do so only on Your own behalf, and not on behalf of\n  the Initial Developer or any Contributor. You must make it\n  absolutely clear that any such warranty, support, indemnity or\n  liability obligation is offered by You alone, and You hereby agree\n  to indemnify the Initial Developer and every Contributor for any\n  liability incurred by the Initial Developer or such Contributor as a\n  result of warranty, support, indemnity or liability terms You offer.\n\n  3.5. Distribution of Executable Versions.\n\n  You may distribute the Executable form of the Covered Software under\n  the terms of this License or under the terms of a license of Your\n  choice, which may contain terms different from this License,\n  provided that You are in compliance with the terms of this License\n  and that the license for the Executable form does not attempt to\n  limit or alter the recipient's rights in the Source Code form from\n  the rights set forth in this License. If You distribute the Covered\n  Software in Executable form under a different license, You must make\n  it absolutely clear that any terms which differ from this License\n  are offered by You alone, not by the Initial Developer or\n  Contributor. You hereby agree to indemnify the Initial Developer and\n  every Contributor for any liability incurred by the Initial\n  Developer or such Contributor as a result of any such terms You offer.\n\n  3.6. Larger Works.\n\n  You may create a Larger Work by combining Covered Software with\n  other code not governed by the terms of this License and distribute\n  the Larger Work as a single product. In such a case, You must make\n  sure the requirements of this License are fulfilled for the Covered\n  Software.\n\n4. Versions of the License.\n\n  4.1. New Versions.\n\n  Oracle is the initial license steward and may publish revised and/or\n  new versions of this License from time to time. Each version will be\n  given a distinguishing version number. Except as provided in Section\n  4.3, no one other than the license steward has the right to modify\n  this License.\n\n  4.2. Effect of New Versions.\n\n  You may always continue to use, distribute or otherwise make the\n  Covered Software available under the terms of the version of the\n  License under which You originally received the Covered Software. If\n  the Initial Developer includes a notice in the Original Software\n  prohibiting it from being distributed or otherwise made available\n  under any subsequent version of the License, You must distribute and\n  make the Covered Software available under the terms of the version\n  of the License under which You originally received the Covered\n  Software. Otherwise, You may also choose to use, distribute or\n  otherwise make the Covered Software available under the terms of any\n  subsequent version of the License published by the license steward.\n\n  4.3. Modified Versions.\n\n  When You are an Initial Developer and You want to create a new\n  license for Your Original Software, You may create and use a\n  modified version of this License if You: (a) rename the license and\n  remove any references to the name of the license steward (except to\n  note that the license differs from this License); and (b) otherwise\n  make it clear that the license contains terms which differ from this\n  License.\n\n5. DISCLAIMER OF WARRANTY.\n\n  COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS,\n  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\n  INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE\n  IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR\n  NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF\n  THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE\n  DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY\n  OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,\n  REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN\n  ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS\n  AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\n\n6. TERMINATION.\n\n  6.1. This License and the rights granted hereunder will terminate\n  automatically if You fail to comply with terms herein and fail to\n  cure such breach within 30 days of becoming aware of the breach.\n  Provisions which, by their nature, must remain in effect beyond the\n  termination of this License shall survive.\n\n  6.2. If You assert a patent infringement claim (excluding\n  declaratory judgment actions) against Initial Developer or a\n  Contributor (the Initial Developer or Contributor against whom You\n  assert such claim is referred to as \"Participant\") alleging that the\n  Participant Software (meaning the Contributor Version where the\n  Participant is a Contributor or the Original Software where the\n  Participant is the Initial Developer) directly or indirectly\n  infringes any patent, then any and all rights granted directly or\n  indirectly to You by such Participant, the Initial Developer (if the\n  Initial Developer is not the Participant) and all Contributors under\n  Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice\n  from Participant terminate prospectively and automatically at the\n  expiration of such 60 day notice period, unless if within such 60\n  day period You withdraw Your claim with respect to the Participant\n  Software against such Participant either unilaterally or pursuant to\n  a written agreement with Participant.\n\n  6.3. If You assert a patent infringement claim against Participant\n  alleging that the Participant Software directly or indirectly\n  infringes any patent where such claim is resolved (such as by\n  license or settlement) prior to the initiation of patent\n  infringement litigation, then the reasonable value of the licenses\n  granted by such Participant under Sections 2.1 or 2.2 shall be taken\n  into account in determining the amount or value of any payment or\n  license.\n\n  6.4. In the event of termination under Sections 6.1 or 6.2 above,\n  all end user licenses that have been validly granted by You or any\n  distributor hereunder prior to termination (excluding licenses\n  granted to You by any distributor) shall survive termination.\n\n7. LIMITATION OF LIABILITY.\n\n  UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\n  (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE\n  INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF\n  COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE\n  TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR\n  CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT\n  LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER\n  FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR\n  LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE\n  POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT\n  APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH\n  PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH\n  LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR\n  LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION\n  AND LIMITATION MAY NOT APPLY TO YOU.\n\n8. U.S. GOVERNMENT END USERS.\n\n  The Covered Software is a \"commercial item,\" as that term is defined\n  in 48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer\n  software\" (as that term is defined at 48 C.F.R. §\n  252.227-7014(a)(1)) and \"commercial computer software documentation\"\n  as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent\n  with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4\n  (June 1995), all U.S. Government End Users acquire Covered Software\n  with only those rights set forth herein. This U.S. Government Rights\n  clause is in lieu of, and supersedes, any other FAR, DFAR, or other\n  clause or provision that addresses Government rights in computer\n  software under this License.\n\n9. MISCELLANEOUS.\n\n  This License represents the complete agreement concerning subject\n  matter hereof. If any provision of this License is held to be\n  unenforceable, such provision shall be reformed only to the extent\n  necessary to make it enforceable. This License shall be governed by\n  the law of the jurisdiction specified in a notice contained within\n  the Original Software (except to the extent applicable law, if any,\n  provides otherwise), excluding such jurisdiction's conflict-of-law\n  provisions. Any litigation relating to this License shall be subject\n  to the jurisdiction of the courts located in the jurisdiction and\n  venue specified in a notice contained within the Original Software,\n  with the losing party responsible for costs, including, without\n  limitation, court costs and reasonable attorneys' fees and expenses.\n  The application of the United Nations Convention on Contracts for\n  the International Sale of Goods is expressly excluded. Any law or\n  regulation which provides that the language of a contract shall be\n  construed against the drafter shall not apply to this License. You\n  agree that You alone are responsible for compliance with the United\n  States export administration regulations (and the export control\n  laws and regulation of any other countries) when You use, distribute\n  or otherwise make available any Covered Software.\n\n10. RESPONSIBILITY FOR CLAIMS.\n\n  As between Initial Developer and the Contributors, each party is\n  responsible for claims and damages arising, directly or indirectly,\n  out of its utilization of rights under this License and You agree to\n  work with Initial Developer and Contributors to distribute such\n  responsibility on an equitable basis. Nothing herein is intended or\n  shall be deemed to constitute any admission of liability.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-jsoup",
    "content": "The MIT License\n\nCopyright (c) 2009-2018 Jonathan Hedley <jonathan@hedley.net>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-jsr311-api",
    "content": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.1\n\n1. Definitions.\n\n    1.1. \"Contributor\" means each individual or entity that creates or\n    contributes to the creation of Modifications.\n\n    1.2. \"Contributor Version\" means the combination of the Original\n    Software, prior Modifications used by a Contributor (if any), and\n    the Modifications made by that particular Contributor.\n\n    1.3. \"Covered Software\" means (a) the Original Software, or (b)\n    Modifications, or (c) the combination of files containing Original\n    Software with files containing Modifications, in each case including\n    portions thereof.\n\n    1.4. \"Executable\" means the Covered Software in any form other than\n    Source Code.\n\n    1.5. \"Initial Developer\" means the individual or entity that first\n    makes Original Software available under this License.\n\n    1.6. \"Larger Work\" means a work which combines Covered Software or\n    portions thereof with code not governed by the terms of this License.\n\n    1.7. \"License\" means this document.\n\n    1.8. \"Licensable\" means having the right to grant, to the maximum\n    extent possible, whether at the time of the initial grant or\n    subsequently acquired, any and all of the rights conveyed herein.\n\n    1.9. \"Modifications\" means the Source Code and Executable form of\n    any of the following:\n\n    A. Any file that results from an addition to, deletion from or\n    modification of the contents of a file containing Original Software\n    or previous Modifications;\n\n    B. Any new file that contains any part of the Original Software or\n    previous Modification; or\n\n    C. Any new file that is contributed or otherwise made available\n    under the terms of this License.\n\n    1.10. \"Original Software\" means the Source Code and Executable form\n    of computer software code that is originally released under this\n    License.\n\n    1.11. \"Patent Claims\" means any patent claim(s), now owned or\n    hereafter acquired, including without limitation, method, process,\n    and apparatus claims, in any patent Licensable by grantor.\n\n    1.12. \"Source Code\" means (a) the common form of computer software\n    code in which modifications are made and (b) associated\n    documentation included in or with such code.\n\n    1.13. \"You\" (or \"Your\") means an individual or a legal entity\n    exercising rights under, and complying with all of the terms of,\n    this License. For legal entities, \"You\" includes any entity which\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants.\n\n    2.1. The Initial Developer Grant.\n\n    Conditioned upon Your compliance with Section 3.1 below and subject\n    to third party intellectual property claims, the Initial Developer\n    hereby grants You a world-wide, royalty-free, non-exclusive license:\n\n    (a) under intellectual property rights (other than patent or\n    trademark) Licensable by Initial Developer, to use, reproduce,\n    modify, display, perform, sublicense and distribute the Original\n    Software (or portions thereof), with or without Modifications,\n    and/or as part of a Larger Work; and\n\n    (b) under Patent Claims infringed by the making, using or selling of\n    Original Software, to make, have made, use, practice, sell, and\n    offer for sale, and/or otherwise dispose of the Original Software\n    (or portions thereof).\n\n    (c) The licenses granted in Sections 2.1(a) and (b) are effective on\n    the date Initial Developer first distributes or otherwise makes the\n    Original Software available to a third party under the terms of this\n    License.\n\n    (d) Notwithstanding Section 2.1(b) above, no patent license is\n    granted: (1) for code that You delete from the Original Software, or\n    (2) for infringements caused by: (i) the modification of the\n    Original Software, or (ii) the combination of the Original Software\n    with other software or devices.\n\n    2.2. Contributor Grant.\n\n    Conditioned upon Your compliance with Section 3.1 below and subject\n    to third party intellectual property claims, each Contributor hereby\n    grants You a world-wide, royalty-free, non-exclusive license:\n\n    (a) under intellectual property rights (other than patent or\n    trademark) Licensable by Contributor to use, reproduce, modify,\n    display, perform, sublicense and distribute the Modifications\n    created by such Contributor (or portions thereof), either on an\n    unmodified basis, with other Modifications, as Covered Software\n    and/or as part of a Larger Work; and\n\n    (b) under Patent Claims infringed by the making, using, or selling\n    of Modifications made by that Contributor either alone and/or in\n    combination with its Contributor Version (or portions of such\n    combination), to make, use, sell, offer for sale, have made, and/or\n    otherwise dispose of: (1) Modifications made by that Contributor (or\n    portions thereof); and (2) the combination of Modifications made by\n    that Contributor with its Contributor Version (or portions of such\n    combination).\n\n    (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective\n    on the date Contributor first distributes or otherwise makes the\n    Modifications available to a third party.\n\n    (d) Notwithstanding Section 2.2(b) above, no patent license is\n    granted: (1) for any code that Contributor has deleted from the\n    Contributor Version; (2) for infringements caused by: (i) third\n    party modifications of Contributor Version, or (ii) the combination\n    of Modifications made by that Contributor with other software\n    (except as part of the Contributor Version) or other devices; or (3)\n    under Patent Claims infringed by Covered Software in the absence of\n    Modifications made by that Contributor.\n\n3. Distribution Obligations.\n\n    3.1. Availability of Source Code.\n\n    Any Covered Software that You distribute or otherwise make available\n    in Executable form must also be made available in Source Code form\n    and that Source Code form must be distributed only under the terms\n    of this License. You must include a copy of this License with every\n    copy of the Source Code form of the Covered Software You distribute\n    or otherwise make available. You must inform recipients of any such\n    Covered Software in Executable form as to how they can obtain such\n    Covered Software in Source Code form in a reasonable manner on or\n    through a medium customarily used for software exchange.\n\n    3.2. Modifications.\n\n    The Modifications that You create or to which You contribute are\n    governed by the terms of this License. You represent that You\n    believe Your Modifications are Your original creation(s) and/or You\n    have sufficient rights to grant the rights conveyed by this License.\n\n    3.3. Required Notices.\n\n    You must include a notice in each of Your Modifications that\n    identifies You as the Contributor of the Modification. You may not\n    remove or alter any copyright, patent or trademark notices contained\n    within the Covered Software, or any notices of licensing or any\n    descriptive text giving attribution to any Contributor or the\n    Initial Developer.\n\n    3.4. Application of Additional Terms.\n\n    You may not offer or impose any terms on any Covered Software in\n    Source Code form that alters or restricts the applicable version of\n    this License or the recipients' rights hereunder. You may choose to\n    offer, and to charge a fee for, warranty, support, indemnity or\n    liability obligations to one or more recipients of Covered Software.\n    However, you may do so only on Your own behalf, and not on behalf of\n    the Initial Developer or any Contributor. You must make it\n    absolutely clear that any such warranty, support, indemnity or\n    liability obligation is offered by You alone, and You hereby agree\n    to indemnify the Initial Developer and every Contributor for any\n    liability incurred by the Initial Developer or such Contributor as a\n    result of warranty, support, indemnity or liability terms You offer.\n\n    3.5. Distribution of Executable Versions.\n\n    You may distribute the Executable form of the Covered Software under\n    the terms of this License or under the terms of a license of Your\n    choice, which may contain terms different from this License,\n    provided that You are in compliance with the terms of this License\n    and that the license for the Executable form does not attempt to\n    limit or alter the recipient's rights in the Source Code form from\n    the rights set forth in this License. If You distribute the Covered\n    Software in Executable form under a different license, You must make\n    it absolutely clear that any terms which differ from this License\n    are offered by You alone, not by the Initial Developer or\n    Contributor. You hereby agree to indemnify the Initial Developer and\n    every Contributor for any liability incurred by the Initial\n    Developer or such Contributor as a result of any such terms You offer.\n\n    3.6. Larger Works.\n\n    You may create a Larger Work by combining Covered Software with\n    other code not governed by the terms of this License and distribute\n    the Larger Work as a single product. In such a case, You must make\n    sure the requirements of this License are fulfilled for the Covered\n    Software.\n\n4. Versions of the License.\n\n    4.1. New Versions.\n\n    Oracle is the initial license steward and may publish revised and/or\n    new versions of this License from time to time. Each version will be\n    given a distinguishing version number. Except as provided in Section\n    4.3, no one other than the license steward has the right to modify\n    this License.\n\n    4.2. Effect of New Versions.\n\n    You may always continue to use, distribute or otherwise make the\n    Covered Software available under the terms of the version of the\n    License under which You originally received the Covered Software. If\n    the Initial Developer includes a notice in the Original Software\n    prohibiting it from being distributed or otherwise made available\n    under any subsequent version of the License, You must distribute and\n    make the Covered Software available under the terms of the version\n    of the License under which You originally received the Covered\n    Software. Otherwise, You may also choose to use, distribute or\n    otherwise make the Covered Software available under the terms of any\n    subsequent version of the License published by the license steward.\n\n    4.3. Modified Versions.\n\n    When You are an Initial Developer and You want to create a new\n    license for Your Original Software, You may create and use a\n    modified version of this License if You: (a) rename the license and\n    remove any references to the name of the license steward (except to\n    note that the license differs from this License); and (b) otherwise\n    make it clear that the license contains terms which differ from this\n    License.\n\n5. DISCLAIMER OF WARRANTY.\n\n    COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS,\n    WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\n    INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE\n    IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR\n    NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF\n    THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE\n    DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY\n    OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,\n    REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN\n    ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS\n    AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\n\n6. TERMINATION.\n\n    6.1. This License and the rights granted hereunder will terminate\n    automatically if You fail to comply with terms herein and fail to\n    cure such breach within 30 days of becoming aware of the breach.\n    Provisions which, by their nature, must remain in effect beyond the\n    termination of this License shall survive.\n\n    6.2. If You assert a patent infringement claim (excluding\n    declaratory judgment actions) against Initial Developer or a\n    Contributor (the Initial Developer or Contributor against whom You\n    assert such claim is referred to as \"Participant\") alleging that the\n    Participant Software (meaning the Contributor Version where the\n    Participant is a Contributor or the Original Software where the\n    Participant is the Initial Developer) directly or indirectly\n    infringes any patent, then any and all rights granted directly or\n    indirectly to You by such Participant, the Initial Developer (if the\n    Initial Developer is not the Participant) and all Contributors under\n    Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice\n    from Participant terminate prospectively and automatically at the\n    expiration of such 60 day notice period, unless if within such 60\n    day period You withdraw Your claim with respect to the Participant\n    Software against such Participant either unilaterally or pursuant to\n    a written agreement with Participant.\n\n    6.3. If You assert a patent infringement claim against Participant\n    alleging that the Participant Software directly or indirectly\n    infringes any patent where such claim is resolved (such as by\n    license or settlement) prior to the initiation of patent\n    infringement litigation, then the reasonable value of the licenses\n    granted by such Participant under Sections 2.1 or 2.2 shall be taken\n    into account in determining the amount or value of any payment or\n    license.\n\n    6.4. In the event of termination under Sections 6.1 or 6.2 above,\n    all end user licenses that have been validly granted by You or any\n    distributor hereunder prior to termination (excluding licenses\n    granted to You by any distributor) shall survive termination.\n\n7. LIMITATION OF LIABILITY.\n\n    UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\n    (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE\n    INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF\n    COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE\n    TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR\n    CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT\n    LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER\n    FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR\n    LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE\n    POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT\n    APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH\n    PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH\n    LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR\n    LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION\n    AND LIMITATION MAY NOT APPLY TO YOU.\n\n8. U.S. GOVERNMENT END USERS.\n\n    The Covered Software is a \"commercial item,\" as that term is defined\n    in 48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer\n    software\" (as that term is defined at 48 C.F.R. §\n    252.227-7014(a)(1)) and \"commercial computer software documentation\"\n    as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent\n    with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4\n    (June 1995), all U.S. Government End Users acquire Covered Software\n    with only those rights set forth herein. This U.S. Government Rights\n    clause is in lieu of, and supersedes, any other FAR, DFAR, or other\n    clause or provision that addresses Government rights in computer\n    software under this License.\n\n9. MISCELLANEOUS.\n\n    This License represents the complete agreement concerning subject\n    matter hereof. If any provision of this License is held to be\n    unenforceable, such provision shall be reformed only to the extent\n    necessary to make it enforceable. This License shall be governed by\n    the law of the jurisdiction specified in a notice contained within\n    the Original Software (except to the extent applicable law, if any,\n    provides otherwise), excluding such jurisdiction's conflict-of-law\n    provisions. Any litigation relating to this License shall be subject\n    to the jurisdiction of the courts located in the jurisdiction and\n    venue specified in a notice contained within the Original Software,\n    with the losing party responsible for costs, including, without\n    limitation, court costs and reasonable attorneys' fees and expenses.\n    The application of the United Nations Convention on Contracts for\n    the International Sale of Goods is expressly excluded. Any law or\n    regulation which provides that the language of a contract shall be\n    construed against the drafter shall not apply to this License. You\n    agree that You alone are responsible for compliance with the United\n    States export administration regulations (and the export control\n    laws and regulation of any other countries) when You use, distribute\n    or otherwise make available any Covered Software.\n\n10. RESPONSIBILITY FOR CLAIMS.\n\n    As between Initial Developer and the Contributors, each party is\n    responsible for claims and damages arising, directly or indirectly,\n    out of its utilization of rights under this License and You agree to\n    work with Initial Developer and Contributors to distribute such\n    responsibility on an equitable basis. Nothing herein is intended or\n    shall be deemed to constitute any admission of liability.\n\n------------------------------------------------------------------------\n\nNOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION\nLICENSE (CDDL)\n\nThe code released under the CDDL shall be governed by the laws of the\nState of California (excluding conflict-of-law provisions). Any\nlitigation relating to this License shall be subject to the jurisdiction\nof the Federal Courts of the Northern District of California and the\nstate courts of the State of California, with venue lying in Santa Clara\nCounty, California.\n\n\n\n  The GNU General Public License (GPL) Version 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc.\n51 Franklin Street, Fifth Floor\nBoston, MA 02110-1335\nUSA\n\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\nPreamble\n\nThe licenses for most software are designed to take away your freedom to\nshare and change it. By contrast, the GNU General Public License is\nintended to guarantee your freedom to share and change free software--to\nmake sure the software is free for all its users. This General Public\nLicense applies to most of the Free Software Foundation's software and\nto any other program whose authors commit to using it. (Some other Free\nSoftware Foundation software is covered by the GNU Library General\nPublic License instead.) You can apply it to your programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price.\nOur General Public Licenses are designed to make sure that you have the\nfreedom to distribute copies of free software (and charge for this\nservice if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs; and that you know you can do these things.\n\nTo protect your rights, we need to make restrictions that forbid anyone\nto deny you these rights or to ask you to surrender the rights. These\nrestrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\nFor example, if you distribute copies of such a program, whether gratis\nor for a fee, you must give the recipients all the rights that you have.\nYou must make sure that they, too, receive or can get the source code.\nAnd you must show them these terms so they know their rights.\n\nWe protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\nAlso, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware. If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\nFinally, any free program is threatened constantly by software patents.\nWe wish to avoid the danger that redistributors of a free program will\nindividually obtain patent licenses, in effect making the program\nproprietary. To prevent this, we have made it clear that any patent must\nbe licensed for everyone's free use or not licensed at all.\n\nThe precise terms and conditions for copying, distribution and\nmodification follow.\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License applies to any program or other work which contains a\nnotice placed by the copyright holder saying it may be distributed under\nthe terms of this General Public License. The \"Program\", below, refers\nto any such program or work, and a \"work based on the Program\" means\neither the Program or any derivative work under copyright law: that is\nto say, a work containing the Program or a portion of it, either\nverbatim or with modifications and/or translated into another language.\n(Hereinafter, translation is included without limitation in the term\n\"modification\".) Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope. The act of running\nthe Program is not restricted, and the output from the Program is\ncovered only if its contents constitute a work based on the Program\n(independent of having been made by running the Program). Whether that\nis true depends on what the Program does.\n\n1. You may copy and distribute verbatim copies of the Program's source\ncode as you receive it, in any medium, provided that you conspicuously\nand appropriately publish on each copy an appropriate copyright notice\nand disclaimer of warranty; keep intact all the notices that refer to\nthis License and to the absence of any warranty; and give any other\nrecipients of the Program a copy of this License along with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of the Program or any portion of\nit, thus forming a work based on the Program, and copy and distribute\nsuch modifications or work under the terms of Section 1 above, provided\nthat you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any part\n    thereof, to be licensed as a whole at no charge to all third parties\n    under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a notice\n    that there is no warranty (or else, saying that you provide a\n    warranty) and that users may redistribute the program under these\n    conditions, and telling the user how to view a copy of this License.\n    (Exception: if the Program itself is interactive but does not\n    normally print such an announcement, your work based on the Program\n    is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole. If\nidentifiable sections of that work are not derived from the Program, and\ncan be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works. But when you\ndistribute the same sections as part of a whole which is a work based on\nthe Program, the distribution of the whole must be on the terms of this\nLicense, whose permissions for other licensees extend to the entire\nwhole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of a\nstorage or distribution medium does not bring the other work under the\nscope of this License.\n\n3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections 1\n    and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your cost\n    of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer to\n    distribute corresponding source code. (This alternative is allowed\n    only for noncommercial distribution and only if you received the\n    program in object code or executable form with such an offer, in\n    accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it. For an executable work, complete source code\nmeans all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to control\ncompilation and installation of the executable. However, as a special\nexception, the source code distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies the\nexecutable.\n\nIf distribution of executable or object code is made by offering access\nto copy from a designated place, then offering equivalent access to copy\nthe source code from the same place counts as distribution of the source\ncode, even though third parties are not compelled to copy the source\nalong with the object code.\n\n4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License. Any attempt otherwise\nto copy, modify, sublicense or distribute the Program is void, and will\nautomatically terminate your rights under this License. However, parties\nwho have received copies, or rights, from you under this License will\nnot have their licenses terminated so long as such parties remain in\nfull compliance.\n\n5. You are not required to accept this License, since you have not\nsigned it. However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works. These actions are\nprohibited by law if you do not accept this License. Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and all\nits terms and conditions for copying, distributing or modifying the\nProgram or works based on it.\n\n6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions. You may not impose any further restrictions\non the recipients' exercise of the rights granted herein. You are not\nresponsible for enforcing compliance by third parties to this License.\n\n7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License. If you cannot distribute\nso as to satisfy simultaneously your obligations under this License and\nany other pertinent obligations, then as a consequence you may not\ndistribute the Program at all. For example, if a patent license would\nnot permit royalty-free redistribution of the Program by all those who\nreceive copies directly or indirectly through you, then the only way you\ncould satisfy both it and this License would be to refrain entirely from\ndistribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is implemented\nby public license practices. Many people have made generous\ncontributions to the wide range of software distributed through that\nsystem in reliance on consistent application of that system; it is up to\nthe author/donor to decide if he or she is willing to distribute\nsoftware through any other system and a licensee cannot impose that choice.\n\nThis section is intended to make thoroughly clear what is believed to be\na consequence of the rest of this License.\n\n8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License may\nadd an explicit geographical distribution limitation excluding those\ncountries, so that distribution is permitted only in or among countries\nnot thus excluded. In such case, this License incorporates the\nlimitation as if written in the body of this License.\n\n9. The Free Software Foundation may publish revised and/or new\nversions of the General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number. If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation. If the Program does not specify a version\nnumber of this License, you may choose any version ever published by the\nFree Software Foundation.\n\n10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the\nauthor to ask for permission. For software which is copyrighted by the\nFree Software Foundation, write to the Free Software Foundation; we\nsometimes make exceptions for this. Our decision will be guided by the\ntwo goals of preserving the free status of all derivatives of our free\nsoftware and of promoting the sharing and reuse of software generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND,\nEITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE\nENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH\nYOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL\nNECESSARY SERVICING, REPAIR OR CORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR\nDAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL\nDAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM\n(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED\nINACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF\nTHE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR\nOTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND CONDITIONS\n\nHow to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is safest to\nattach them to the start of each source file to most effectively convey\nthe exclusion of warranty; and each file should have at least the\n\"copyright\" line and a pointer to where the full notice is found.\n\n    One line to give the program's name and a brief idea of what it does.\n    Copyright (C) <year> <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful, but\n    WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n    General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type\n    `show w'. This is free software, and you are welcome to redistribute\n    it under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the\nappropriate parts of the General Public License. Of course, the commands\nyou use may be called something other than `show w' and `show c'; they\ncould even be mouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary. Here is a sample; alter the names:\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the\n    program `Gnomovision' (which makes passes at compilers) written by\n    James Hacker.\n\n    signature of Ty Coon, 1 April 1989\n    Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program\ninto proprietary programs. If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications\nwith the library. If this is what you want to do, use the GNU Library\nGeneral Public License instead of this License.\n\n#\n\nCertain source files distributed by Oracle America, Inc. and/or its\naffiliates are subject to the following clarification and special\nexception to the GPLv2, based on the GNU Project exception for its\nClasspath libraries, known as the GNU Classpath Exception, but only\nwhere Oracle has expressly included in the particular source file's\nheader the words \"Oracle designates this particular file as subject to\nthe \"Classpath\" exception as provided by Oracle in the LICENSE file\nthat accompanied this code.\"\n\nYou should also note that Oracle includes multiple, independent\nprograms in this software package. Some of those programs are provided\nunder licenses deemed incompatible with the GPLv2 by the Free Software\nFoundation and others.  For example, the package includes programs\nlicensed under the Apache License, Version 2.0.  Such programs are\nlicensed to you under their original licenses.\n\nOracle facilitates your further distribution of this package by adding\nthe Classpath Exception to the necessary parts of its GPLv2 code, which\npermits you to use that code in combination with other independent\nmodules not licensed under the GPLv2.  However, note that this would\nnot permit you to commingle code under an incompatible license with\nOracle's GPLv2 licensed code by, for example, cutting and pasting such\ncode into a file also containing Oracle's GPLv2 licensed code and then\ndistributing the result.  Additionally, if you were to remove the\nClasspath Exception from any of the files to which it applies and\ndistribute the result, you would likely be required to license some or\nall of the other code in that distribution under the GPLv2 as well, and\nsince the GPLv2 is incompatible with the license terms of some items\nincluded in the distribution by Oracle, removing the Classpath\nException could therefore effectively compromise your ability to\nfurther distribute the package.\n\nProceed with caution and we recommend that you obtain the advice of a\nlawyer skilled in open source matters before removing the Classpath\nException or making modifications to this package which may\nsubsequently be redistributed and/or involve the use of third party\nsoftware.\n\nCLASSPATH EXCEPTION\nLinking this library statically or dynamically with other modules is\nmaking a combined work based on this library.  Thus, the terms and\nconditions of the GNU General Public License version 2 cover the whole\ncombination.\n\nAs a special exception, the copyright holders of this library give you\npermission to link this library with independent modules to produce an\nexecutable, regardless of the license terms of these independent\nmodules, and to copy and distribute the resulting executable under\nterms of your choice, provided that you also meet, for each linked\nindependent module, the terms and conditions of the license of that\nmodule.  An independent module is a module which is not derived from or\nbased on this library.  If you modify this library, you may extend this\nexception to your version of the library, but you are not obligated to\ndo so.  If you do not wish to do so, delete this exception statement\nfrom your version.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-logback",
    "content": "Logback LICENSE\n---------------\n\nLogback: the reliable, generic, fast and flexible logging framework.\nCopyright (C) 1999-2015, QOS.ch. All rights reserved.\n\nThis program and the accompanying materials are dual-licensed under\neither the terms of the Eclipse Public License v1.0 as published by\nthe Eclipse Foundation\n\n  or (per the licensee's choosing)\n\nunder the terms of the GNU Lesser General Public License version 2.1\nas published by the Free Software Foundation.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-mozilla-v20",
    "content": "Mozilla Public License\nVersion 2.0\n1. Definitions\n1.1. “Contributor”\nmeans each individual or legal entity that creates, contributes to the creation of, or owns Covered Software.\n\n1.2. “Contributor Version”\nmeans the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution.\n\n1.3. “Contribution”\nmeans Covered Software of a particular Contributor.\n\n1.4. “Covered Software”\nmeans 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.\n\n1.5. “Incompatible With Secondary Licenses”\nmeans\n\nthat the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or\n\nthat 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.\n\n1.6. “Executable Form”\nmeans any form of the work other than Source Code Form.\n\n1.7. “Larger Work”\nmeans a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software.\n\n1.8. “License”\nmeans this document.\n\n1.9. “Licensable”\nmeans 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.\n\n1.10. “Modifications”\nmeans any of the following:\n\nany file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or\n\nany new file in Source Code Form that contains any Covered Software.\n\n1.11. “Patent Claims” of a Contributor\nmeans 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.\n\n1.12. “Secondary License”\nmeans 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.\n\n1.13. “Source Code Form”\nmeans the form of the work preferred for making modifications.\n\n1.14. “You” (or “Your”)\nmeans 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.\n\n2. License Grants and Conditions\n2.1. Grants\nEach Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:\n\nunder 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\n\nunder 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.\n\n2.2. Effective Date\nThe 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.\n\n2.3. Limitations on Grant Scope\nThe 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:\n\nfor any code that a Contributor has removed from Covered Software; or\n\nfor 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\n\nunder Patent Claims infringed by Covered Software in the absence of its Contributions.\n\nThis 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).\n\n2.4. Subsequent Licenses\nNo 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).\n\n2.5. Representation\nEach 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.\n\n2.6. Fair Use\nThis License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents.\n\n2.7. Conditions\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1.\n\n3. Responsibilities\n3.1. Distribution of Source Form\nAll 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.\n\n3.2. Distribution of Executable Form\nIf You distribute Covered Software in Executable Form then:\n\nsuch 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\n\nYou 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.\n\n3.3. Distribution of a Larger Work\nYou 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).\n\n3.4. Notices\nYou 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.\n\n3.5. Application of Additional Terms\nYou 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.\n\n4. Inability to Comply Due to Statute or Regulation\nIf 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.\n\n5. Termination\n5.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.\n\n5.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.\n\n5.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.\n\n6. Disclaimer of Warranty\nCovered 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.\n\n7. Limitation of Liability\nUnder 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.\n\n8. Litigation\nAny 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.\n\n9. Miscellaneous\nThis 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.\n\n10. Versions of the License\n10.1. New Versions\nMozilla 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.\n\n10.2. Effect of New Versions\nYou 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.\n\n10.3. Modified Versions\nIf 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).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses\nIf 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.\n\nExhibit A - Source Code Form License Notice\nThis Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.\n\nIf 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.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - “Incompatible With Secondary Licenses” Notice\nThis Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-protobuf",
    "content": "Copyright 2008 Google Inc.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n    * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nCode generated by the Protocol Buffer compiler is owned by the owner\nof the input file used when generating it.  This code is not\nstandalone and requires a support library to be linked with it.  This\nsupport library is itself covered by the above license.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-slf4j",
    "content": "Copyright (c) 2004-2017 QOS.ch\nAll rights reserved.\n\nPermission is hereby granted, free  of charge, to any person obtaining\na  copy  of this  software  and  associated  documentation files  (the\n\"Software\"), to  deal in  the Software without  restriction, including\nwithout limitation  the rights to  use, copy, modify,  merge, publish,\ndistribute,  sublicense, and/or sell  copies of  the Software,  and to\npermit persons to whom the Software  is furnished to do so, subject to\nthe following conditions:\n\nThe  above  copyright  notice  and  this permission  notice  shall  be\nincluded in all copies or substantial portions of the Software.\n\nTHE  SOFTWARE IS  PROVIDED  \"AS  IS\", WITHOUT  WARRANTY  OF ANY  KIND,\nEXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF\nMERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "distribution/src/release/licenses/LICENSE-woodstox-stax2-api",
    "content": "This copy of Stax2 API is licensed under the\nSimplified BSF License (also known as \"2-clause BSD\", or \"FreeBSD License\")\nSee the License for details about distribution rights, and the\nspecific rights regarding derivate works.\n\nYou may obtain a copy of the License at:\n\nhttp://www.opensource.org/licenses/bsd-license.php\n\nwith details of:\n\n<OWNER> = FasterXML.com\n<YEAR> = 2010-\n"
  },
  {
    "path": "distribution/src/release/licenses/NOTICE-apache-commons-codec",
    "content": "Apache Commons Codec\nCopyright 2002-2017 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n\nsrc/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java\ncontains test data from http://aspell.net/test/orig/batch0.tab.\nCopyright (C) 2002 Kevin Atkinson (kevina@gnu.org)\n\n===============================================================================\n\nThe content of package org.apache.commons.codec.language.bm has been translated\nfrom the original php source code available at http://stevemorse.org/phoneticinfo.htm\nwith permission from the original authors.\nOriginal source copyright:\nCopyright (c) 2008 Alexander Beider & Stephen P. Morse.\n"
  },
  {
    "path": "distribution/src/release/licenses/NOTICE-netty",
    "content": "                            The Netty Project\n                            =================\n\nPlease visit the Netty web site for more information:\n\n  * http://netty.io/\n\nCopyright 2014 The Netty Project\n\nThe Netty Project licenses this file to you under the Apache License,\nversion 2.0 (the \"License\"); you may not use this file except in compliance\nwith the License. You may obtain a copy of the License at:\n\n  http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\nWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\nLicense for the specific language governing permissions and limitations\nunder the License.\n\nAlso, please refer to each LICENSE.<component>.txt file, which is located in\nthe 'license' directory of the distribution file, for the license terms of the\ncomponents that this product depends on.\n\n-------------------------------------------------------------------------------\nThis product contains the extensions to Java Collections Framework which has\nbeen derived from the works by JSR-166 EG, Doug Lea, and Jason T. Greene:\n\n  * LICENSE:\n    * license/LICENSE.jsr166y.txt (Public Domain)\n  * HOMEPAGE:\n    * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/\n    * http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/\n\nThis product contains a modified version of Robert Harder's Public Domain\nBase64 Encoder and Decoder, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.base64.txt (Public Domain)\n  * HOMEPAGE:\n    * http://iharder.sourceforge.net/current/java/base64/\n\nThis product contains a modified portion of 'Webbit', an event based\nWebSocket and HTTP server, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.webbit.txt (BSD License)\n  * HOMEPAGE:\n    * https://github.com/joewalnes/webbit\n\nThis product contains a modified portion of 'SLF4J', a simple logging\nfacade for Java, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.slf4j.txt (MIT License)\n  * HOMEPAGE:\n    * http://www.slf4j.org/\n\nThis product contains a modified portion of 'Apache Harmony', an open source\nJava SE, which can be obtained at:\n\n  * NOTICE:\n    * license/NOTICE.harmony.txt\n  * LICENSE:\n    * license/LICENSE.harmony.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * http://archive.apache.org/dist/harmony/\n\nThis product contains a modified portion of 'jbzip2', a Java bzip2 compression\nand decompression library written by Matthew J. Francis. It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.jbzip2.txt (MIT License)\n  * HOMEPAGE:\n    * https://code.google.com/p/jbzip2/\n\nThis product contains a modified portion of 'libdivsufsort', a C API library to construct\nthe suffix array and the Burrows-Wheeler transformed string for any input string of\na constant-size alphabet written by Yuta Mori. It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.libdivsufsort.txt (MIT License)\n  * HOMEPAGE:\n    * https://github.com/y-256/libdivsufsort\n\nThis product contains a modified portion of Nitsan Wakart's 'JCTools', Java Concurrency Tools for the JVM,\n which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.jctools.txt (ASL2 License)\n  * HOMEPAGE:\n    * https://github.com/JCTools/JCTools\n\nThis product optionally depends on 'JZlib', a re-implementation of zlib in\npure Java, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.jzlib.txt (BSD style License)\n  * HOMEPAGE:\n    * http://www.jcraft.com/jzlib/\n\nThis product optionally depends on 'Compress-LZF', a Java library for encoding and\ndecoding data in LZF format, written by Tatu Saloranta. It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.compress-lzf.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://github.com/ning/compress\n\nThis product optionally depends on 'lz4', a LZ4 Java compression\nand decompression library written by Adrien Grand. It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.lz4.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://github.com/jpountz/lz4-java\n\nThis product optionally depends on 'lzma-java', a LZMA Java compression\nand decompression library, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.lzma-java.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://github.com/jponge/lzma-java\n\nThis product contains a modified portion of 'jfastlz', a Java port of FastLZ compression\nand decompression library written by William Kinney. It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.jfastlz.txt (MIT License)\n  * HOMEPAGE:\n    * https://code.google.com/p/jfastlz/\n\nThis product contains a modified portion of and optionally depends on 'Protocol Buffers', Google's data\ninterchange format, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.protobuf.txt (New BSD License)\n  * HOMEPAGE:\n    * https://github.com/google/protobuf\n\nThis product optionally depends on 'Bouncy Castle Crypto APIs' to generate\na temporary self-signed X.509 certificate when the JVM does not provide the\nequivalent functionality.  It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.bouncycastle.txt (MIT License)\n  * HOMEPAGE:\n    * http://www.bouncycastle.org/\n\nThis product optionally depends on 'Snappy', a compression library produced\nby Google Inc, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.snappy.txt (New BSD License)\n  * HOMEPAGE:\n    * https://github.com/google/snappy\n\nThis product optionally depends on 'JBoss Marshalling', an alternative Java\nserialization API, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.jboss-marshalling.txt (GNU LGPL 2.1)\n  * HOMEPAGE:\n    * http://www.jboss.org/jbossmarshalling\n\nThis product optionally depends on 'Caliper', Google's micro-\nbenchmarking framework, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.caliper.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://github.com/google/caliper\n\nThis product optionally depends on 'Apache Commons Logging', a logging\nframework, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.commons-logging.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * http://commons.apache.org/logging/\n\nThis product optionally depends on 'Apache Log4J', a logging framework, which\ncan be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.log4j.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * http://logging.apache.org/log4j/\n\nThis product optionally depends on 'Aalto XML', an ultra-high performance\nnon-blocking XML processor, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.aalto-xml.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * http://wiki.fasterxml.com/AaltoHome\n\nThis product contains a modified version of 'HPACK', a Java implementation of\nthe HTTP/2 HPACK algorithm written by Twitter. It can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.hpack.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://github.com/twitter/hpack\n\nThis product contains a modified portion of 'Apache Commons Lang', a Java library\nprovides utilities for the java.lang API, which can be obtained at:\n\n  * LICENSE:\n    * license/LICENSE.commons-lang.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://commons.apache.org/proper/commons-lang/\n\n\nThis product contains the Maven wrapper scripts from 'Maven Wrapper', that provides an easy way to ensure a user has everything necessary to run the Maven build.\n\n  * LICENSE:\n    * license/LICENSE.mvn-wrapper.txt (Apache License 2.0)\n  * HOMEPAGE:\n    * https://github.com/takari/maven-wrapper\n"
  },
  {
    "path": "distribution/src/release/licenses/NOTICE-prometheus",
    "content": "Prometheus instrumentation library for JVM applications\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nBoxever Ltd. (http://www.boxever.com/).\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\nThis product includes software developed as part of the\nOcelli project by Netflix Inc. (https://github.com/Netflix/ocelli/).\n"
  },
  {
    "path": "distribution/src/release/licenses/NOTICE-protostuff",
    "content": "==============================================================\n protostuff\n Copyright 2009 David Yu dyuproject@gmail.com\n==============================================================\n\nprotobuf is copyright Google inc unless otherwise noted.\nIt is licensed under the BSD license.\n\njackson-core-asl is copyright FasterXml unless otherwise noted.\nIt is licensed under the apache 2.0 license.\n\nantlr is copyright Terence Parr unless otherwise noted.\nIt is licensed under the BSD license.\n\nstringtemplate is copyright Terence Parr unless otherwise noted.\nIt is licensed under the BSD license.\n\nvelocity is licensed under the apache 2.0 license.\n\nB64Code.java is copyright Mort Bay Consulting Pty Ltd unless otherwise noted.\nIt is licensed under the apache 2.0 license.\n\njarjar is copyright Google inc unless otherwise noted.\nIt is licensed under the apache 2.0 license.\n\nguava is copyright Google inc unless otherwise noted.\nIt is licensed under the apache 2.0 license.\n"
  },
  {
    "path": "distribution/src/release/licenses/NOTICE-tomcat",
    "content": "Apache Tomcat\nCopyright 1999-2018 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n\nThis software contains code derived from netty-native\ndeveloped by the Netty project\n(http://netty.io, https://github.com/netty/netty-tcnative/)\nand from finagle-native developed at Twitter\n(https://github.com/twitter/finagle).\n\nThe Windows Installer is built with the Nullsoft\nScriptable Install System (NSIS), which is\nopen source software.  The original software and\nrelated information is available at\nhttp://nsis.sourceforge.net.\n\nJava compilation software for JSP pages is provided by the Eclipse\nJDT Core Batch Compiler component, which is open source software.\nThe original software and related information is available at\nhttp://www.eclipse.org/jdt/core/.\n\nFor portions of the Tomcat JNI OpenSSL API and the OpenSSL JSSE integration\nThe org.apache.tomcat.jni and the org.apache.tomcat.net.openssl packages\nare derivative work originating from the Netty project and the finagle-native\nproject developed at Twitter\n* Copyright 2014 The Netty Project\n* Copyright 2014 Twitter\n\nThe original XML Schemas for Java EE Deployment Descriptors:\n - javaee_5.xsd\n - javaee_web_services_1_2.xsd\n - javaee_web_services_client_1_2.xsd\n - javaee_6.xsd\n - javaee_web_services_1_3.xsd\n - javaee_web_services_client_1_3.xsd\n - jsp_2_2.xsd\n - web-app_3_0.xsd\n - web-common_3_0.xsd\n - web-fragment_3_0.xsd\n - javaee_7.xsd\n - javaee_web_services_1_4.xsd\n - javaee_web_services_client_1_4.xsd\n - jsp_2_3.xsd\n - web-app_3_1.xsd\n - web-common_3_1.xsd\n - web-fragment_3_1.xsd\n - javaee_8.xsd\n - web-app_4_0.xsd\n - web-common_4_0.xsd\n - web-fragment_4_0.xsd\n\nmay be obtained from:\nhttp://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html\n"
  },
  {
    "path": "dynamic-config/config-apollo/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>dynamic-config</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>config-apollo</artifactId>\n  <name>Java Chassis::Dynamic Config::Apollo</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-web</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/java/org/apache/servicecomb/config/apollo/ApolloClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.apollo;\n\nimport static org.apache.servicecomb.config.apollo.ConfigurationAction.CREATE;\nimport static org.apache.servicecomb.config.apollo.ConfigurationAction.DELETE;\nimport static org.apache.servicecomb.config.apollo.ConfigurationAction.SET;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.config.apollo.ApolloDynamicPropertiesSource.UpdateHandler;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.client.RestTemplate;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.netty.handler.codec.http.HttpResponseStatus;\n\npublic class ApolloClient {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ApolloClient.class);\n\n  private static final Map<String, Object> originalConfigMap = new ConcurrentHashMap<>();\n\n  private static final ScheduledExecutorService EXECUTOR = Executors.newScheduledThreadPool(1);\n\n  private final ApolloConfig apolloConfig;\n\n  private final UpdateHandler updateHandler;\n\n  private static RestTemplate rest = new RestTemplate();\n\n  public ApolloClient(UpdateHandler updateHandler, ApolloConfig apolloConfig) {\n    this.updateHandler = updateHandler;\n    this.apolloConfig = apolloConfig;\n  }\n\n  @VisibleForTesting\n  static Map<String, Object> getOriginalConfigMap() {\n    return originalConfigMap;\n  }\n\n  @VisibleForTesting\n  static void setRest(RestTemplate rest) {\n    ApolloClient.rest = rest;\n  }\n\n  public void refreshApolloConfig() {\n    EXECUTOR.scheduleWithFixedDelay(new ConfigRefresh(apolloConfig.getServerUri()),\n        apolloConfig.getFirstRefreshInterval(),\n        apolloConfig.getRefreshInterval(), TimeUnit.SECONDS);\n  }\n\n  class ConfigRefresh implements Runnable {\n    private final String serviceUri;\n\n    ConfigRefresh(String serviceUris) {\n      this.serviceUri = serviceUris;\n    }\n\n    @Override\n    public void run() {\n      try {\n        refreshConfig();\n      } catch (Throwable e) {\n        LOGGER.error(\"client refresh thread exception \", e);\n      }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    void refreshConfig() {\n      HttpHeaders headers = new HttpHeaders();\n      headers.add(\"Content-Type\", \"application/json;charset=UTF-8\");\n      headers.add(\"Authorization\", apolloConfig.getToken());\n      HttpEntity<String> entity = new HttpEntity<>(headers);\n      ResponseEntity<String> exchange = rest.exchange(composeAPI(), HttpMethod.GET, entity, String.class);\n      if (HttpResponseStatus.OK.code() == exchange.getStatusCode().value()) {\n        try {\n          Map<String, Object> body = JsonUtils.OBJ_MAPPER.readValue(exchange.getBody(),\n              new TypeReference<Map<String, Object>>() {\n              });\n          refreshConfigItems((Map<String, Object>) body.get(\"configurations\"));\n        } catch (IOException e) {\n          LOGGER.error(\"JsonObject parse config center response error: \", e);\n        }\n      } else {\n        LOGGER.error(\"fetch configuration failed, error code:{} for {}\",\n            exchange.getStatusCode().value(),\n            exchange.getBody());\n      }\n    }\n\n    private String composeAPI() {\n      String api = serviceUri + \"/openapi/v1/envs/\" + apolloConfig.getEnv() +\n          \"/apps/\" + apolloConfig.getServiceName() +\n          \"/clusters/\" + apolloConfig.getServerClusters() +\n          \"/namespaces/\" + apolloConfig.getNamespace() +\n          \"/releases/latest\";\n      return api;\n    }\n\n    private void refreshConfigItems(Map<String, Object> map) {\n      compareChangedConfig(originalConfigMap, map);\n      originalConfigMap.clear();\n      originalConfigMap.putAll(map);\n    }\n\n    void compareChangedConfig(Map<String, Object> before, Map<String, Object> after) {\n      Map<String, Object> itemsCreated = new HashMap<>();\n      Map<String, Object> itemsDeleted = new HashMap<>();\n      Map<String, Object> itemsModified = new HashMap<>();\n      if (before == null || before.isEmpty()) {\n        updateHandler.handle(CREATE, after);\n        return;\n      }\n      if (after == null || after.isEmpty()) {\n        updateHandler.handle(DELETE, before);\n        return;\n      }\n      after.forEach((itemKey, itemValue) -> {\n        if (!before.containsKey(itemKey)) {\n          itemsCreated.put(itemKey, itemValue);\n        } else if (!itemValue.equals(before.get(itemKey))) {\n          itemsModified.put(itemKey, itemValue);\n        }\n      });\n      for (String itemKey : before.keySet()) {\n        if (!after.containsKey(itemKey)) {\n          itemsDeleted.put(itemKey, \"\");\n        }\n      }\n      updateHandler.handle(CREATE, itemsCreated);\n      updateHandler.handle(SET, itemsModified);\n      updateHandler.handle(DELETE, itemsDeleted);\n    }\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/java/org/apache/servicecomb/config/apollo/ApolloConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.apollo;\n\nimport org.springframework.core.env.Environment;\n\npublic class ApolloConfig {\n  private static final String SERVER_URL_KEY = \"apollo.config.serverUri\";\n\n  private static final String SERVER_NAMESPACE = \"apollo.config.namespace\";\n\n  private static final String SERVER_ENV = \"apollo.config.env\";\n\n  private static final String SERVER_CLUSTERS = \"apollo.config.clusters\";\n\n  private static final String APOLLO_SERVICE_NAME = \"apollo.config.serviceName\";\n\n  private static final String TOKEN = \"apollo.config.token\";\n\n  private static final String REFRESH_INTERVAL = \"apollo.config.refreshInterval\";\n\n  private static final String FIRST_REFRESH_INTERVAL = \"apollo.config.firstRefreshInterval\";\n\n  private static final int DEFAULT_REFRESH_INTERVAL = 3;\n\n  private static final int DEFAULT_FIRST_REFRESH_INTERVAL = 0;\n\n  private final Environment environment;\n\n  public ApolloConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getServiceName() {\n    return environment.getProperty(APOLLO_SERVICE_NAME);\n  }\n\n  public String getServerUri() {\n    return environment.getProperty(SERVER_URL_KEY);\n  }\n\n  public String getToken() {\n    return environment.getProperty(TOKEN);\n  }\n\n  public String getEnv() {\n    return environment.getProperty(SERVER_ENV);\n  }\n\n  public String getNamespace() {\n    return environment.getProperty(SERVER_NAMESPACE);\n  }\n\n  public String getServerClusters() {\n    return environment.getProperty(SERVER_CLUSTERS);\n  }\n\n  public int getRefreshInterval() {\n    return environment.getProperty(REFRESH_INTERVAL, int.class, DEFAULT_REFRESH_INTERVAL);\n  }\n\n  public int getFirstRefreshInterval() {\n    return environment.getProperty(FIRST_REFRESH_INTERVAL, int.class, DEFAULT_FIRST_REFRESH_INTERVAL);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/java/org/apache/servicecomb/config/apollo/ApolloConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.apollo;\n\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ApolloConfiguration {\n\n}\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/java/org/apache/servicecomb/config/apollo/ApolloDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.apollo;\n\nimport static org.apache.servicecomb.config.apollo.ConfigurationAction.CREATE;\nimport static org.apache.servicecomb.config.apollo.ConfigurationAction.DELETE;\nimport static org.apache.servicecomb.config.apollo.ConfigurationAction.SET;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.servicecomb.config.ConfigMapping;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\npublic class ApolloDynamicPropertiesSource implements DynamicPropertiesSource {\n  public static final String SOURCE_NAME = \"apollo\";\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ApolloDynamicPropertiesSource.class);\n\n  private final Map<String, Object> valueCache = new ConcurrentHashMap<>();\n\n  private final ApolloDynamicPropertiesSource.UpdateHandler updateHandler =\n      new ApolloDynamicPropertiesSource.UpdateHandler();\n\n  public ApolloDynamicPropertiesSource() {\n  }\n\n  @Override\n  public int getOrder() {\n    return 300;\n  }\n\n  private void init(Environment environment) {\n    ApolloConfig apolloConfig = new ApolloConfig(environment);\n    ApolloClient apolloClient = new ApolloClient(updateHandler, apolloConfig);\n    apolloClient.refreshApolloConfig();\n  }\n\n  public class UpdateHandler {\n    public void handle(ConfigurationAction action, Map<String, Object> config) {\n      if (config == null || config.isEmpty()) {\n        return;\n      }\n      Map<String, Object> configuration = ConfigMapping.getConvertedMap(config);\n      if (CREATE.equals(action)) {\n        valueCache.putAll(configuration);\n      } else if (SET.equals(action)) {\n        valueCache.putAll(configuration);\n      } else if (DELETE.equals(action)) {\n        configuration.keySet().forEach(valueCache::remove);\n      } else {\n        LOGGER.error(\"action: {} is invalid.\", action.name());\n        return;\n      }\n      LOGGER.warn(\"Config value cache changed: action:{}; item:{}\", action.name(), configuration.keySet());\n    }\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    init(environment);\n    return new MapPropertySource(SOURCE_NAME, valueCache);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/java/org/apache/servicecomb/config/apollo/ConfigurationAction.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.apollo;\n\npublic enum ConfigurationAction {\n  CREATE,\n  SET,\n  DELETE\n}\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.apollo.ApolloDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.config.apollo.ApolloConfiguration\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/test/java/org/apache/servicecomb/config/apollo/ApolloClientTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.apollo;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.apollo.ApolloClient.ConfigRefresh;\nimport org.apache.servicecomb.config.apollo.ApolloDynamicPropertiesSource.UpdateHandler;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.ArgumentMatchers;\nimport org.mockito.Mockito;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.client.RestTemplate;\n\npublic class ApolloClientTest {\n  @BeforeAll\n  public static void setUpClass() {\n\n  }\n\n  @Test\n  public void refreshApolloConfig() {\n    ApolloConfig apolloConfig = Mockito.mock(ApolloConfig.class);\n    RestTemplate rest = Mockito.mock(RestTemplate.class);\n    ApolloClient.setRest(rest);\n\n    ResponseEntity<String> responseEntity = new ResponseEntity<>(\n        \"{\\\"apollo\\\":\\\"mocked\\\", \\\"configurations\\\":{\\\"timeout\\\":1000}}\", HttpStatus.OK);\n    Mockito.when(rest.exchange(\n        ArgumentMatchers.anyString(),\n        ArgumentMatchers.any(HttpMethod.class),\n        ArgumentMatchers.<HttpEntity<String>>any(),\n        ArgumentMatchers.<Class<String>>any())).thenReturn(responseEntity);\n    ApolloDynamicPropertiesSource impl = new ApolloDynamicPropertiesSource();\n    UpdateHandler updateHandler = impl.new UpdateHandler();\n    ApolloClient apolloClient = new ApolloClient(updateHandler, apolloConfig);\n    ConfigRefresh cr = apolloClient.new ConfigRefresh(apolloConfig.getServerUri());\n    cr.run();\n\n    Assertions.assertEquals(1, ApolloClient.getOriginalConfigMap().size());\n  }\n\n  @Test\n  public void testCompareChangedConfig() {\n    ApolloConfig apolloConfig = Mockito.mock(ApolloConfig.class);\n    boolean status = true;\n    Map<String, Object> before = new HashMap<>();\n    Map<String, Object> after = new HashMap<>();\n\n    ApolloDynamicPropertiesSource impl = new ApolloDynamicPropertiesSource();\n    UpdateHandler updateHandler = impl.new UpdateHandler();\n    ApolloClient apolloClient = new ApolloClient(updateHandler, apolloConfig);\n\n    ConfigRefresh cr = apolloClient.new ConfigRefresh(\"\");\n\n    try {\n      cr.compareChangedConfig(before, after);\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertTrue(status);\n\n    before.put(\"test\", \"testValue\");\n    try {\n      cr.compareChangedConfig(before, after);\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertTrue(status);\n\n    after.put(\"test\", \"testValue2\");\n    try {\n      cr.compareChangedConfig(before, after);\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertTrue(status);\n\n    try {\n      cr.compareChangedConfig(before, after);\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertTrue(status);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-apollo/src/test/resources/microservice.yaml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nAPPLICATION_ID: apollotest\nservice_description:\n  name: apollo-test\n  version: 1.0.1\n\napollo:\n  config:\n    serverUri: http://127.0.0.1:8070\n    serviceName: apollo-test\n    env: DEV\n    clusters: test-cluster\n    namespace: application\n    token: xxx\n    refreshInterval: 30\n    firstRefreshInterval: 0\n\nservicecomb:\n  service:\n    registry:\n      address: http://127.0.0.1:30100\n  rest:\n    address: 0.0.0.0:8080\n  highway:\n    address: 0.0.0.0:7070\n"
  },
  {
    "path": "dynamic-config/config-cc/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>dynamic-config</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>config-cc</artifactId>\n  <name>Java Chassis::Foundations::Config CC</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-ssl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n      <dependency>\n          <groupId>org.apache.servicecomb</groupId>\n          <artifactId>java-chassis-core</artifactId>\n      </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-center-client</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.cc;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.foundation.vertx.VertxConst;\nimport org.springframework.core.env.Environment;\n\npublic final class ConfigCenterConfig {\n  public static final String SSL_TAG = \"cc.consumer\";\n\n  private static final String ADDRESS = \"servicecomb.config.client.serverUri\";\n\n  private static final String DOMAIN_NAME = \"servicecomb.config.client.domainName\";\n\n  private static final String REFRESH_INTERVAL = \"servicecomb.config.client.refresh_interval\";\n\n  private static final String FIRST_PULL_REQUIRED = \"servicecomb.config.client.firstPullRequired\";\n\n  public static final String FILE_SOURCE = \"servicecomb.config.client.fileSource\";\n\n  private static final int DEFAULT_REFRESH_INTERVAL = 15000;\n\n  private static final String CLIENT_CONNECT_TIMEOUT = \"servicecomb.config.client.timeout.connect\";\n\n  private static final String CLIENT_REQUEST_TIMEOUT = \"servicecomb.config.client.timeout.request\";\n\n  private static final String CLIENT_SOCKET_TIMEOUT = \"servicecomb.config.client.timeout.socket\";\n\n  private final Environment environment;\n\n  public ConfigCenterConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getDomainName() {\n    return environment.getProperty(DOMAIN_NAME, \"default\");\n  }\n\n  public boolean firstPullRequired() {\n    return environment.getProperty(FIRST_PULL_REQUIRED, boolean.class, false);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public List<String> getFileSources() {\n    return environment.getProperty(FILE_SOURCE, List.class, Collections.emptyList());\n  }\n\n  public long getRefreshInterval() {\n    return environment.getProperty(\n        REFRESH_INTERVAL, long.class, (long) DEFAULT_REFRESH_INTERVAL);\n  }\n\n  public Boolean isProxyEnable() {\n    return environment.getProperty(VertxConst.PROXY_ENABLE, boolean.class, false);\n  }\n\n  public String getProxyHost() {\n    return environment.getProperty(VertxConst.PROXY_HOST, \"127.0.0.1\");\n  }\n\n  public int getProxyPort() {\n    return environment.getProperty(VertxConst.PROXY_PORT, int.class, 8080);\n  }\n\n  public String getProxyUsername() {\n    return environment.getProperty(VertxConst.PROXY_USERNAME);\n  }\n\n  public String getProxyPasswd() {\n    return environment.getProperty(VertxConst.PROXY_PASSWD);\n  }\n\n  public List<String> getServerUri() {\n    return ConfigUtil.parseArrayValue(environment.getProperty(ADDRESS, \"\"));\n  }\n\n  public int getConnectTimeout() {\n    return environment.getProperty(CLIENT_CONNECT_TIMEOUT, int.class, 5000);\n  }\n\n  public int getConnectionRequestTimeout() {\n    return environment.getProperty(CLIENT_REQUEST_TIMEOUT,  int.class, 5000);\n  }\n\n  public int getSocketTimeout() {\n    return environment.getProperty(CLIENT_SOCKET_TIMEOUT,  int.class, 5000);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.cc;\n\nimport org.springframework.context.annotation.Bean;\n\npublic class ConfigCenterConfiguration {\n  @Bean\n  public ConfigCenterInformationCollector configCenterInformationCollector() {\n    return new ConfigCenterInformationCollector();\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.cc;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.apache.servicecomb.config.center.client.ConfigCenterAddressManager;\nimport org.apache.servicecomb.config.center.client.ConfigCenterClient;\nimport org.apache.servicecomb.config.center.client.ConfigCenterConfigurationChangedEvent;\nimport org.apache.servicecomb.config.center.client.ConfigCenterManager;\nimport org.apache.servicecomb.config.center.client.model.ConfigCenterConfiguration;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsRequest;\nimport org.apache.servicecomb.config.center.client.model.QueryConfigurationsResponse;\nimport org.apache.servicecomb.config.common.ConfigConverter;\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpTransportFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic class ConfigCenterDynamicPropertiesSource implements DynamicPropertiesSource {\n  public static final String SOURCE_NAME = \"config-center\";\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConfigCenterDynamicPropertiesSource.class);\n\n  private final Map<String, Object> data = new ConcurrentHashMapEx<>();\n\n  private ConfigConverter configConverter;\n\n  public ConfigCenterDynamicPropertiesSource() {\n  }\n\n  private void init(Environment environment) {\n    ConfigCenterConfig configCenterConfig = new ConfigCenterConfig(environment);\n    configConverter = new ConfigConverter(configCenterConfig.getFileSources());\n\n    ConfigCenterAddressManager configCenterAddressManager = configCenterAddressManager(configCenterConfig, environment);\n\n    HttpTransport httpTransport = createHttpTransport(configCenterAddressManager,\n        buildRequestConfig(configCenterConfig), environment, configCenterConfig);\n    ConfigCenterClient configCenterClient = new ConfigCenterClient(configCenterAddressManager, httpTransport);\n    EventManager.register(this);\n\n    ConfigCenterConfiguration configCenterConfiguration =\n        createConfigCenterConfiguration(configCenterConfig);\n\n    QueryConfigurationsRequest queryConfigurationsRequest = firstPull(configCenterConfig, configCenterClient,\n        environment, configCenterAddressManager);\n\n    ConfigCenterManager configCenterManager = new ConfigCenterManager(configCenterClient, EventManager.getEventBus(),\n        configConverter, configCenterConfiguration, configCenterAddressManager);\n    configCenterManager.setQueryConfigurationsRequest(queryConfigurationsRequest);\n    configCenterManager.startConfigCenterManager();\n    data.putAll(configConverter.getCurrentData());\n  }\n\n  private RequestConfig buildRequestConfig(ConfigCenterConfig config) {\n    RequestConfig.Builder builder = HttpTransportFactory.defaultRequestConfig();\n    builder.setConnectTimeout(config.getConnectTimeout());\n    builder.setConnectionRequestTimeout(config.getConnectionRequestTimeout());\n    builder.setSocketTimeout(config.getSocketTimeout());\n    return builder.build();\n  }\n\n  private QueryConfigurationsRequest firstPull(ConfigCenterConfig configCenterConfig,\n      ConfigCenterClient configCenterClient, Environment environment,\n      ConfigCenterAddressManager configCenterAddressManager) {\n    QueryConfigurationsRequest queryConfigurationsRequest = createQueryConfigurationsRequest(environment);\n    try {\n      QueryConfigurationsResponse response = configCenterClient\n          .queryConfigurations(queryConfigurationsRequest, configCenterAddressManager.address());\n      if (response.isChanged()) {\n        configConverter.updateData(response.getConfigurations());\n        queryConfigurationsRequest.setRevision(response.getRevision());\n      }\n    } catch (Exception e) {\n      if (configCenterConfig.firstPullRequired()) {\n        throw e;\n      }\n      LOGGER.warn(\"first pull failed, and ignore {}\", e.getMessage());\n    }\n    return queryConfigurationsRequest;\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigCenterConfigurationChangedEvent event) {\n    LOGGER.info(\"Dynamic configuration changed: {}\", event.getChanged());\n    data.putAll(event.getAdded());\n    data.putAll(event.getUpdated());\n    event.getDeleted().forEach((k, v) -> data.remove(k));\n    EventManager.post(ConfigurationChangedEvent.createIncremental(event.getAdded(),\n        event.getUpdated(), event.getDeleted()));\n  }\n\n  private QueryConfigurationsRequest createQueryConfigurationsRequest(Environment environment) {\n    QueryConfigurationsRequest request = new QueryConfigurationsRequest();\n    request.setApplication(BootStrapProperties.readApplication(environment));\n    request.setServiceName(BootStrapProperties.readServiceName(environment));\n    request.setVersion(BootStrapProperties.readServiceVersion(environment));\n    request.setEnvironment(BootStrapProperties.readServiceEnvironment(environment));\n    // 需要设置为 null， 并且 query 参数为 revision=null 才会返回 revision 信息。 revision = 是不行的。\n    request.setRevision(null);\n    return request;\n  }\n\n  private ConfigCenterConfiguration createConfigCenterConfiguration(\n      ConfigCenterConfig configCenterConfig) {\n    return new ConfigCenterConfiguration().setRefreshIntervalInMillis(configCenterConfig.getRefreshInterval());\n  }\n\n  private HttpTransport createHttpTransport(ConfigCenterAddressManager configCenterAddressManager,\n      RequestConfig requestConfig,\n      Environment environment, ConfigCenterConfig configCenterConfig) {\n    List<AuthHeaderProvider> authHeaderProviders = SPIServiceUtils.getOrLoadSortedService(AuthHeaderProvider.class);\n\n    if (configCenterConfig.isProxyEnable()) {\n      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().\n          setDefaultRequestConfig(requestConfig);\n      HttpHost proxy = new HttpHost(configCenterConfig.getProxyHost(),\n          configCenterConfig.getProxyPort(), \"http\");  // now only support http proxy\n      httpClientBuilder.setProxy(proxy);\n      CredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n      credentialsProvider.setCredentials(new AuthScope(proxy),\n          new UsernamePasswordCredentials(configCenterConfig.getProxyUsername(),\n              configCenterConfig.getProxyPasswd()));\n      httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n\n      return HttpTransportFactory\n          .createHttpTransport(\n              TransportUtils\n                  .createSSLProperties(configCenterAddressManager.sslEnabled(), environment, ConfigCenterConfig.SSL_TAG),\n              getRequestAuthHeaderProvider(authHeaderProviders), httpClientBuilder);\n    }\n\n    return HttpTransportFactory\n        .createHttpTransport(\n            TransportUtils\n                .createSSLProperties(configCenterAddressManager.sslEnabled(), environment, ConfigCenterConfig.SSL_TAG),\n            getRequestAuthHeaderProvider(authHeaderProviders), requestConfig);\n  }\n\n  private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {\n    return signRequest -> {\n      String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : \"\";\n      Map<String, String> headers = new HashMap<>();\n      authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host)));\n      return headers;\n    };\n  }\n\n  private ConfigCenterAddressManager configCenterAddressManager(ConfigCenterConfig configCenterConfig, Environment environment) {\n    String region = environment.getProperty(\"servicecomb.datacenter.region\");\n    String availableZone = environment.getProperty(\"servicecomb.datacenter.availableZone\");\n    return new ConfigCenterAddressManager(configCenterConfig.getDomainName(),\n        configCenterConfig.getServerUri(), EventManager.getEventBus(), region, availableZone);\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    init(environment);\n    return new MapPropertySource(SOURCE_NAME, data);\n  }\n\n  @Override\n  public int getOrder() {\n    return 200;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterInformationCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.cc;\n\nimport org.apache.servicecomb.core.bootup.BootUpInformationCollector;\nimport org.springframework.context.EnvironmentAware;\nimport org.springframework.core.env.Environment;\nimport org.springframework.lang.NonNull;\n\n\npublic class ConfigCenterInformationCollector implements BootUpInformationCollector, EnvironmentAware {\n  private ConfigCenterConfig configCenterConfig;\n\n  @Override\n  public void setEnvironment(@NonNull Environment environment) {\n    this.configCenterConfig = new ConfigCenterConfig(environment);\n  }\n\n  @Override\n  public String collect() {\n    return \"Config Center: \" + configCenterConfig.getServerUri();\n  }\n\n  @Override\n  public int getOrder() {\n    return 1;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/TransportUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.cc;\n\nimport static org.apache.servicecomb.foundation.ssl.SSLOption.DEFAULT_OPTION;\n\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.springframework.core.env.Environment;\n\npublic class TransportUtils {\n  public static SSLProperties createSSLProperties(boolean sslEnabled, Environment environment, String tag) {\n    SSLProperties sslProperties = new SSLProperties();\n    sslProperties.setEnabled(sslEnabled);\n\n    if (!sslEnabled) {\n      return sslProperties;\n    }\n\n    SSLOption option = new SSLOption();\n    option.setEngine(getStringProperty(environment,\n        DEFAULT_OPTION.getEngine(),\n        \"ssl.\" + tag + \".engine\",\n        \"ssl.engine\"));\n    option.setProtocols(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getProtocols(),\n            \"ssl.\" + tag + \".protocols\",\n            \"ssl.protocols\"));\n    option.setCiphers(\n        getStringProperty(environment, DEFAULT_OPTION.getCiphers(), \"ssl.\" + tag + \".ciphers\", \"ssl.ciphers\"));\n    option.setAuthPeer(\n        getBooleanProperty(environment, DEFAULT_OPTION.isAuthPeer(), \"ssl.\" + tag + \".authPeer\", \"ssl.authPeer\"));\n    option.setCheckCNHost(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNHost(),\n            \"ssl.\" + tag + \".checkCN.host\",\n            \"ssl.checkCN.host\"));\n    option.setCheckCNWhite(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNWhite(),\n            \"ssl.\" + tag + \".checkCN.white\",\n            \"ssl.checkCN.white\"));\n    option.setCheckCNWhiteFile(getStringProperty(environment,\n        DEFAULT_OPTION.getCiphers(),\n        \"ssl.\" + tag + \".checkCN.white.file\",\n        \"ssl.checkCN.white.file\"));\n    option.setAllowRenegotiate(getBooleanProperty(environment,\n        DEFAULT_OPTION.isAllowRenegotiate(),\n        \"ssl.\" + tag + \".allowRenegotiate\",\n        \"ssl.allowRenegotiate\"));\n    option.setStorePath(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getStorePath(),\n            \"ssl.\" + tag + \".storePath\",\n            \"ssl.storePath\"));\n    option.setClientAuth(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getClientAuth(),\n            \"ssl.\" + tag + \".clientAuth\",\n            \"ssl.clientAuth\"));\n    option.setTrustStore(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getTrustStore(),\n            \"ssl.\" + tag + \".trustStore\",\n            \"ssl.trustStore\"));\n    option.setTrustStoreType(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreType(),\n        \"ssl.\" + tag + \".trustStoreType\",\n        \"ssl.trustStoreType\"));\n    option.setTrustStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreValue(),\n        \"ssl.\" + tag + \".trustStoreValue\",\n        \"ssl.trustStoreValue\"));\n    option.setKeyStore(\n        getStringProperty(environment, DEFAULT_OPTION.getKeyStore(), \"ssl.\" + tag + \".keyStore\", \"ssl.keyStore\"));\n    option.setKeyStoreType(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getKeyStoreType(),\n            \"ssl.\" + tag + \".keyStoreType\",\n            \"ssl.keyStoreType\"));\n    option.setKeyStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getKeyStoreValue(),\n        \"ssl.\" + tag + \".keyStoreValue\",\n        \"ssl.keyStoreValue\"));\n    option.setCrl(getStringProperty(environment, DEFAULT_OPTION.getCrl(), \"ssl.\" + tag + \".crl\", \"ssl.crl\"));\n    option.setSslCustomClass(\n        getStringProperty(environment, null, \"ssl.\" + tag + \".sslCustomClass\", \"ssl.sslCustomClass\"));\n\n    sslProperties.setSslOption(option);\n    sslProperties.setSslCustom(SSLCustom.createSSLCustom(option.getSslCustomClass()));\n    return sslProperties;\n  }\n\n  private static String getStringProperty(Environment environment, String defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key);\n      }\n    }\n    return defaultValue;\n  }\n\n  private static boolean getBooleanProperty(Environment environment, boolean defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key, boolean.class, false);\n      }\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.cc.ConfigCenterDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/resources/META-INF/services/org.apache.servicecomb.core.bootup.BootUpInformationCollector",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\norg.apache.servicecomb.config.cc.ConfigCenterInformationCollector\n"
  },
  {
    "path": "dynamic-config/config-cc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.config.cc.ConfigCenterConfiguration\n"
  },
  {
    "path": "dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.cc;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.center.client.ConfigCenterAddressManager;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport com.google.common.eventbus.EventBus;\n\nclass ConfigCenterAddressManagerTest {\n  private static final List<String> addresses = new ArrayList<>();\n\n  private static ConfigCenterAddressManager addressManager1;\n\n  private static ConfigCenterAddressManager addressManager2;\n\n  @Test\n  public void addressManagerTest() throws NoSuchFieldException, IllegalAccessException {\n    addresses.add(\"http://127.0.0.1:30103\");\n    addresses.add(\"https://127.0.0.2:30103\");\n    addressManager1 = new ConfigCenterAddressManager(\"project\", addresses, new EventBus(), \"\", \"\");\n    addressManager2 = new ConfigCenterAddressManager(null, addresses, new EventBus(), \"\", \"\");\n    Field addressManagerField = addressManager1.getClass().getSuperclass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager1, 0);\n    addressManagerField = addressManager2.getClass().getSuperclass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager2, 0);\n\n    Assertions.assertNotNull(addressManager1);\n    Assertions.assertNotNull(addressManager2);\n\n    List<String> addresses = addressManager1.getAddresses();\n    Assertions.assertEquals(2, addresses.size());\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v3/project\", addresses.get(0));\n\n    Assertions.assertEquals(\"https://127.0.0.2:30103/v3/project\", addressManager1.address());\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v3/project\", addressManager1.address());\n    Assertions.assertEquals(\"https://127.0.0.2:30103/v3/default\", addressManager2.address());\n  }\n\n  @Test\n  public void onRefreshEndpointEvent() {\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"http://127.0.0.3:30100\");\n    List<String> addressRG = new ArrayList<>();\n    addressRG.add(\"http://127.0.0.4:30100\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", addressRG);\n    addressManager1 = new ConfigCenterAddressManager(\"project\", addresses, new EventBus(), \"\", \"\");\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"CseConfigCenter\");\n    addressManager1.refreshEndpoint(event, \"CseConfigCenter\");\n\n    List<String> availableZone = addressManager1.getAvailableZone();\n    Assertions.assertEquals(\"http://127.0.0.3:30100/v3/project\", availableZone.get(0));\n\n    List<String> availableRegion = addressManager1.getAvailableRegion();\n    Assertions.assertEquals(\"http://127.0.0.4:30100/v3/project\", availableRegion.get(0));\n\n    Assertions.assertEquals(\"http://127.0.0.3:30100/v3/project\", addressManager1.address());\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.cc;\n\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.center.client.ConfigCenterAddressManager;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nclass ConfigCenterConfigurationSourceImplTest {\n  @Test\n  void configAddressManagerTest() throws IllegalAccessException, NoSuchFieldException {\n    List<String> addresses = new ArrayList<>();\n    addresses.add(\"http://127.0.0.1:30103\");\n    addresses.add(\"http://127.0.0.2:30103\");\n    ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager(\"test\", addresses,\n        EventManager.getEventBus(), \"\", \"\");\n    Field addressManagerField = addressManager.getClass().getSuperclass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager, 0);\n    Assertions.assertNotNull(addressManager);\n\n    String address = addressManager.address();\n    Assertions.assertEquals(\"http://127.0.0.2:30103/v3/test\", address);\n    address = addressManager.address();\n    Assertions.assertEquals(\"http://127.0.0.1:30103/v3/test\", address);\n\n    addressManager = new ConfigCenterAddressManager(null, addresses, EventManager.getEventBus(), \"\", \"\");\n    addressManagerField = addressManager.getClass().getSuperclass().getDeclaredField(\"index\");\n    addressManagerField.setAccessible(true);\n    addressManagerField.set(addressManager, 0);\n    address = addressManager.address();\n    Assertions.assertEquals(\"http://127.0.0.2:30103/v3/default\", address);\n  }\n\n  @Test\n  void onRefreshEndpointEventTest() {\n    List<String> addresses = new ArrayList<>();\n    addresses.add(\"http://127.0.0.1:30103\");\n    List<String> addressAZ = new ArrayList<>();\n    addressAZ.add(\"rest://127.0.0.1:30100?sslEnabled=true\");\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    zoneAndRegion.put(\"sameZone\", addressAZ);\n    zoneAndRegion.put(\"sameRegion\", new ArrayList<>());\n    RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, \"CseConfigCenter\");\n    ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager(\"test\", addresses,\n        EventManager.getEventBus(), \"\", \"\");\n    addressManager.onRefreshEndpointEvent(event);\n\n    List<String> availableAZ = addressManager.getAvailableZone();\n    Assertions.assertEquals(\"https://127.0.0.1:30100/v3/test\", availableAZ.get(0));\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-cc/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nhost.name: 172.16.8.7\ntrace:\n  handler:\n    enabled: false\n    sampler:\n      percent: 0.5\n  metric:\n    service:\n      enable: false\nvalidate:\n  parameter:\n    enabled: true\n  returnValue:\n    enabled: true\n  apiInvoke:\n    enabled: true\nshutDownHandler:\n  enabled: true\n  timeLimit: 30000\neureka:\n  instance:\n    preferIpAddress: true\n    leaseRenewalIntervalInSeconds: 3\n    leaseExpirationDurationInSeconds: 5\n  client:\n    serviceUrl:\n      defaultZone: http://172.16.8.8:30100/\nservicecomb:\n  config:\n    client:\n      serviceName: testDemo\n      serverUri: https://172.16.8.7:30103,https://${host.name}:30103\n      tenantName: csetest\n      refreshMode: 1\n      refresh_interval: 10000\n  service:\n    registry:\n      autodiscovery: true\nservice_description:\n  name: testDemo\n  environment: testing\n"
  },
  {
    "path": "dynamic-config/config-consul/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>dynamic-config</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>config-consul</artifactId>\n  <name>Java Chassis::Dynamic Config::Consul</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.kiwiproject</groupId>\n      <artifactId>consul-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.gson</groupId>\n      <artifactId>gson</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.consul;\n\nimport org.springframework.core.env.Environment;\n\npublic class ConsulConfig {\n\n  public static final String CONSUL_CONFIG_PREFIX = \"servicecomb.config.consul\";\n\n  public static final String CONSUL_DEFAULT_ENVIRONMENT = \"production\";\n\n  public static final String PROPERTY_CONSUL_HOST = \"servicecomb.config.consul.host\";\n\n  public static final String PROPERTY_CONSUL_PORT = \"servicecomb.config.consul.port\";\n\n  public static final String PROPERTY_CONSUL_SCHEME = \"servicecomb.config.consul.scheme\";\n\n  public static final String PROPERTY_CONSUL_ACL_TOKEN = \"servicecomb.config.consul.acl-token\";\n\n  public static final String PROPERTY_CONSUL_WATCH_SECONDS = \"servicecomb.config.consul.watch-seconds\";\n\n  public static final String PROPERTY_INSTANCE_TAG = \"servicecomb.config.consul.instance-tag\";\n\n  public static final String PATH_ENVIRONMENT = \"/servicecomb/config/environment/%s\";\n\n  public static final String PATH_APPLICATION = \"/servicecomb/config/application/%s/%s\";\n\n  public static final String PATH_SERVICE = \"/servicecomb/config/service/%s/%s/%s\";\n\n  public static final String PATH_VERSION = \"/servicecomb/config/version/%s/%s/%s/%s\";\n\n  public static final String PATH_TAG = \"/servicecomb/config/tag/%s/%s/%s/%s/%s\";\n\n  private final Environment environment;\n\n  public ConsulConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getConsulHost() {\n    return environment.getProperty(PROPERTY_CONSUL_HOST, String.class, \"127.0.0.1\");\n  }\n\n  public int getConsulPort() {\n    return environment.getProperty(PROPERTY_CONSUL_PORT, int.class, 8500);\n  }\n\n  public String getConsulScheme() {\n    return environment.getProperty(PROPERTY_CONSUL_SCHEME);\n  }\n\n  public String getConsulAclToken() {\n    return environment.getProperty(PROPERTY_CONSUL_ACL_TOKEN);\n  }\n\n  public int getConsulWatchSeconds() {\n    return environment.getProperty(PROPERTY_CONSUL_WATCH_SECONDS, int.class, 8);\n  }\n\n  public String getInstanceTag() {\n    return environment.getProperty(PROPERTY_INSTANCE_TAG);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.consul;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.jetbrains.annotations.NotNull;\nimport org.kiwiproject.consul.Consul;\nimport org.kiwiproject.consul.KeyValueClient;\nimport org.kiwiproject.consul.cache.KVCache;\nimport org.kiwiproject.consul.model.kv.Value;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.config.YamlPropertiesFactoryBean;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.io.ByteArrayResource;\n\nimport java.io.IOException;\nimport java.io.StringReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Properties;\n\nimport static org.apache.servicecomb.config.consul.ConsulConfig.PATH_APPLICATION;\nimport static org.apache.servicecomb.config.consul.ConsulConfig.PATH_ENVIRONMENT;\nimport static org.apache.servicecomb.config.consul.ConsulConfig.PATH_SERVICE;\nimport static org.apache.servicecomb.config.consul.ConsulConfig.PATH_TAG;\nimport static org.apache.servicecomb.config.consul.ConsulConfig.PATH_VERSION;\n\npublic class ConsulConfigClient {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsulConfigClient.class);\n\n  public class GetDataRunnable implements Runnable {\n\n    private Map<String, Object> dataMap;\n\n    private String path;\n\n    public GetDataRunnable(String path, Map<String, Object> dataMap) {\n      this.dataMap = dataMap;\n      this.path = path;\n    }\n\n    @Override\n    public void run() {\n      try {\n        if (path.equals(\"tagData\")) {\n          tagData = dataMap;\n        } else if (path.equals(\"versionData\")) {\n          versionData = dataMap;\n        } else if (path.equals(\"serviceData\")) {\n          serviceData = dataMap;\n        } else if (path.equals(\"applicationData\")) {\n          applicationData = dataMap;\n        } else {\n          environmentData = dataMap;\n        }\n        refreshConfigItems();\n      } catch (Exception e) {\n        throw new RuntimeException(e);\n      }\n    }\n  }\n\n  private ConsulDynamicPropertiesSource.UpdateHandler updateHandler;\n\n  private ConsulConfig consulConfig;\n\n  private Environment environment;\n\n  private final Object lock = new Object();\n\n  private Consul consulClient;\n\n  private KeyValueClient kvClient;\n\n  private ConsulConfigProperties consulConfigProperties;\n\n  private Map<String, Object> environmentData = new HashMap<>();\n\n  private Map<String, Object> applicationData = new HashMap<>();\n\n  private Map<String, Object> serviceData = new HashMap<>();\n\n  private Map<String, Object> versionData = new HashMap<>();\n\n  private Map<String, Object> tagData = new HashMap<>();\n\n  private Map<String, Object> allLast = new HashMap<>();\n\n  public ConsulConfigClient(ConsulDynamicPropertiesSource.UpdateHandler updateHandler, Environment environment, ConsulConfigProperties consulConfigProperties, Consul consulClient) {\n    this.updateHandler = updateHandler;\n    this.consulConfig = new ConsulConfig(environment);\n    this.environment = environment;\n    this.consulConfigProperties = consulConfigProperties;\n    this.consulClient = consulClient;\n    this.kvClient = consulClient.keyValueClient();\n  }\n\n  public void refreshConsulConfig() {\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = ConsulConfig.CONSUL_DEFAULT_ENVIRONMENT;\n    }\n    addEnvironmentConfig(env);\n    addApplicationConfig(env);\n    addServiceConfig(env);\n    addVersionConfig(env);\n    addTagConfig(env);\n\n    refreshConfigItems();\n  }\n\n  private void addTagConfig(String env) {\n    if (StringUtils.isBlank(consulConfig.getInstanceTag())) {\n      return;\n    }\n    String path = String.format(PATH_TAG, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment),\n        consulConfig.getInstanceTag());\n\n    this.tagData = parseData(path);\n    try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) {\n      cache.addListener(newValues -> {\n        Optional<Value> newValue = newValues.values().stream()\n            .filter(value -> value.getKey().equals(path))\n            .findAny();\n\n        newValue.ifPresent(value -> {\n          Optional<String> decodedValue = newValue.get().getValueAsString();\n          decodedValue.ifPresent(v -> new Thread(new GetDataRunnable(\"tagData\", getValues(path))).start());\n        });\n      });\n      cache.start();\n    }\n  }\n\n  private void addVersionConfig(String env) {\n    String path = String.format(PATH_VERSION, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment));\n\n    this.versionData = parseData(path);\n    try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) {\n      cache.addListener(newValues -> {\n        Optional<Value> newValue = newValues.values().stream()\n            .filter(value -> value.getKey().equals(path))\n            .findAny();\n\n        newValue.ifPresent(value -> {\n          Optional<String> decodedValue = newValue.get().getValueAsString();\n          decodedValue.ifPresent(v -> new Thread(new GetDataRunnable(\"versionData\", getValues(path))).start());\n        });\n      });\n      cache.start();\n    }\n  }\n\n  private void addServiceConfig(String env) {\n    String path = String.format(PATH_SERVICE, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment));\n\n    this.serviceData = parseData(path);\n    try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) {\n      cache.addListener(newValues -> {\n        Optional<Value> newValue = newValues.values().stream()\n            .filter(value -> value.getKey().equals(path))\n            .findAny();\n\n        newValue.ifPresent(value -> {\n          Optional<String> decodedValue = newValue.get().getValueAsString();\n          decodedValue.ifPresent(v -> new Thread(new GetDataRunnable(\"serviceData\", getValues(path))).start());\n        });\n      });\n      cache.start();\n    }\n  }\n\n  private void addApplicationConfig(String env) {\n    String path = String.format(PATH_APPLICATION, env, BootStrapProperties.readApplication(environment));\n    this.applicationData = parseData(path);\n    try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) {\n      cache.addListener(newValues -> {\n        Optional<Value> newValue = newValues.values().stream()\n            .filter(value -> value.getKey().equals(path))\n            .findAny();\n\n        newValue.ifPresent(value -> {\n          Optional<String> decodedValue = newValue.get().getValueAsString();\n          decodedValue.ifPresent(v -> new Thread(new GetDataRunnable(\"applicationData\", getValues(path))).start());\n        });\n      });\n      cache.start();\n    }\n  }\n\n  private void addEnvironmentConfig(String env) {\n    String path = String.format(PATH_ENVIRONMENT, env);\n\n    this.environmentData = parseData(path);\n    try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) {\n      cache.addListener(newValues -> {\n        Optional<Value> newValue = newValues.values().stream()\n            .filter(value -> value.getKey().equals(path))\n            .findAny();\n\n        newValue.ifPresent(value -> {\n          Optional<String> decodedValue = newValue.get().getValueAsString();\n          decodedValue.ifPresent(v -> new Thread(new GetDataRunnable(\"environmentData\", getValues(path))).start());\n        });\n      });\n      cache.start();\n    }\n  }\n\n  public Map<String, Object> parseData(String path) {\n    try {\n      return getValues(path);\n    } catch (Exception e) {\n      LOGGER.error(e.getMessage(), e);\n    }\n    return new HashMap<>();\n  }\n\n  private Map<String, Object> getValues(String path) {\n    Map<String, Object> values = new HashMap<>();\n    KeyValueClient keyValueClient = consulClient.keyValueClient();\n    String decodedValue = keyValueClient.getValueAsString(path).orElseThrow();\n    if (StringUtils.isBlank(decodedValue)) {\n      return values;\n    }\n    return getValues(path, decodedValue);\n  }\n\n  private @NotNull Map<String, Object> getValues(String path, String decodedValue) {\n    Map<String, Object> values = new HashMap<>();\n    if (path.endsWith(\".yaml\") || path.endsWith(\".yml\")) {\n      YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();\n      yamlFactory.setResources(new ByteArrayResource(decodedValue.getBytes(StandardCharsets.UTF_8)));\n      values.putAll(toMap(yamlFactory.getObject()));\n    } else if (path.endsWith(\".properties\")) {\n      Properties properties = new Properties();\n      try {\n        properties.load(new StringReader(decodedValue));\n      } catch (IOException e) {\n        LOGGER.error(e.getMessage(), e);\n      }\n      values.putAll(toMap(properties));\n    } else {\n      values.put(path, decodedValue);\n    }\n    return values;\n  }\n\n  private void refreshConfigItems() {\n    synchronized (lock) {\n      Map<String, Object> all = new HashMap<>();\n      all.putAll(environmentData);\n      all.putAll(applicationData);\n      all.putAll(serviceData);\n      all.putAll(versionData);\n      all.putAll(tagData);\n      updateHandler.handle(all, allLast);\n      this.allLast = all;\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private Map<String, Object> toMap(Properties properties) {\n    if (properties == null) {\n      return Collections.emptyMap();\n    }\n    Map<String, Object> result = new HashMap<>();\n    Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();\n    while (keys.hasMoreElements()) {\n      String key = keys.nextElement();\n      Object value = properties.getProperty(key);\n      result.put(key, value);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.consul;\n\npublic class ConsulConfigProperties {\n\n  private String host = \"localhost\";\n\n  private Integer port = 8500;\n\n  private String scheme = \"http\";\n\n  private String aclToken;\n\n  private Integer watchSeconds = 8;\n\n  public String getHost() {\n    return host;\n  }\n\n  public void setHost(String host) {\n    this.host = host;\n  }\n\n  public Integer getPort() {\n    return port;\n  }\n\n  public void setPort(Integer port) {\n    this.port = port;\n  }\n\n  public String getScheme() {\n    return scheme;\n  }\n\n  public void setScheme(String scheme) {\n    this.scheme = scheme;\n  }\n\n  public String getAclToken() {\n    return aclToken;\n  }\n\n  public void setAclToken(String aclToken) {\n    this.aclToken = aclToken;\n  }\n\n  public Integer getWatchSeconds() {\n    return watchSeconds;\n  }\n\n  public void setWatchSeconds(Integer watchSeconds) {\n    this.watchSeconds = watchSeconds;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.consul;\n\nimport com.google.common.net.HostAndPort;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.kiwiproject.consul.Consul;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class ConsulDynamicPropertiesSource implements DynamicPropertiesSource {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsulDynamicPropertiesSource.class);\n\n  public static final String SOURCE_NAME = \"consul\";\n\n  private final Map<String, Object> valueCache = new ConcurrentHashMap<>();\n\n  private ConsulConfigClient consulConfigClient;\n\n  public ConsulDynamicPropertiesSource() {\n  }\n\n  private final UpdateHandler updateHandler = new UpdateHandler();\n  public class UpdateHandler {\n    public void handle(Map<String, Object> current, Map<String, Object> last) {\n      ConfigurationChangedEvent event = ConfigurationChangedEvent.createIncremental(current, last);\n      LOGGER.info(\"Dynamic configuration changed: {}\", event.getChanged());\n      valueCache.putAll(event.getAdded());\n      valueCache.putAll(event.getUpdated());\n      event.getDeleted().forEach((k, v) -> valueCache.remove(k));\n      EventManager.post(event);\n    }\n  }\n\n  private ConsulConfigProperties consulConfigProperties(Environment environment) {\n    ConsulConfig consulConfig = new ConsulConfig(environment);\n    ConsulConfigProperties consulConfigProperties = new ConsulConfigProperties();\n    consulConfigProperties.setHost(consulConfig.getConsulHost());\n    consulConfigProperties.setPort(consulConfig.getConsulPort());\n    consulConfigProperties.setScheme(consulConfig.getConsulScheme());\n    consulConfigProperties.setAclToken(consulConfig.getConsulAclToken());\n    consulConfigProperties.setWatchSeconds(consulConfig.getConsulWatchSeconds());\n    return consulConfigProperties;\n  }\n\n  private Consul consulClient(ConsulConfigProperties consulConfigProperties) {\n    Consul.Builder builder = Consul.builder().withHostAndPort(HostAndPort.fromParts(consulConfigProperties.getHost(), consulConfigProperties.getPort()));\n    if (StringUtils.isNotBlank(consulConfigProperties.getAclToken())) {\n      builder.withAclToken(consulConfigProperties.getAclToken());\n    }\n    return builder.build();\n  }\n\n  private ConsulConfigClient consulConfigClient(Environment environment) {\n    ConsulConfigProperties consulConfigProperties = consulConfigProperties(environment);\n    Consul consulClient = consulClient(consulConfigProperties);\n    return new ConsulConfigClient(updateHandler, environment, consulConfigProperties, consulClient);\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    try {\n      consulConfigClient = consulConfigClient(environment);\n      consulConfigClient.refreshConsulConfig();\n    } catch (Exception e) {\n      throw new IllegalStateException(\"Set up consul config failed.\", e);\n    }\n    return new MapPropertySource(SOURCE_NAME, valueCache);\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-consul/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.consul.ConsulDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/config-etcd/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>dynamic-config</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>config-etcd</artifactId>\n  <name>Java Chassis::Dynamic Config::Zookeeper</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.etcd</groupId>\n      <artifactId>jetcd-core</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.etcd;\n\nimport java.io.IOException;\nimport java.io.StringReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.etcd.EtcdDynamicPropertiesSource.UpdateHandler;\nimport org.apache.servicecomb.foundation.common.utils.MuteExceptionUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.config.YamlPropertiesFactoryBean;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.io.ByteArrayResource;\n\nimport io.etcd.jetcd.ByteSequence;\nimport io.etcd.jetcd.Client;\nimport io.etcd.jetcd.KeyValue;\nimport io.etcd.jetcd.Watch;\nimport io.etcd.jetcd.kv.GetResponse;\nimport io.etcd.jetcd.options.GetOption;\nimport io.etcd.jetcd.options.WatchOption;\n\npublic class EtcdClient {\n\n  public class GetDataRunnable implements Runnable {\n\n    private Map<String, Object> dataMap;\n\n    private EtcdClient etcdClient;\n\n    private String path;\n\n    public GetDataRunnable(Map<String, Object> dataMap, EtcdClient etcdClient, String path) {\n      this.dataMap = dataMap;\n      this.etcdClient = etcdClient;\n      this.path = path;\n    }\n\n    @Override\n    public void run() {\n      try {\n        dataMap.clear();\n        dataMap.putAll(etcdClient.parseData(path));\n        refreshConfigItems();\n      } catch (Exception e) {\n        throw new RuntimeException(e);\n      }\n    }\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(EtcdClient.class);\n\n  public static final String PATH_ENVIRONMENT = \"/servicecomb/config/environment/%s\";\n\n  public static final String PATH_APPLICATION = \"/servicecomb/config/application/%s/%s\";\n\n  public static final String PATH_SERVICE = \"/servicecomb/config/service/%s/%s/%s\";\n\n  public static final String PATH_VERSION = \"/servicecomb/config/version/%s/%s/%s/%s\";\n\n  public static final String PATH_TAG = \"/servicecomb/config/tag/%s/%s/%s/%s/%s\";\n\n  private final UpdateHandler updateHandler;\n\n  private final EtcdConfig etcdConfig;\n\n  private final Environment environment;\n\n  private final Object lock = new Object();\n\n  private Map<String, Object> environmentData = new HashMap<>();\n\n  private Map<String, Object> applicationData = new HashMap<>();\n\n  private Map<String, Object> serviceData = new HashMap<>();\n\n  private Map<String, Object> versionData = new HashMap<>();\n\n  private Map<String, Object> tagData = new HashMap<>();\n\n  private Map<String, Object> allLast = new HashMap<>();\n\n  private Client client;\n\n  public EtcdClient(UpdateHandler updateHandler, Environment environment) {\n    this.updateHandler = updateHandler;\n    this.etcdConfig = new EtcdConfig(environment);\n    this.environment = environment;\n  }\n\n  public void getClient() {\n    if (StringUtils.isEmpty(etcdConfig.getAuthInfo())) {\n      this.client = Client.builder().endpoints(etcdConfig.getConnectString()).build();\n    } else {\n      String[] authInfo = etcdConfig.getAuthInfo().split(\":\");\n      this.client = Client.builder().endpoints(etcdConfig.getConnectString())\n          .user(ByteSequence.from(authInfo[0], StandardCharsets.UTF_8))\n          .password(ByteSequence.from(authInfo[1], StandardCharsets.UTF_8)).build();\n    }\n  }\n\n  public void refreshEtcdConfig() throws Exception {\n\n    getClient();\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = EtcdConfig.ZOOKEEPER_DEFAULT_ENVIRONMENT;\n    }\n    addEnvironmentConfig(env);\n    addApplicationConfig(env);\n    addServiceConfig(env);\n    addVersionConfig(env);\n    addTagConfig(env);\n\n    refreshConfigItems();\n  }\n\n  private void addTagConfig(String env) throws Exception {\n    if (StringUtils.isEmpty(etcdConfig.getInstanceTag())) {\n      return;\n    }\n    String path = String.format(PATH_TAG, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment),\n        etcdConfig.getInstanceTag());\n\n    ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8);\n    Watch watchClient = client.getWatchClient();\n    watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(),\n        resp -> new Thread(new GetDataRunnable(tagData, this, path)).start());\n    this.tagData = parseData(path);\n  }\n\n  private void addVersionConfig(String env) throws Exception {\n    String path = String.format(PATH_VERSION, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment));\n\n    ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8);\n    Watch watchClient = client.getWatchClient();\n    watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(),\n        resp -> new Thread(new GetDataRunnable(versionData, this, path)).start());\n    this.versionData = parseData(path);\n  }\n\n  private void addServiceConfig(String env) throws Exception {\n    String path = String.format(PATH_SERVICE, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment));\n\n    ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8);\n    Watch watchClient = client.getWatchClient();\n    watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(),\n        resp -> new Thread(new GetDataRunnable(serviceData, this, path)).start());\n    this.serviceData = parseData(path);\n  }\n\n  private void addApplicationConfig(String env) throws Exception {\n    String path = String.format(PATH_APPLICATION, env, BootStrapProperties.readApplication(environment));\n\n    ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8);\n    Watch watchClient = client.getWatchClient();\n    watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(),\n        resp -> new Thread(new GetDataRunnable(applicationData, this, path)).start());\n    this.applicationData = parseData(path);\n  }\n\n  private void addEnvironmentConfig(String env) throws Exception {\n    String path = String.format(PATH_ENVIRONMENT, env);\n\n    ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8);\n    Watch watchClient = client.getWatchClient();\n    watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(),\n        resp -> new Thread(new GetDataRunnable(environmentData, this, path)).start());\n    this.environmentData = parseData(path);\n  }\n\n  public Map<String, Object> parseData(String path) throws Exception {\n\n    List<KeyValue> endpointKv = getValuesByPrefix(path);\n    return getValues(path, endpointKv);\n  }\n\n  private Map<String, Object> getValues(String path, List<KeyValue> endpointKv) {\n    Map<String, Object> values = new HashMap<>();\n    for (KeyValue keyValue : endpointKv) {\n      String key = new String(keyValue.getKey().getBytes(), StandardCharsets.UTF_8);\n      String value = new String(keyValue.getValue().getBytes(), StandardCharsets.UTF_8);\n      if (key.equals(path)) {\n        continue;\n      }\n      if (key.endsWith(\".yaml\") || key.endsWith(\".yml\")) {\n        YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();\n        yamlFactory.setResources(new ByteArrayResource(value.getBytes(StandardCharsets.UTF_8)));\n        values.putAll(toMap(yamlFactory.getObject()));\n      } else if (key.endsWith(\".properties\")) {\n        Properties properties = new Properties();\n        try {\n          properties.load(new StringReader(value));\n        } catch (IOException e) {\n          LOGGER.error(\"load error\");\n        }\n        values.putAll(toMap(properties));\n      } else {\n        values.put(key, value);\n      }\n    }\n    return values;\n  }\n\n  private List<KeyValue> getValuesByPrefix(String prefix) {\n\n    CompletableFuture<GetResponse> getFuture = client.getKVClient()\n        .get(ByteSequence.from(prefix, StandardCharsets.UTF_8),\n            GetOption.builder().withPrefix(ByteSequence.from(prefix, StandardCharsets.UTF_8)).build());\n    GetResponse response = MuteExceptionUtil.builder().withLog(\"get kv by prefix error\")\n        .executeCompletableFuture(getFuture);\n    return response.getKvs();\n  }\n\n  private void refreshConfigItems() {\n    synchronized (lock) {\n      Map<String, Object> all = new HashMap<>();\n      all.putAll(environmentData);\n      all.putAll(applicationData);\n      all.putAll(serviceData);\n      all.putAll(versionData);\n      all.putAll(tagData);\n      updateHandler.handle(all, allLast);\n      this.allLast = all;\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private Map<String, Object> toMap(Properties properties) {\n    if (properties == null) {\n      return Collections.emptyMap();\n    }\n    Map<String, Object> result = new HashMap<>();\n    Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();\n    while (keys.hasMoreElements()) {\n      String key = keys.nextElement();\n      Object value = properties.getProperty(key);\n      result.put(key, value);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.etcd;\n\nimport org.springframework.core.env.Environment;\n\npublic class EtcdConfig {\n  public static final String ZOOKEEPER_DEFAULT_ENVIRONMENT = \"production\";\n\n  public static final String PROPERTY_CONNECT_STRING = \"servicecomb.config.etcd.connectString\";\n\n  public static final String PROPERTY_SESSION_TIMEOUT = \"servicecomb.config.etcd.sessionTimeoutMillis\";\n\n  public static final String PROPERTY_CONNECTION_TIMEOUT = \"servicecomb.config.etcd.connectionTimeoutMills\";\n\n  public static final String PROPERTY_AUTH_SCHEMA = \"servicecomb.config.etcd.authenticationSchema\";\n\n  public static final String PROPERTY_AUTH_INFO = \"servicecomb.config.etcd.authenticationInfo\";\n\n  public static final String PROPERTY_INSTANCE_TAG = \"servicecomb.config.etcd.instanceTag\";\n\n  private final Environment environment;\n\n  public EtcdConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getConnectString() {\n    return environment.getProperty(PROPERTY_CONNECT_STRING, \"http://127.0.0.1:2379\");\n  }\n\n  public int getSessionTimeoutMillis() {\n    return environment.getProperty(PROPERTY_SESSION_TIMEOUT, int.class, 60000);\n  }\n\n  public int getConnectionTimeoutMillis() {\n    return environment.getProperty(PROPERTY_CONNECTION_TIMEOUT, int.class, 1000);\n  }\n\n  public String getAuthSchema() {\n    return environment.getProperty(PROPERTY_AUTH_SCHEMA);\n  }\n\n  public String getAuthInfo() {\n    return environment.getProperty(PROPERTY_AUTH_INFO);\n  }\n\n  public String getInstanceTag() {\n    return environment.getProperty(PROPERTY_INSTANCE_TAG);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.etcd;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\npublic class EtcdDynamicPropertiesSource implements DynamicPropertiesSource {\n  public static final String SOURCE_NAME = \"etcd\";\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(EtcdDynamicPropertiesSource.class);\n\n  private final Map<String, Object> valueCache = new ConcurrentHashMap<>();\n\n  public EtcdDynamicPropertiesSource() {\n  }\n\n  private final UpdateHandler updateHandler = new UpdateHandler();\n\n  private void init(Environment environment) {\n    EtcdClient etcdClient = new EtcdClient(updateHandler, environment);\n    try {\n      etcdClient.refreshEtcdConfig();\n    } catch (Exception e) {\n      throw new IllegalStateException(\"Set up etcd config failed.\", e);\n    }\n  }\n\n  public class UpdateHandler {\n    public void handle(Map<String, Object> current, Map<String, Object> last) {\n      ConfigurationChangedEvent event = ConfigurationChangedEvent.createIncremental(current, last);\n      LOGGER.info(\"Dynamic configuration changed: {}\", event.getChanged());\n      valueCache.putAll(event.getAdded());\n      valueCache.putAll(event.getUpdated());\n      event.getDeleted().forEach((k, v) -> valueCache.remove(k));\n      EventManager.post(event);\n    }\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    init(environment);\n    return new MapPropertySource(SOURCE_NAME, valueCache);\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-etcd/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.etcd.EtcdDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/config-kie/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>dynamic-config</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>config-kie</artifactId>\n  <name>Java Chassis::Dynamic Config::Kie</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-ssl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n      <dependency>\n          <groupId>org.apache.servicecomb</groupId>\n          <artifactId>java-chassis-core</artifactId>\n      </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>config-kie-client</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.vertx.VertxConst;\nimport org.springframework.core.env.Environment;\n\npublic class KieConfig {\n  public static final String SSL_TAG = \"kie.consumer\";\n\n  private static final String SERVER_URL_KEY = \"servicecomb.kie.serverUri\";\n\n  private static final String REFRESH_INTERVAL = \"servicecomb.kie.refreshInterval\";\n\n  private static final String FIRST_REFRESH_INTERVAL = \"servicecomb.kie.firstRefreshInterval\";\n\n  private static final String DOMAIN_NAME = \"servicecomb.kie.domainName\";\n\n  private static final String ENABLE_LONG_POLLING = \"servicecomb.kie.enableLongPolling\";\n\n  private static final String POLLING_WAIT_TIME = \"servicecomb.kie.pollingWaitTime\";\n\n  private static final String FIRST_PULL_REQUIRED = \"servicecomb.kie.firstPullRequired\";\n\n  private static final String CUSTOM_LABEL = \"servicecomb.kie.customLabel\";\n\n  private static final String CUSTOM_LABEL_VALUE = \"servicecomb.kie.customLabelValue\";\n\n  private static final String ENABLE_APP_CONFIG = \"servicecomb.kie.enableAppConfig\";\n\n  private static final String ENABLE_SERVICE_CONFIG = \"servicecomb.kie.enableServiceConfig\";\n\n  private static final String ENABLE_VERSION_CONFIG = \"servicecomb.kie.enableVersionConfig\";\n\n  private static final String ENABLE_CUSTOM_CONFIG = \"servicecomb.kie.enableCustomConfig\";\n\n  public static final String FILE_SOURCE = \"servicecomb.config.client.fileSource\";\n\n  private static final int DEFAULT_REFRESH_INTERVAL = 15000;\n\n  private static final int DEFAULT_POLLING_WAIT_TIME = 10;\n\n  private static final int DEFAULT_FIRST_REFRESH_INTERVAL = 0;\n\n  private static final boolean DEFAULT_ENABLE_LONG_POLLING = true;\n\n  private static final String CUSTOM_LABEL_DEFAULT = \"public\";\n\n  private static final String CUSTOM_LABEL_VALUE_DEFAULT = \"\";\n\n  private static final String CLIENT_CONNECT_TIMEOUT = \"servicecomb.kie.client.timeout.connect\";\n\n  private static final String CLIENT_REQUEST_TIMEOUT = \"servicecomb.kie.client.timeout.request\";\n\n  private static final String CLIENT_SOCKET_TIMEOUT = \"servicecomb.kie.client.timeout.socket\";\n\n  private final Environment environment;\n\n  public KieConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public List<String> getFileSources() {\n    return environment.getProperty(FILE_SOURCE, List.class, Collections.emptyList());\n  }\n\n  public String getDomainName() {\n    return environment.getProperty(DOMAIN_NAME, \"default\");\n  }\n\n  public String getServerUri() {\n    return environment.getProperty(SERVER_URL_KEY);\n  }\n\n  public int getRefreshInterval() {\n    return environment.getProperty(REFRESH_INTERVAL, int.class, DEFAULT_REFRESH_INTERVAL);\n  }\n\n  public int getFirstRefreshInterval() {\n    return environment.getProperty(FIRST_REFRESH_INTERVAL, int.class, DEFAULT_FIRST_REFRESH_INTERVAL);\n  }\n\n  public boolean enableAppConfig() {\n    return environment.getProperty(ENABLE_APP_CONFIG, boolean.class, true);\n  }\n\n  public boolean enableServiceConfig() {\n    return environment.getProperty(ENABLE_SERVICE_CONFIG, boolean.class, true);\n  }\n\n  public boolean enableVersionConfig() {\n    return environment.getProperty(ENABLE_VERSION_CONFIG, boolean.class, true);\n  }\n\n  public boolean enableCustomConfig() {\n    return environment.getProperty(ENABLE_CUSTOM_CONFIG, boolean.class, true);\n  }\n\n  public boolean enableLongPolling() {\n    return environment.getProperty(ENABLE_LONG_POLLING, boolean.class, DEFAULT_ENABLE_LONG_POLLING);\n  }\n\n  public int getPollingWaitTime() {\n    return environment.getProperty(POLLING_WAIT_TIME, int.class, DEFAULT_POLLING_WAIT_TIME);\n  }\n\n  public boolean firstPullRequired() {\n    return environment.getProperty(FIRST_PULL_REQUIRED, boolean.class, false);\n  }\n\n  public String getCustomLabel() {\n    return environment.getProperty(CUSTOM_LABEL, CUSTOM_LABEL_DEFAULT);\n  }\n\n  public String getCustomLabelValue() {\n    return environment.getProperty(CUSTOM_LABEL_VALUE, CUSTOM_LABEL_VALUE_DEFAULT);\n  }\n\n  public Boolean isProxyEnable() {\n    return environment.getProperty(VertxConst.PROXY_ENABLE, boolean.class, false);\n  }\n\n  public String getProxyHost() {\n    return environment.getProperty(VertxConst.PROXY_HOST, \"127.0.0.1\");\n  }\n\n  public int getProxyPort() {\n    return environment.getProperty(VertxConst.PROXY_PORT, int.class, 8080);\n  }\n\n  public String getProxyUsername() {\n    return environment.getProperty(VertxConst.PROXY_USERNAME);\n  }\n\n  public String getProxyPasswd() {\n    return environment.getProperty(VertxConst.PROXY_PASSWD);\n  }\n\n  public int getConnectTimeout() {\n    return environment.getProperty(CLIENT_CONNECT_TIMEOUT, int.class, 5000);\n  }\n\n  public int getConnectionRequestTimeout() {\n    return environment.getProperty(CLIENT_REQUEST_TIMEOUT,  int.class, 5000);\n  }\n\n  public int getSocketTimeout() {\n    return environment.getProperty(CLIENT_SOCKET_TIMEOUT,  int.class, 5000);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.kie;\n\nimport org.apache.servicecomb.config.kie.collect.KieClientInformationCollector;\nimport org.springframework.context.annotation.Bean;\n\npublic class KieConfigConfiguration {\n  @Bean\n  public KieClientInformationCollector kieClientInformationCollector() {\n    return new KieClientInformationCollector();\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.kie;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.client.config.RequestConfig.Builder;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.apache.servicecomb.config.common.ConfigConverter;\nimport org.apache.servicecomb.config.kie.client.KieClient;\nimport org.apache.servicecomb.config.kie.client.KieConfigManager;\nimport org.apache.servicecomb.config.kie.client.KieConfigurationChangedEvent;\nimport org.apache.servicecomb.config.kie.client.model.KieAddressManager;\nimport org.apache.servicecomb.config.kie.client.model.KieConfiguration;\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpTransportFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic class KieDynamicPropertiesSource implements DynamicPropertiesSource {\n  private static final Logger LOGGER = LoggerFactory.getLogger(KieDynamicPropertiesSource.class);\n\n  public static final String SOURCE_NAME = \"kie\";\n\n  private final Map<String, Object> data = new ConcurrentHashMapEx<>();\n\n  private KieConfigManager kieConfigManager;\n\n  private ConfigConverter configConverter;\n\n  public KieDynamicPropertiesSource() {\n\n  }\n\n  private void init(Environment environment) {\n    KieConfig kieConfig = new KieConfig(environment);\n    configConverter = new ConfigConverter(kieConfig.getFileSources());\n    KieAddressManager kieAddressManager = configKieAddressManager(kieConfig, environment);\n\n    RequestConfig.Builder requestBuilder = buildRequestConfigBuilder(kieConfig);\n    if (kieConfig.enableLongPolling()\n        && kieConfig.getPollingWaitTime() >= 0) {\n      requestBuilder.setConnectionRequestTimeout(kieConfig.getPollingWaitTime() * 2 * 1000);\n      requestBuilder.setSocketTimeout(kieConfig.getPollingWaitTime() * 2 * 1000);\n    }\n    HttpTransport httpTransport = createHttpTransport(kieAddressManager, requestBuilder.build(),\n        kieConfig, environment);\n    KieConfiguration kieConfiguration = createKieConfiguration(kieConfig, environment);\n    KieClient kieClient = new KieClient(kieAddressManager, httpTransport, kieConfiguration);\n    EventManager.register(this);\n    kieConfigManager = new KieConfigManager(kieClient, EventManager.getEventBus(), kieConfiguration, configConverter,\n        kieAddressManager);\n    kieConfigManager.firstPull();\n    kieConfigManager.startConfigKieManager();\n    data.putAll(configConverter.getCurrentData());\n  }\n\n  private Builder buildRequestConfigBuilder(KieConfig kieConfig) {\n    Builder builder = HttpTransportFactory.defaultRequestConfig();\n    builder.setConnectTimeout(kieConfig.getConnectTimeout());\n    builder.setConnectionRequestTimeout(kieConfig.getConnectionRequestTimeout());\n    builder.setSocketTimeout(kieConfig.getSocketTimeout());\n    return builder;\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(KieConfigurationChangedEvent event) {\n    LOGGER.info(\"Dynamic configuration changed: {}\", event.getChanged());\n    data.putAll(event.getAdded());\n    data.putAll(event.getUpdated());\n    event.getDeleted().forEach((k, v) -> data.remove(k));\n    EventManager.post(ConfigurationChangedEvent.createIncremental(event.getAdded(),\n        event.getUpdated(), event.getDeleted()));\n  }\n\n  private KieConfiguration createKieConfiguration(KieConfig kieConfig, Environment environment) {\n    return new KieConfiguration()\n        .setAppName(BootStrapProperties.readApplication(environment))\n        .setServiceName(BootStrapProperties.readServiceName(environment))\n        .setEnvironment(BootStrapProperties.readServiceEnvironment(environment))\n        .setVersion(BootStrapProperties.readServiceVersion(environment))\n        .setFirstPullRequired(kieConfig.firstPullRequired())\n        .setCustomLabel(kieConfig.getCustomLabel())\n        .setCustomLabelValue(kieConfig.getCustomLabelValue())\n        .setEnableAppConfig(kieConfig.enableAppConfig())\n        .setEnableCustomConfig(kieConfig.enableCustomConfig())\n        .setEnableLongPolling(kieConfig.enableLongPolling())\n        .setEnableServiceConfig(kieConfig.enableServiceConfig())\n        .setEnableVersionConfig(kieConfig.enableVersionConfig())\n        .setPollingWaitInSeconds(kieConfig.getPollingWaitTime())\n        .setProject(kieConfig.getDomainName())\n        .setRefreshIntervalInMillis(kieConfig.getRefreshInterval());\n  }\n\n  private HttpTransport createHttpTransport(KieAddressManager kieAddressManager,\n      RequestConfig requestConfig, KieConfig kieConfig,\n      Environment environment) {\n    List<AuthHeaderProvider> authHeaderProviders = SPIServiceUtils.getOrLoadSortedService(AuthHeaderProvider.class);\n\n    if (kieConfig.isProxyEnable()) {\n      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().\n          setDefaultRequestConfig(requestConfig);\n      HttpHost proxy = new HttpHost(kieConfig.getProxyHost(),\n          kieConfig.getProxyPort(), \"http\"); // now only support http proxy\n      httpClientBuilder.setProxy(proxy);\n      CredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n      credentialsProvider.setCredentials(new AuthScope(proxy),\n          new UsernamePasswordCredentials(kieConfig.getProxyUsername(),\n              kieConfig.getProxyPasswd()));\n      httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n\n      return HttpTransportFactory\n          .createHttpTransport(\n              TransportUtils\n                  .createSSLProperties(kieAddressManager.sslEnabled(), environment, KieConfig.SSL_TAG),\n              getRequestAuthHeaderProvider(authHeaderProviders), httpClientBuilder);\n    }\n\n    return HttpTransportFactory\n        .createHttpTransport(\n            TransportUtils\n                .createSSLProperties(kieAddressManager.sslEnabled(), environment, KieConfig.SSL_TAG),\n            getRequestAuthHeaderProvider(authHeaderProviders), requestConfig);\n  }\n\n  private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {\n    return signRequest -> {\n      String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : \"\";\n      Map<String, String> headers = new HashMap<>();\n      authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host)));\n      return headers;\n    };\n  }\n\n  private KieAddressManager configKieAddressManager(KieConfig kieConfig, Environment environment) {\n    String region = environment.getProperty(\"servicecomb.datacenter.region\");\n    String availableZone = environment.getProperty(\"servicecomb.datacenter.availableZone\");\n    return new KieAddressManager(\n        Arrays.asList(kieConfig.getServerUri().split(\",\")), EventManager.getEventBus(), region, availableZone);\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    init(environment);\n    return new MapPropertySource(SOURCE_NAME, data);\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie;\n\nimport static org.apache.servicecomb.foundation.ssl.SSLOption.DEFAULT_OPTION;\n\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.springframework.core.env.Environment;\n\npublic class TransportUtils {\n  public static SSLProperties createSSLProperties(boolean sslEnabled, Environment environment, String tag) {\n    SSLProperties sslProperties = new SSLProperties();\n    sslProperties.setEnabled(sslEnabled);\n\n    if (!sslEnabled) {\n      return sslProperties;\n    }\n\n    SSLOption option = new SSLOption();\n    option.setEngine(getStringProperty(environment,\n        DEFAULT_OPTION.getEngine(),\n        \"ssl.\" + tag + \".engine\",\n        \"ssl.engine\"));\n    option.setProtocols(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getProtocols(),\n            \"ssl.\" + tag + \".protocols\",\n            \"ssl.protocols\"));\n    option.setCiphers(\n        getStringProperty(environment, DEFAULT_OPTION.getCiphers(), \"ssl.\" + tag + \".ciphers\", \"ssl.ciphers\"));\n    option.setAuthPeer(\n        getBooleanProperty(environment, DEFAULT_OPTION.isAuthPeer(), \"ssl.\" + tag + \".authPeer\", \"ssl.authPeer\"));\n    option.setCheckCNHost(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNHost(),\n            \"ssl.\" + tag + \".checkCN.host\",\n            \"ssl.checkCN.host\"));\n    option.setCheckCNWhite(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNWhite(),\n            \"ssl.\" + tag + \".checkCN.white\",\n            \"ssl.checkCN.white\"));\n    option.setCheckCNWhiteFile(getStringProperty(environment,\n        DEFAULT_OPTION.getCiphers(),\n        \"ssl.\" + tag + \".checkCN.white.file\",\n        \"ssl.checkCN.white.file\"));\n    option.setAllowRenegotiate(getBooleanProperty(environment,\n        DEFAULT_OPTION.isAllowRenegotiate(),\n        \"ssl.\" + tag + \".allowRenegotiate\",\n        \"ssl.allowRenegotiate\"));\n    option.setStorePath(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getStorePath(),\n            \"ssl.\" + tag + \".storePath\",\n            \"ssl.storePath\"));\n    option.setClientAuth(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getClientAuth(),\n            \"ssl.\" + tag + \".clientAuth\",\n            \"ssl.clientAuth\"));\n    option.setTrustStore(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getTrustStore(),\n            \"ssl.\" + tag + \".trustStore\",\n            \"ssl.trustStore\"));\n    option.setTrustStoreType(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreType(),\n        \"ssl.\" + tag + \".trustStoreType\",\n        \"ssl.trustStoreType\"));\n    option.setTrustStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreValue(),\n        \"ssl.\" + tag + \".trustStoreValue\",\n        \"ssl.trustStoreValue\"));\n    option.setKeyStore(\n        getStringProperty(environment, DEFAULT_OPTION.getKeyStore(), \"ssl.\" + tag + \".keyStore\", \"ssl.keyStore\"));\n    option.setKeyStoreType(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getKeyStoreType(),\n            \"ssl.\" + tag + \".keyStoreType\",\n            \"ssl.keyStoreType\"));\n    option.setKeyStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getKeyStoreValue(),\n        \"ssl.\" + tag + \".keyStoreValue\",\n        \"ssl.keyStoreValue\"));\n    option.setCrl(getStringProperty(environment, DEFAULT_OPTION.getCrl(), \"ssl.\" + tag + \".crl\", \"ssl.crl\"));\n    option.setSslCustomClass(\n        getStringProperty(environment, null, \"ssl.\" + tag + \".sslCustomClass\", \"ssl.sslCustomClass\"));\n\n    sslProperties.setSslOption(option);\n    sslProperties.setSslCustom(SSLCustom.createSSLCustom(option.getSslCustomClass()));\n    return sslProperties;\n  }\n\n  private static String getStringProperty(Environment environment, String defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key);\n      }\n    }\n    return defaultValue;\n  }\n\n  private static boolean getBooleanProperty(Environment environment, boolean defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key, boolean.class, false);\n      }\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/collect/KieClientInformationCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.kie.collect;\n\nimport org.apache.servicecomb.config.kie.KieConfig;\nimport org.apache.servicecomb.core.bootup.BootUpInformationCollector;\nimport org.springframework.context.EnvironmentAware;\nimport org.springframework.core.env.Environment;\nimport org.springframework.lang.NonNull;\n\npublic class KieClientInformationCollector implements BootUpInformationCollector, EnvironmentAware {\n  private KieConfig kieConfig;\n\n  @Override\n  public void setEnvironment(@NonNull Environment environment) {\n    this.kieConfig = new KieConfig(environment);\n  }\n\n  @Override\n  public String collect() {\n    return \"Kie Center: \" + kieConfig.getServerUri();\n  }\n\n  @Override\n  public int getOrder() {\n    return 2;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.kie.KieDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/resources/META-INF/services/org.apache.servicecomb.core.bootup.BootUpInformationCollector",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\norg.apache.servicecomb.config.kie.collect.KieClientInformationCollector\n"
  },
  {
    "path": "dynamic-config/config-kie/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.config.kie.KieConfigConfiguration\n"
  },
  {
    "path": "dynamic-config/config-kie/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nhost.name: 172.16.8.7\ntrace:\n  handler:\n    enabled: false\n    sampler:\n      percent: 0.5\n  metric:\n    service:\n      enable: false\nvalidate:\n  parameter:\n    enabled: true\n  returnValue:\n    enabled: true\n  apiInvoke:\n    enabled: true\nshutDownHandler:\n  enabled: true\n  timeLimit: 30000\neureka:\n  instance:\n    preferIpAddress: true\n    leaseRenewalIntervalInSeconds: 3\n    leaseExpirationDurationInSeconds: 5\n  client:\n    serviceUrl:\n      defaultZone: http://172.16.8.8:30100/\nservicecomb:\n  kie:\n    serverUri: https://172.16.8.7:30110\n  service:\n    registry:\n      autodiscovery: true\n      refreshInterval: 3000\n      firstRefreshInterval: 0\n\nservice_description:\n  name: testDemo\n  environment: testing\n"
  },
  {
    "path": "dynamic-config/config-nacos/README.md",
    "content": "# Dynamic configurations implementation with [Nacos](https://github.com/alibaba/nacos)\n\nRead [developers guide](https://docs.servicecomb.io/java-chassis/zh_CN/config/general-config/)\nfor details.\n"
  },
  {
    "path": "dynamic-config/config-nacos/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>dynamic-config</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>config-nacos</artifactId>\n  <name>Java Chassis::Dynamic Config::Nacos</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <!--nacos client-->\n    <dependency>\n      <groupId>com.alibaba.nacos</groupId>\n      <artifactId>nacos-client</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.nacos;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\nimport java.util.concurrent.Executor;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.nacos.NacosDynamicPropertiesSource.UpdateHandler;\nimport org.apache.servicecomb.config.parser.Parser;\nimport org.springframework.core.env.Environment;\n\nimport com.alibaba.nacos.api.NacosFactory;\nimport com.alibaba.nacos.api.config.ConfigService;\nimport com.alibaba.nacos.api.config.listener.Listener;\nimport com.alibaba.nacos.api.exception.NacosException;\n\npublic class NacosClient {\n  private final UpdateHandler updateHandler;\n\n  private final NacosConfig nacosConfig;\n\n  private final Environment environment;\n\n  private final Object lock = new Object();\n\n  private Map<String, Object> application = new HashMap<>();\n\n  private Map<String, Object> service = new HashMap<>();\n\n  private Map<String, Object> version = new HashMap<>();\n\n  private Map<String, Object> profile = new HashMap<>();\n\n  private Map<String, Object> custom = new HashMap<>();\n\n  private Map<String, Object> allLast = new HashMap<>();\n\n  public NacosClient(UpdateHandler updateHandler, Environment environment) {\n    this.updateHandler = updateHandler;\n    this.nacosConfig = new NacosConfig(environment);\n    this.environment = environment;\n  }\n\n  public void refreshNacosConfig() throws NacosException {\n    Properties properties = nacosProperties(environment, nacosConfig);\n\n    ConfigService configService = NacosFactory.createConfigService(properties);\n    addApplicationConfig(configService);\n    addServiceConfig(configService);\n    addVersionConfig(configService);\n    addProfileConfig(configService);\n    addCustomConfig(configService);\n\n    refreshConfigItems();\n  }\n\n  private void addApplicationConfig(ConfigService configService) throws NacosException {\n    String content = configService.getConfig(BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readApplication(environment), 5000);\n    processApplicationConfig(content);\n    configService.addListener(BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readApplication(environment), new Listener() {\n          @Override\n          public void receiveConfigInfo(String configInfo) {\n            processApplicationConfig(configInfo);\n            refreshConfigItems();\n          }\n\n          @Override\n          public Executor getExecutor() {\n            return null;\n          }\n        });\n  }\n\n  private void processApplicationConfig(String content) {\n    if (StringUtils.isEmpty(content)) {\n      this.application = new HashMap<>();\n      return;\n    }\n    Parser contentParser = Parser.findParser(\"yaml\");\n    this.application = contentParser.parse(content, \"\", false);\n  }\n\n  private void addServiceConfig(ConfigService configService) throws NacosException {\n    String content = configService.getConfig(BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readApplication(environment),\n        5000);\n    processServiceConfig(content);\n    configService.addListener(BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readApplication(environment), new Listener() {\n          @Override\n          public void receiveConfigInfo(String configInfo) {\n            processServiceConfig(configInfo);\n            refreshConfigItems();\n          }\n\n          @Override\n          public Executor getExecutor() {\n            return null;\n          }\n        });\n  }\n\n  private void processServiceConfig(String content) {\n    if (StringUtils.isEmpty(content)) {\n      this.service = new HashMap<>();\n      return;\n    }\n    Parser contentParser = Parser.findParser(\"yaml\");\n    this.service = contentParser.parse(content, \"\", false);\n  }\n\n  private void addVersionConfig(ConfigService configService) throws NacosException {\n    String content = configService.getConfig(\n        BootStrapProperties.readServiceName(environment) + \"-\" +\n            BootStrapProperties.readServiceVersion(environment),\n        BootStrapProperties.readApplication(environment),\n        5000);\n    processVersionConfig(content);\n    configService.addListener(BootStrapProperties.readServiceName(environment) + \"-\" +\n            BootStrapProperties.readServiceVersion(environment),\n        BootStrapProperties.readApplication(environment), new Listener() {\n          @Override\n          public void receiveConfigInfo(String configInfo) {\n            processVersionConfig(configInfo);\n            refreshConfigItems();\n          }\n\n          @Override\n          public Executor getExecutor() {\n            return null;\n          }\n        });\n  }\n\n  private void processVersionConfig(String content) {\n    if (StringUtils.isEmpty(content)) {\n      this.version = new HashMap<>();\n      return;\n    }\n    Parser contentParser = Parser.findParser(\"yaml\");\n    this.version = contentParser.parse(content, \"\", false);\n  }\n\n  private void addProfileConfig(ConfigService configService) throws NacosException {\n    String profile = environment.getProperty(\"spring.profiles.active\");\n    if (StringUtils.isEmpty(profile)) {\n      return;\n    }\n    String content = configService.getConfig(BootStrapProperties.readServiceName(environment) + \"-\" + profile,\n        BootStrapProperties.readApplication(environment), 5000);\n    processProfileConfig(content);\n    configService.addListener(BootStrapProperties.readServiceName(environment) + \"-\" + profile,\n        BootStrapProperties.readApplication(environment), new Listener() {\n          @Override\n          public void receiveConfigInfo(String configInfo) {\n            processProfileConfig(configInfo);\n            refreshConfigItems();\n          }\n\n          @Override\n          public Executor getExecutor() {\n            return null;\n          }\n        });\n  }\n\n  private void processProfileConfig(String content) {\n    if (StringUtils.isEmpty(content)) {\n      this.profile = new HashMap<>();\n      return;\n    }\n    Parser contentParser = Parser.findParser(\"yaml\");\n    this.profile = contentParser.parse(content, \"\", false);\n  }\n\n  private void addCustomConfig(ConfigService configService) throws NacosException {\n    if (StringUtils.isEmpty(nacosConfig.getDataId()) || StringUtils.isEmpty(nacosConfig.getGroup())) {\n      return;\n    }\n    String content = configService.getConfig(nacosConfig.getDataId(),\n        nacosConfig.getGroup(), 5000);\n    processCustomConfig(content);\n    configService.addListener(nacosConfig.getDataId(),\n        nacosConfig.getGroup(), new Listener() {\n          @Override\n          public void receiveConfigInfo(String configInfo) {\n            processCustomConfig(configInfo);\n            refreshConfigItems();\n          }\n\n          @Override\n          public Executor getExecutor() {\n            return null;\n          }\n        });\n  }\n\n  private void processCustomConfig(String content) {\n    if (StringUtils.isEmpty(content)) {\n      this.custom = new HashMap<>();\n      return;\n    }\n    Parser contentParser = Parser.findParser(nacosConfig.getContentType());\n    String keyPrefix = nacosConfig.getGroup() + \".\" +\n        nacosConfig.getDataId();\n    this.custom = contentParser.parse(content, keyPrefix, nacosConfig.getAddPrefix());\n  }\n\n  private void refreshConfigItems() {\n    synchronized (lock) {\n      Map<String, Object> all = new HashMap<>();\n      all.putAll(application);\n      all.putAll(service);\n      all.putAll(version);\n      all.putAll(profile);\n      all.putAll(custom);\n      updateHandler.handle(all, allLast);\n      this.allLast = all;\n    }\n  }\n\n  private static Properties nacosProperties(Environment environment, NacosConfig nacosConfig) {\n    Properties properties = new Properties();\n    properties.put(NacosConfig.PROP_NAMESPACE, BootStrapProperties.readServiceEnvironment(environment));\n    properties.put(NacosConfig.PROP_ADDRESS, nacosConfig.getServerAddr());\n    if (nacosConfig.getUsername() != null) {\n      properties.put(NacosConfig.PROP_USERNAME, nacosConfig.getUsername());\n    }\n    if (nacosConfig.getPassword() != null) {\n      properties.put(NacosConfig.PROP_PASSWORD, nacosConfig.getPassword());\n    }\n    if (nacosConfig.getAccessKey() != null) {\n      properties.put(NacosConfig.PROP_ACCESS_KEY, nacosConfig.getAccessKey());\n    }\n    if (nacosConfig.getSecretKey() != null) {\n      properties.put(NacosConfig.PROP_SECRET_KEY, nacosConfig.getSecretKey());\n    }\n    return properties;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.nacos;\n\nimport org.springframework.core.env.Environment;\n\npublic class NacosConfig {\n  public static final String PROPERTY_DATA_ID = \"servicecomb.nacos.dataId\";\n\n  public static final String PROPERTY_SERVER_ADDR = \"servicecomb.nacos.serverAddr\";\n\n  public static final String PROPERTY_GROUP = \"servicecomb.nacos.group\";\n\n  public static final String PROPERTY_ADD_PREFIX = \"servicecomb.nacos.addPrefix\";\n\n  public static final String PROPERTY_CONTENT_TYPE = \"servicecomb.nacos.contentType\";\n\n  public static final String PROPERTY_USERNAME = \"servicecomb.nacos.username\";\n\n  public static final String PROPERTY_PASSWORD = \"servicecomb.nacos.password\";\n\n  public static final String PROPERTY_ACCESS_KEY = \"servicecomb.nacos.accessKey\";\n\n  public static final String PROPERTY_SECRET_KEY = \"servicecomb.nacos.secretKey\";\n\n  public static final String PROP_NAMESPACE = \"namespace\";\n\n  public static final String PROP_ADDRESS = \"serverAddr\";\n\n  public static final String PROP_USERNAME = \"username\";\n\n  public static final String PROP_PASSWORD = \"password\";\n\n  public static final String PROP_ACCESS_KEY = \"accessKey\";\n\n  public static final String PROP_SECRET_KEY = \"secretKey\";\n\n  private final Environment environment;\n\n  public NacosConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getServerAddr() {\n    return environment.getProperty(PROPERTY_SERVER_ADDR, \"http://127.0.0.1:8848\");\n  }\n\n  public String getDataId() {\n    return environment.getProperty(PROPERTY_DATA_ID);\n  }\n\n  public String getGroup() {\n    return environment.getProperty(PROPERTY_GROUP);\n  }\n\n  public String getUsername() {\n    return environment.getProperty(PROPERTY_USERNAME);\n  }\n\n  public String getPassword() {\n    return environment.getProperty(PROPERTY_PASSWORD);\n  }\n\n  public String getAccessKey() {\n    return environment.getProperty(PROPERTY_ACCESS_KEY);\n  }\n\n  public String getSecretKey() {\n    return environment.getProperty(PROPERTY_SECRET_KEY);\n  }\n\n  public String getContentType() {\n    return environment.getProperty(PROPERTY_CONTENT_TYPE, \"yaml\");\n  }\n\n  public boolean getAddPrefix() {\n    return environment.getProperty(PROPERTY_ADD_PREFIX, boolean.class, false);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/NacosDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.nacos;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\npublic class NacosDynamicPropertiesSource implements DynamicPropertiesSource {\n  public static final String SOURCE_NAME = \"nacos\";\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(NacosDynamicPropertiesSource.class);\n\n  private final Map<String, Object> valueCache = new ConcurrentHashMap<>();\n\n  public NacosDynamicPropertiesSource() {\n  }\n\n  private final UpdateHandler updateHandler = new UpdateHandler();\n\n  private void init(Environment environment) {\n    NacosClient nacosClient = new NacosClient(updateHandler, environment);\n    try {\n      nacosClient.refreshNacosConfig();\n    } catch (Exception e) {\n      throw new IllegalStateException(\"Set up nacos config failed.\", e);\n    }\n  }\n\n  public class UpdateHandler {\n    public void handle(Map<String, Object> current, Map<String, Object> last) {\n      ConfigurationChangedEvent event = ConfigurationChangedEvent.createIncremental(current, last);\n      LOGGER.info(\"Dynamic configuration changed: {}\", event.getChanged());\n      valueCache.putAll(event.getAdded());\n      valueCache.putAll(event.getUpdated());\n      event.getDeleted().forEach((k, v) -> valueCache.remove(k));\n      EventManager.post(event);\n    }\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    init(environment);\n    return new MapPropertySource(SOURCE_NAME, valueCache);\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-nacos/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.nacos.NacosDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/config-nacos/src/test/resources/microservice.yaml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nAPPLICATION_ID: nacostest\nservice_description:\n  name: nacos-test\n  version: 1.0.1\n\nservicecomb:\n  service:\n    registry:\n      address: http://127.0.0.1:30100\n  nacos:\n    serverAddr: 127.0.0.1:8848\n    dataId: example\n    group: DEFAULT_GROUP\n  rest:\n    address: 0.0.0.0:8080\n  highway:\n    address: 0.0.0.0:7070\n"
  },
  {
    "path": "dynamic-config/config-zookeeper/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>dynamic-config</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>config-zookeeper</artifactId>\n  <name>Java Chassis::Dynamic Config::Zookeeper</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <!--zookeeper client-->\n    <dependency>\n      <groupId>org.apache.curator</groupId>\n      <artifactId>curator-framework</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.curator</groupId>\n      <artifactId>curator-recipes</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "dynamic-config/config-zookeeper/src/main/java/org/apache/servicecomb/config/zookeeper/ZookeeperClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.zookeeper;\n\nimport java.io.StringReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport javax.security.auth.login.AppConfigurationEntry;\nimport javax.security.auth.login.Configuration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.curator.framework.CuratorFramework;\nimport org.apache.curator.framework.CuratorFrameworkFactory;\nimport org.apache.curator.framework.recipes.cache.CuratorCache;\nimport org.apache.curator.retry.ExponentialBackoffRetry;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.zookeeper.ZookeeperDynamicPropertiesSource.UpdateHandler;\nimport org.apache.zookeeper.server.auth.DigestLoginModule;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.config.YamlPropertiesFactoryBean;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.io.ByteArrayResource;\n\npublic class ZookeeperClient {\n  static class ZookeeperSASLConfig extends Configuration {\n    AppConfigurationEntry entry;\n\n    public ZookeeperSASLConfig(String username,\n        String password) {\n      Map<String, String> options = new HashMap<>();\n      options.put(\"username\", username);\n      options.put(\"password\", password);\n      this.entry = new AppConfigurationEntry(\n          DigestLoginModule.class.getName(),\n          AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,\n          options\n      );\n    }\n\n    @Override\n    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {\n      AppConfigurationEntry[] array = new AppConfigurationEntry[1];\n      array[0] = entry;\n      return array;\n    }\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperClient.class);\n\n  public static final String PATH_ENVIRONMENT = \"/servicecomb/config/environment/%s\";\n\n  public static final String PATH_APPLICATION = \"/servicecomb/config/application/%s/%s\";\n\n  public static final String PATH_SERVICE = \"/servicecomb/config/service/%s/%s/%s\";\n\n  public static final String PATH_VERSION = \"/servicecomb/config/version/%s/%s/%s/%s\";\n\n  public static final String PATH_TAG = \"/servicecomb/config/tag/%s/%s/%s/%s/%s\";\n\n  private final UpdateHandler updateHandler;\n\n  private final ZookeeperConfig zookeeperConfig;\n\n  private final Environment environment;\n\n  private final Object lock = new Object();\n\n  private Map<String, Object> environmentData = new HashMap<>();\n\n  private Map<String, Object> applicationData = new HashMap<>();\n\n  private Map<String, Object> serviceData = new HashMap<>();\n\n  private Map<String, Object> versionData = new HashMap<>();\n\n  private Map<String, Object> tagData = new HashMap<>();\n\n  private Map<String, Object> allLast = new HashMap<>();\n\n\n  public ZookeeperClient(UpdateHandler updateHandler, Environment environment) {\n    this.updateHandler = updateHandler;\n    this.zookeeperConfig = new ZookeeperConfig(environment);\n    this.environment = environment;\n  }\n\n  public void refreshZookeeperConfig() throws Exception {\n    CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()\n        .connectString(zookeeperConfig.getConnectString())\n        .sessionTimeoutMs(zookeeperConfig.getSessionTimeoutMillis())\n        .retryPolicy(new ExponentialBackoffRetry(1000, 3));\n    String authSchema = zookeeperConfig.getAuthSchema();\n    if (StringUtils.isNotEmpty(authSchema)) {\n      if (!\"digest\".equals(authSchema)) {\n        throw new IllegalStateException(\"Not supported schema now. \" + authSchema);\n      }\n      if (zookeeperConfig.getAuthInfo() == null) {\n        throw new IllegalStateException(\"Auth info can not be empty. \");\n      }\n\n      String[] authInfo = zookeeperConfig.getAuthInfo().split(\":\");\n      Configuration.setConfiguration(new ZookeeperSASLConfig(authInfo[0], authInfo[1]));\n    }\n    CuratorFramework client = builder.build();\n    client.start();\n\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = ZookeeperConfig.ZOOKEEPER_DEFAULT_ENVIRONMENT;\n    }\n    addEnvironmentConfig(env, client);\n    addApplicationConfig(env, client);\n    addServiceConfig(env, client);\n    addVersionConfig(env, client);\n    addTagConfig(env, client);\n\n    refreshConfigItems();\n  }\n\n  private void addTagConfig(String env, CuratorFramework client) throws Exception {\n    if (StringUtils.isEmpty(zookeeperConfig.getInstanceTag())) {\n      return;\n    }\n    String path = String.format(PATH_TAG, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment),\n        zookeeperConfig.getInstanceTag());\n    CuratorCache cache = CuratorCache.builder(client, path).build();\n    cache.listenable().addListener((type, oldData, newData) -> {\n      try {\n        this.tagData = parseData(client, path);\n        refreshConfigItems();\n      } catch (Exception e) {\n        LOGGER.error(\"process event failed\", e);\n      }\n    });\n    cache.start();\n    this.tagData = parseData(client, path);\n  }\n\n  private void addVersionConfig(String env, CuratorFramework client) throws Exception {\n    String path = String.format(PATH_VERSION, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment),\n        BootStrapProperties.readServiceVersion(environment));\n    CuratorCache cache = CuratorCache.builder(client, path).build();\n    cache.listenable().addListener((type, oldData, newData) -> {\n      try {\n        this.versionData = parseData(client, path);\n        refreshConfigItems();\n      } catch (Exception e) {\n        LOGGER.error(\"process event failed\", e);\n      }\n    });\n    cache.start();\n    this.versionData = parseData(client, path);\n  }\n\n  private void addServiceConfig(String env, CuratorFramework client) throws Exception {\n    String path = String.format(PATH_SERVICE, env,\n        BootStrapProperties.readApplication(environment),\n        BootStrapProperties.readServiceName(environment));\n    CuratorCache cache = CuratorCache.builder(client, path).build();\n    cache.listenable().addListener((type, oldData, newData) -> {\n      try {\n        this.serviceData = parseData(client, path);\n        refreshConfigItems();\n      } catch (Exception e) {\n        LOGGER.error(\"process event failed\", e);\n      }\n    });\n    cache.start();\n    this.serviceData = parseData(client, path);\n  }\n\n  private void addApplicationConfig(String env, CuratorFramework client) throws Exception {\n    String path = String.format(PATH_APPLICATION, env, BootStrapProperties.readApplication(environment));\n    CuratorCache cache = CuratorCache.builder(client, path).build();\n    cache.listenable().addListener((type, oldData, newData) -> {\n      try {\n        this.applicationData = parseData(client, path);\n        refreshConfigItems();\n      } catch (Exception e) {\n        LOGGER.error(\"process event failed\", e);\n      }\n    });\n    cache.start();\n    this.applicationData = parseData(client, path);\n  }\n\n  private void addEnvironmentConfig(String env, CuratorFramework client) throws Exception {\n    String path = String.format(PATH_ENVIRONMENT, env);\n    CuratorCache cache = CuratorCache.builder(client, path).build();\n    cache.listenable().addListener((type, oldData, newData) -> {\n      try {\n        this.environmentData = parseData(client, path);\n        refreshConfigItems();\n      } catch (Exception e) {\n        LOGGER.error(\"process event failed\", e);\n      }\n    });\n    cache.start();\n    this.environmentData = parseData(client, path);\n  }\n\n  private Map<String, Object> parseData(CuratorFramework client, String path) throws Exception {\n    Map<String, Object> values = new HashMap<>();\n\n    if (client.checkExists().forPath(path) != null) {\n      client.getChildren().forPath(path).stream().sorted().forEach(item -> {\n        try {\n          byte[] data = client.getData().forPath(path + \"/\" + item);\n          if (item.endsWith(\".yaml\") || item.endsWith(\".yml\")) {\n            YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();\n            yamlFactory.setResources(new ByteArrayResource(data));\n            values.putAll(toMap(yamlFactory.getObject()));\n          } else if (item.endsWith(\".properties\")) {\n            Properties properties = new Properties();\n            properties.load(new StringReader(new String(data, StandardCharsets.UTF_8)));\n            values.putAll(toMap(properties));\n          } else {\n            values.put(item, new String(data, StandardCharsets.UTF_8));\n          }\n        } catch (Exception e) {\n          LOGGER.error(\"\", e);\n        }\n      });\n    }\n\n    return values;\n  }\n\n  private void refreshConfigItems() {\n    synchronized (lock) {\n      Map<String, Object> all = new HashMap<>();\n      all.putAll(environmentData);\n      all.putAll(applicationData);\n      all.putAll(serviceData);\n      all.putAll(versionData);\n      all.putAll(tagData);\n      updateHandler.handle(all, allLast);\n      this.allLast = all;\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private Map<String, Object> toMap(Properties properties) {\n    if (properties == null) {\n      return Collections.emptyMap();\n    }\n    Map<String, Object> result = new HashMap<>();\n    Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();\n    while (keys.hasMoreElements()) {\n      String key = keys.nextElement();\n      Object value = properties.getProperty(key);\n      result.put(key, value);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-zookeeper/src/main/java/org/apache/servicecomb/config/zookeeper/ZookeeperConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.zookeeper;\n\nimport org.springframework.core.env.Environment;\n\npublic class ZookeeperConfig {\n  public static final String ZOOKEEPER_DEFAULT_ENVIRONMENT = \"production\";\n\n  public static final String PROPERTY_CONNECT_STRING = \"servicecomb.config.zk.connect-string\";\n\n  public static final String PROPERTY_SESSION_TIMEOUT = \"servicecomb.config.zk.session-timeout-millis\";\n\n  public static final String PROPERTY_CONNECTION_TIMEOUT = \"servicecomb.config.zk.connection-timeout-mills\";\n\n  public static final String PROPERTY_AUTH_SCHEMA = \"servicecomb.config.zk.authentication-schema\";\n\n  public static final String PROPERTY_AUTH_INFO = \"servicecomb.config.zk.authentication-info\";\n\n  public static final String PROPERTY_INSTANCE_TAG = \"servicecomb.config.zk.instance-tag\";\n\n  private final Environment environment;\n\n  public ZookeeperConfig(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getConnectString() {\n    return environment.getProperty(PROPERTY_CONNECT_STRING, \"127.0.0.1:2181\");\n  }\n\n  public int getSessionTimeoutMillis() {\n    return environment.getProperty(PROPERTY_SESSION_TIMEOUT, int.class, 60000);\n  }\n\n  public int getConnectionTimeoutMillis() {\n    return environment.getProperty(PROPERTY_CONNECTION_TIMEOUT, int.class, 1000);\n  }\n\n  public String getAuthSchema() {\n    return environment.getProperty(PROPERTY_AUTH_SCHEMA);\n  }\n\n  public String getAuthInfo() {\n    return environment.getProperty(PROPERTY_AUTH_INFO);\n  }\n\n  public String getInstanceTag() {\n    return environment.getProperty(PROPERTY_INSTANCE_TAG);\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-zookeeper/src/main/java/org/apache/servicecomb/config/zookeeper/ZookeeperDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.zookeeper;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.DynamicPropertiesSource;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\npublic class ZookeeperDynamicPropertiesSource implements DynamicPropertiesSource {\n  public static final String SOURCE_NAME = \"zookeeper\";\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperDynamicPropertiesSource.class);\n\n  private final Map<String, Object> valueCache = new ConcurrentHashMap<>();\n\n  public ZookeeperDynamicPropertiesSource() {\n  }\n\n  private final UpdateHandler updateHandler = new UpdateHandler();\n\n  private void init(Environment environment) {\n    ZookeeperClient zookeeperClient = new ZookeeperClient(updateHandler, environment);\n    try {\n      zookeeperClient.refreshZookeeperConfig();\n    } catch (Exception e) {\n      throw new IllegalStateException(\"Set up zookeeper config failed.\", e);\n    }\n  }\n\n  public class UpdateHandler {\n    public void handle(Map<String, Object> current, Map<String, Object> last) {\n      ConfigurationChangedEvent event = ConfigurationChangedEvent.createIncremental(current, last);\n      LOGGER.info(\"Dynamic configuration changed: {}\", event.getChanged());\n      valueCache.putAll(event.getAdded());\n      valueCache.putAll(event.getUpdated());\n      event.getDeleted().forEach((k, v) -> valueCache.remove(k));\n      EventManager.post(event);\n    }\n  }\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    init(environment);\n    return new MapPropertySource(SOURCE_NAME, valueCache);\n  }\n\n  @Override\n  public int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "dynamic-config/config-zookeeper/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.zookeeper.ZookeeperDynamicPropertiesSource\n"
  },
  {
    "path": "dynamic-config/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>dynamic-config</artifactId>\n  <name>Java Chassis::Dynamic Config</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>config-apollo</module>\n    <module>config-cc</module>\n    <module>config-nacos</module>\n    <module>config-kie</module>\n    <module>config-zookeeper</module>\n    <module>config-etcd</module>\n    <module>config-consul</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "edge/edge-core/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>edge</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>edge-core</artifactId>\n  <name>Java Chassis::Edge::Core</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/AbstractEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.apache.servicecomb.transport.rest.vertx.AbstractVertxHttpDispatcher;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.RoutingContext;\n\npublic abstract class AbstractEdgeDispatcher extends AbstractVertxHttpDispatcher {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractEdgeDispatcher.class);\n\n  protected void onFailure(RoutingContext context) {\n    LOGGER.error(\"edge server failed.\", context.failure());\n    HttpServerResponse response = context.response();\n    if (response.closed() || response.ended()) {\n      return;\n    }\n\n    if (context.failure() instanceof InvocationException) {\n      InvocationException exception = (InvocationException) context.failure();\n      response.setStatusCode(exception.getStatusCode());\n      response.setStatusMessage(exception.getReasonPhrase());\n      if (null == exception.getErrorData()) {\n        response.end();\n        return;\n      }\n\n      String responseBody;\n      try {\n        responseBody = RestObjectMapperFactory.getRestObjectMapper().writeValueAsString(exception.getErrorData());\n        response.putHeader(\"Content-Type\", MediaType.APPLICATION_JSON);\n      } catch (JsonProcessingException e) {\n        responseBody = exception.getErrorData().toString();\n        response.putHeader(\"Content-Type\", MediaType.TEXT_PLAIN);\n      }\n      response.end(responseBody);\n    } else {\n      response.setStatusCode(Status.BAD_GATEWAY.getStatusCode());\n      response.setStatusMessage(Status.BAD_GATEWAY.getReasonPhrase());\n      response.end();\n    }\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/CommonHttpEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationItem;\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationLoader;\nimport org.apache.servicecomb.common.rest.route.Utils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.loadbalance.ExtensionsManager;\nimport org.apache.servicecomb.loadbalance.LoadBalanceFilter;\nimport org.apache.servicecomb.loadbalance.LoadBalancer;\nimport org.apache.servicecomb.loadbalance.RuleExt;\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\nimport org.apache.servicecomb.transport.rest.client.Http2TransportHttpClientOptionsSPI;\nimport org.apache.servicecomb.transport.rest.client.HttpTransportHttpClientOptionsSPI;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.Subscribe;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClient;\nimport io.vertx.core.http.RequestOptions;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * This dispatcher forwards requests to any http servers, includes java-chassis providers and other,\n * provided the server is registered to service center.\n *\n * This dispatcher using loadbalance handler to choose the target server. So any functions\n * provided by loadbalancer handler is available, excluding retrying.\n */\npublic class CommonHttpEdgeDispatcher extends AbstractEdgeDispatcher {\n  private static final Logger LOG = LoggerFactory.getLogger(CommonHttpEdgeDispatcher.class);\n\n  private static final String KEY_ENABLED = \"servicecomb.http.dispatcher.edge.http.enabled\";\n\n  private static final String KEY_ORDER = \"servicecomb.http.dispatcher.edge.http.order\";\n\n  private static final String KEY_PATTERN = \"servicecomb.http.dispatcher.edge.http.pattern\";\n\n  private static final String PATTERN_ANY = \"/(.*)\";\n\n  private static final String KEY_MAPPING_PREFIX = \"servicecomb.http.dispatcher.edge.http.mappings\";\n\n  private final Map<String, LoadBalancer> loadBalancerMap = new ConcurrentHashMapEx<>();\n\n  private Map<String, URLMappedConfigurationItem> configurations = new HashMap<>();\n\n  private Environment environment;\n\n  public CommonHttpEdgeDispatcher() {\n\n  }\n\n  // though this is an SPI, but add as beans.\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n    if (this.enabled()) {\n      loadConfigurations();\n    }\n  }\n\n  // Maybe future change to beans\n  protected DiscoveryTree getDiscoveryTree() {\n    return BeanUtils.getBean(DiscoveryTree.class);\n  }\n\n  // Maybe future change to beans\n  protected Environment getEnvironment() {\n    return BeanUtils.getBean(Environment.class);\n  }\n\n  // Maybe future change to beans\n  protected ExtensionsManager getExtensionsManager() {\n    return BeanUtils.getBean(ExtensionsManager.class);\n  }\n\n  @Override\n  public int getOrder() {\n    return LegacyPropertyFactory.getIntProperty(KEY_ORDER, 40_000);\n  }\n\n  @Override\n  public boolean enabled() {\n    return environment.getProperty(KEY_ENABLED, boolean.class, false);\n  }\n\n  @Override\n  public void init(Router router) {\n    String pattern = environment.getProperty(KEY_PATTERN, PATTERN_ANY);\n    router.routeWithRegex(pattern).failureHandler(this::onFailure).handler(this::onRequest);\n  }\n\n  private void loadConfigurations() {\n    configurations = URLMappedConfigurationLoader.loadConfigurations(environment, KEY_MAPPING_PREFIX);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(KEY_MAPPING_PREFIX)) {\n        loadConfigurations();\n        break;\n      }\n    }\n  }\n\n  protected void onRequest(RoutingContext context) {\n    URLMappedConfigurationItem configurationItem = findConfigurationItem(context.request().uri());\n    if (configurationItem == null) {\n      context.next();\n      return;\n    }\n\n    String uri = Utils.findActualPath(context.request().uri(), configurationItem.getPrefixSegmentCount());\n\n    Invocation invocation = new Invocation() {\n      @Override\n      public String getConfigTransportName() {\n        return \"rest\";\n      }\n\n      @Override\n      public String getMicroserviceName() {\n        return configurationItem.getMicroserviceName();\n      }\n    };\n\n    LoadBalancer loadBalancer = getOrCreateLoadBalancer(invocation, configurationItem.getMicroserviceName()\n    );\n    ServiceCombServer server = loadBalancer.chooseServer(invocation);\n    if (server == null) {\n      LOG.warn(\"no available server for service {}\", configurationItem.getMicroserviceName());\n      serverNotReadyResponse(context);\n      return;\n    }\n\n    URIEndpointObject endpointObject = new URIEndpointObject(server.getEndpoint().getEndpoint());\n\n    RequestOptions requestOptions = new RequestOptions();\n    requestOptions.setHost(endpointObject.getHostOrIp())\n        .setPort(endpointObject.getPort())\n        .setSsl(endpointObject.isSslEnabled())\n        .setMethod(context.request().method())\n        .setURI(uri);\n\n    HttpClient httpClient;\n    if (endpointObject.isHttp2Enabled()) {\n      httpClient = HttpClients.getClient(Http2TransportHttpClientOptionsSPI.CLIENT_NAME, false).getHttpClient();\n    } else {\n      httpClient = HttpClients.getClient(HttpTransportHttpClientOptionsSPI.CLIENT_NAME, false).getHttpClient();\n    }\n\n    context.request().pause();\n\n    httpClient\n        .request(requestOptions).compose(httpClientRequest -> {\n          context.request().headers()\n              .forEach((header) -> httpClientRequest.headers().set(header.getKey(), header.getValue()));\n\n          context.request().resume();\n          context.request().handler(httpClientRequest::write);\n          context.request().endHandler((v) -> httpClientRequest.end());\n\n          return httpClientRequest.response().compose(httpClientResponse -> {\n            context.response().setStatusCode(httpClientResponse.statusCode());\n            httpClientResponse.headers()\n                .forEach((header) -> context.response().headers().set(header.getKey(), header.getValue()));\n            httpClientResponse.handler(this.responseHandler(context));\n            httpClientResponse.endHandler((v) -> context.response().end());\n            return Future.succeededFuture();\n          });\n        }).onFailure(failure -> {\n          LOG.warn(\"send request to target {}:{} failed, cause {}\", endpointObject.getHostOrIp(), endpointObject.getPort(),\n              failure.getMessage());\n          serverNotReadyResponse(context);\n        });\n  }\n\n  private void serverNotReadyResponse(RoutingContext context) {\n    context.response().setStatusCode(503);\n    context.response().setStatusMessage(\"service not ready\");\n    context.response().end();\n  }\n\n  protected Handler<Buffer> responseHandler(RoutingContext routingContext) {\n    return data -> routingContext.response().write(data);\n  }\n\n  protected LoadBalancer getOrCreateLoadBalancer(Invocation invocation, String microserviceName) {\n    DiscoveryContext context = new DiscoveryContext();\n    context.setInputParameters(invocation);\n    VersionedCache serversVersionedCache = getDiscoveryTree().discovery(context,\n        BootStrapProperties.readApplication(environment),\n        microserviceName);\n    invocation.addLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST, serversVersionedCache.data());\n    return loadBalancerMap\n        .computeIfAbsent(microserviceName, name -> createLoadBalancer(microserviceName));\n  }\n\n  private LoadBalancer createLoadBalancer(String microserviceName) {\n    RuleExt rule = getExtensionsManager().createLoadBalancerRule(microserviceName);\n    return new LoadBalancer(rule, microserviceName);\n  }\n\n  private URLMappedConfigurationItem findConfigurationItem(String path) {\n    for (URLMappedConfigurationItem item : configurations.values()) {\n      if (item.getPattern().matcher(path).matches()) {\n        return item;\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport org.apache.servicecomb.common.rest.RestProducerInvocationFlow;\nimport org.apache.servicecomb.common.rest.route.Utils;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.codegen.annotations.Nullable;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\n\n/**\n * Provide an easy mapping dispatcher that starts with a common prefix pattern.\n */\npublic class DefaultEdgeDispatcher extends AbstractEdgeDispatcher {\n\n  private static final String KEY_ENABLED = \"servicecomb.http.dispatcher.edge.default.enabled\";\n\n  private static final String KEY_ORDER = \"servicecomb.http.dispatcher.edge.default.order\";\n\n  private static final String KEY_PREFIX = \"servicecomb.http.dispatcher.edge.default.prefix\";\n\n  private static final String KEY_PREFIX_SEGMENT_COUNT = \"servicecomb.http.dispatcher.edge.default.prefixSegmentCount\";\n\n  public static final String MICROSERVICE_NAME = \"param0\";\n\n  private int prefixSegmentCount;\n\n  private Environment environment;\n\n  // though this is an SPI, but add as beans.\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public int getOrder() {\n    // can not use environment, add as beans is later than instantiate SPI\n    return LegacyPropertyFactory.getIntProperty(KEY_ORDER, 20_000);\n  }\n\n  @Override\n  public boolean enabled() {\n    return environment.getProperty(KEY_ENABLED, boolean.class, false);\n  }\n\n  @Override\n  public void init(Router router) {\n    String prefix = environment.getProperty(KEY_PREFIX, \"api\");\n    prefixSegmentCount = environment.getProperty(KEY_PREFIX_SEGMENT_COUNT, int.class, 1);\n    String regex = generateRouteRegex(prefix, false);\n\n    // cookies handler are enabled by default start from 3.8.3\n    router.routeWithRegex(regex).handler(createBodyHandler());\n    router.routeWithRegex(regex).failureHandler(this::onFailure).handler(this::onRequest);\n  }\n\n  @VisibleForTesting\n  String generateRouteRegex(String prefix, boolean withVersion) {\n    String version = withVersion ? \"/([^\\\\\\\\/]+)\" : \"\";\n    return String.format(\"/%s/([^\\\\\\\\/]+)%s/(.*)\", prefix, version);\n  }\n\n  protected void onRequest(RoutingContext context) {\n    String microserviceName = extractMicroserviceName(context);\n    String path = Utils.findActualPath(context.request().path(), prefixSegmentCount);\n\n    requestByFilter(context, microserviceName, path);\n  }\n\n  @Nullable\n  private String extractMicroserviceName(RoutingContext context) {\n    return context.pathParam(MICROSERVICE_NAME);\n  }\n\n  protected void requestByFilter(RoutingContext context, String microserviceName, String path) {\n    HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context);\n    HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response());\n    InvocationCreator creator = new EdgeInvocationCreator(context, requestEx, responseEx,\n        microserviceName, path);\n    new RestProducerInvocationFlow(creator, requestEx, responseEx)\n        .run();\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeAddHeaderFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.edge.core;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.transport.rest.client.RestClientTransportContext;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic class EdgeAddHeaderFilter extends AbstractFilter implements EdgeFilter {\n  public static final String NAME = \"edge-add-headers\";\n\n  private static final String PREFIX = \"servicecomb.edge.filter.addHeader\";\n\n  private static final String KEY_HEADERS = PREFIX + \".allowedHeaders\";\n\n  private final Environment environment;\n\n  private List<String> publicHeaders = new ArrayList<>();\n\n  public EdgeAddHeaderFilter(Environment environment) {\n    this.environment = environment;\n    init();\n    EventManager.register(this);\n  }\n\n  @Subscribe\n  @SuppressWarnings(\"unused\")\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(PREFIX)) {\n        init();\n        break;\n      }\n    }\n  }\n\n  private void init() {\n    String publicHeaderStr = environment.getProperty(KEY_HEADERS);\n    if (StringUtils.isEmpty(publicHeaderStr)) {\n      return;\n    }\n    publicHeaders = Arrays.asList(publicHeaderStr.split(\",\"));\n  }\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.RESTFUL.equals(transport);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1995;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (publicHeaders.isEmpty()) {\n      return nextNode.onFilter(invocation);\n    }\n\n    RestClientTransportContext transportContext = invocation.getTransportContext();\n    HttpServletRequestEx oldRequest = invocation.getRequestEx();\n    publicHeaders.forEach(key -> {\n      String value = oldRequest.getHeader(key);\n      if (StringUtils.isNotEmpty(value)) {\n        transportContext.getHttpClientRequest().putHeader(key, value);\n      }\n    });\n\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.executor.ExecutorManager;\nimport org.apache.servicecomb.transport.rest.vertx.TransportConfig;\n\npublic class EdgeBootListener implements BootListener {\n  @Override\n  public void onBootEvent(BootEvent event) {\n    if (!EventType.BEFORE_PRODUCER_PROVIDER.equals(event.getEventType())) {\n      return;\n    }\n\n    TransportConfig.setRestServerVerticle(EdgeRestServerVerticle.class);\n    ExecutorManager.setExecutorDefault(ExecutorManager.EXECUTOR_REACTIVE);\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeCoreConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.edge.core;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\npublic class EdgeCoreConfiguration {\n  @Bean\n  public EdgeBootListener scbEdgeBootListener() {\n    return new EdgeBootListener();\n  }\n\n  @Bean\n  public EdgeAddHeaderFilter scbEdgeAddHeaderFilter(Environment environment) {\n    return new EdgeAddHeaderFilter(environment);\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.edge.core;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.common.rest.RestVertxProducerInvocationCreator;\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\n\nimport io.vertx.core.Vertx;\nimport io.vertx.ext.web.RoutingContext;\n\npublic class EdgeInvocationCreator extends RestVertxProducerInvocationCreator {\n  public static final String EDGE_INVOCATION_CONTEXT = \"edgeInvocationContext\";\n\n  protected final String microserviceName;\n\n  protected final String path;\n\n  protected MicroserviceReferenceConfig microserviceReferenceConfig;\n\n  public EdgeInvocationCreator(RoutingContext routingContext,\n      HttpServletRequestEx requestEx, HttpServletResponseEx responseEx,\n      String microserviceName, String path) {\n    // Set endpoint before load balance because edge service will use RESTFUL transport filters.\n    super(routingContext, null,\n        SCBEngine.getInstance().getTransportManager().findTransport(CoreConst.RESTFUL).getEndpoint(),\n        requestEx, responseEx);\n\n    this.microserviceName = microserviceName;\n    this.path = path;\n  }\n\n  @Override\n  public CompletableFuture<Invocation> createAsync() {\n    return createMicroserviceReferenceConfig()\n        .thenCompose(v -> super.createAsync());\n  }\n\n  protected CompletableFuture<Void> createMicroserviceReferenceConfig() {\n    return SCBEngine.getInstance()\n        .getOrCreateReferenceConfigAsync(microserviceName)\n        .thenAccept(mrc -> {\n          this.microserviceReferenceConfig = mrc;\n          this.microserviceMeta = mrc.getMicroserviceMeta();\n        });\n  }\n\n  @Override\n  protected OperationLocator locateOperation(ServicePathManager servicePathManager) {\n    return servicePathManager.consumerLocateOperation(path, requestEx.getMethod());\n  }\n\n  @Override\n  protected Invocation createInstance() {\n    ReferenceConfig referenceConfig = microserviceReferenceConfig\n        .createReferenceConfig(restOperationMeta.getOperationMeta());\n\n    Invocation invocation = InvocationFactory.forConsumer(referenceConfig,\n        restOperationMeta.getOperationMeta(),\n        restOperationMeta.getOperationMeta().buildBaseConsumerRuntimeType(),\n        null);\n    invocation.setSync(false);\n    invocation.setEdge();\n    invocation.setEndpoint(endpoint); // ensure transport name is correct\n    invocation.addLocalContext(EDGE_INVOCATION_CONTEXT, Vertx.currentContext());\n\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeRestServerVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.edge.core;\n\nimport org.apache.servicecomb.transport.rest.vertx.RestServerVerticle;\n\npublic class EdgeRestServerVerticle extends RestServerVerticle {\n  @Override\n  public void start() throws Exception {\n    super.start();\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestProducerInvocationFlow;\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationItem;\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationLoader;\nimport org.apache.servicecomb.common.rest.route.Utils;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;\nimport org.apache.servicecomb.transport.rest.vertx.RestBodyHandler;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.eventbus.Subscribe;\n\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\nimport io.vertx.ext.web.handler.PlatformHandler;\n\n/**\n * Provide a URL mapping based dispatcher. Users configure witch URL patterns dispatch to a target service.\n */\npublic class URLMappedEdgeDispatcher extends AbstractEdgeDispatcher {\n  public static final String CONFIGURATION_ITEM = \"URLMappedConfigurationItem\";\n\n  private static final String PATTERN_ANY = \"/(.*)\";\n\n  private static final String KEY_ORDER = \"servicecomb.http.dispatcher.edge.url.order\";\n\n  private static final String KEY_ENABLED = \"servicecomb.http.dispatcher.edge.url.enabled\";\n\n  private static final String KEY_PATTERN = \"servicecomb.http.dispatcher.edge.url.pattern\";\n\n  private static final String KEY_MAPPING_PREFIX = \"servicecomb.http.dispatcher.edge.url.mappings\";\n\n  private Map<String, URLMappedConfigurationItem> configurations = new HashMap<>();\n\n  private Environment environment;\n\n  public URLMappedEdgeDispatcher() {\n    EventManager.register(this);\n  }\n\n  // though this is an SPI, but add as beans.\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n    if (this.enabled()) {\n      loadConfigurations();\n    }\n  }\n\n  @VisibleForTesting\n  public Map<String, URLMappedConfigurationItem> getConfigurations() {\n    return configurations;\n  }\n\n  @Override\n  public int getOrder() {\n    return LegacyPropertyFactory.getIntProperty(KEY_ORDER, 30_000);\n  }\n\n  @Override\n  public boolean enabled() {\n    return environment.getProperty(KEY_ENABLED, boolean.class, false);\n  }\n\n  @Override\n  public void init(Router router) {\n    // cookies handler are enabled by default start from 3.8.3\n    String pattern = environment.getProperty(KEY_PATTERN, PATTERN_ANY);\n    router.routeWithRegex(pattern).failureHandler(this::onFailure)\n        .handler((PlatformHandler) URLMappedEdgeDispatcher.this::preCheck)\n        .handler(createBodyHandler())\n        .handler(this::onRequest);\n  }\n\n  private void loadConfigurations() {\n    configurations = URLMappedConfigurationLoader.loadConfigurations(environment, KEY_MAPPING_PREFIX);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(KEY_MAPPING_PREFIX)) {\n        loadConfigurations();\n        break;\n      }\n    }\n  }\n\n  protected void preCheck(RoutingContext context) {\n    URLMappedConfigurationItem configurationItem = findConfigurationItem(context.request().path());\n    if (configurationItem == null) {\n      // by pass body handler flag\n      context.put(RestBodyHandler.BYPASS_BODY_HANDLER, Boolean.TRUE);\n      context.next();\n      return;\n    }\n    context.put(CONFIGURATION_ITEM, configurationItem);\n    context.next();\n  }\n\n  protected void onRequest(RoutingContext context) {\n    Boolean bypass = context.get(RestBodyHandler.BYPASS_BODY_HANDLER);\n    if (Boolean.TRUE.equals(bypass)) {\n      // clear flag\n      context.put(RestBodyHandler.BYPASS_BODY_HANDLER, Boolean.FALSE);\n      context.next();\n      return;\n    }\n\n    URLMappedConfigurationItem configurationItem = context.get(CONFIGURATION_ITEM);\n\n    String path = Utils.findActualPath(context.request().path(), configurationItem.getPrefixSegmentCount());\n\n    requestByFilter(context, configurationItem, path);\n  }\n\n  protected void requestByFilter(RoutingContext context, URLMappedConfigurationItem configurationItem, String path) {\n    HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context);\n    HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response());\n    InvocationCreator creator = new EdgeInvocationCreator(context, requestEx, responseEx,\n        configurationItem.getMicroserviceName(), path);\n    new RestProducerInvocationFlow(creator, requestEx, responseEx)\n        .run();\n  }\n\n  private URLMappedConfigurationItem findConfigurationItem(String path) {\n    for (URLMappedConfigurationItem item : configurations.values()) {\n      if (item.getPattern().matcher(path).matches()) {\n        return item;\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/main/resources/META-INF/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: -500\n\nservicecomb:\n  context:\n    # do not decode invocation context for edge service by default\n    decodeInvocationContext: false\n"
  },
  {
    "path": "edge/edge-core/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.edge.core.DefaultEdgeDispatcher\norg.apache.servicecomb.edge.core.URLMappedEdgeDispatcher\norg.apache.servicecomb.edge.core.CommonHttpEdgeDispatcher\n"
  },
  {
    "path": "edge/edge-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.edge.core.EdgeCoreConfiguration\n"
  },
  {
    "path": "edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestAbstractEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestAbstractEdgeDispatcher {\n  static class AbstractEdgeDispatcherForTest extends AbstractEdgeDispatcher {\n    @Override\n    public int getOrder() {\n      return 0;\n    }\n\n    @Override\n    public void init(Router router) {\n    }\n  }\n\n  @Test\n  public void onFailure() {\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n\n    HttpServerResponse response = Mockito.mock(HttpServerResponse.class);\n\n    Mockito.when(context.response()).thenReturn(response);\n    Mockito.when(context.failure()).thenReturn(new RuntimeExceptionWithoutStackTrace(\"failed\"));\n\n    AbstractEdgeDispatcherForTest dispatcher = new AbstractEdgeDispatcherForTest();\n    dispatcher.onFailure(context);\n\n    Mockito.verify(response).setStatusMessage(\"Bad Gateway\");\n    Mockito.verify(response).setStatusCode(502);\n\n    Mockito.when(context.failure()).thenReturn(new InvocationException(401, \"unauthorized\", \"unauthorized\"));\n\n    dispatcher = new AbstractEdgeDispatcherForTest();\n    dispatcher.onFailure(context);\n    Mockito.verify(response).setStatusMessage(\"unauthorized\");\n    Mockito.verify(response).setStatusCode(401);\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestURLMappedEdgeDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationItem;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.transport.rest.vertx.RestBodyHandler;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.MutablePropertySources;\n\nimport io.vertx.ext.web.RoutingContext;\n\npublic class TestURLMappedEdgeDispatcher {\n  ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\n\n  @BeforeEach\n  public void setUp() throws Exception {\n  }\n\n  @AfterEach\n  public void tearDown() {\n  }\n\n  @Test\n  public void testConfigurations() {\n    EnumerablePropertySource<?> propertySource = Mockito.mock(EnumerablePropertySource.class);\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.enabled\", boolean.class, false))\n        .thenReturn(true);\n    URLMappedEdgeDispatcher dispatcher = new URLMappedEdgeDispatcher();\n    dispatcher.setEnvironment(environment);\n    Map<String, URLMappedConfigurationItem> items = dispatcher.getConfigurations();\n    Assertions.assertEquals(items.size(), 0);\n\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n    Mockito.when(context.get(RestBodyHandler.BYPASS_BODY_HANDLER)).thenReturn(Boolean.TRUE);\n    dispatcher.onRequest(context);\n\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.path\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.microserviceName\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.prefixSegmentCount\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.versionRule\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.mappings.service1.path\"))\n        .thenReturn(\"/a/b/c/.*\");\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.mappings.service1.microserviceName\"))\n        .thenReturn(\"serviceName\");\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.mappings.service1.prefixSegmentCount\",\n            int.class, 0))\n        .thenReturn(2);\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.mappings.service1.versionRule\",\n            \"0.0.0+\"))\n        .thenReturn(\"2.0.0+\");\n    Map<String, Object> latest = new HashMap<>();\n    latest.put(\"servicecomb.http.dispatcher.edge.url.mappings.service1.path\", \"/a/b/c/.*\");\n    dispatcher.onConfigurationChangedEvent(ConfigurationChangedEvent.createIncremental(latest, new HashMap<>()));\n\n    items = dispatcher.getConfigurations();\n    Assertions.assertEquals(items.size(), 1);\n    URLMappedConfigurationItem item = items.get(\"service1\");\n    Assertions.assertEquals(item.getMicroserviceName(), \"serviceName\");\n    Assertions.assertEquals(item.getPrefixSegmentCount(), 2);\n    Assertions.assertEquals(item.getStringPattern(), \"/a/b/c/.*\");\n    Assertions.assertEquals(item.getVersionRule(), \"2.0.0+\");\n\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.path\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.microserviceName\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.prefixSegmentCount\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service1.versionRule\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service2.versionRule\",\n        \"servicecomb.http.dispatcher.edge.url.mappings.service3.path\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.mappings.service2.versionRule\"))\n        .thenReturn(\"2.0.0+\");\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.edge.url.mappings.service3.path\"))\n        .thenReturn(\"/b/c/d/.*\");\n\n    latest = new HashMap<>();\n    latest.put(\"servicecomb.http.dispatcher.edge.url.mappings.service3.path\", \"/a/b/c/.*\");\n    dispatcher.onConfigurationChangedEvent(ConfigurationChangedEvent.createIncremental(latest, new HashMap<>()));\n\n    items = dispatcher.getConfigurations();\n    Assertions.assertEquals(items.size(), 1);\n    item = items.get(\"service1\");\n    Assertions.assertEquals(item.getMicroserviceName(), \"serviceName\");\n    Assertions.assertEquals(item.getPrefixSegmentCount(), 2);\n    Assertions.assertEquals(item.getStringPattern(), \"/a/b/c/.*\");\n    Assertions.assertEquals(item.getVersionRule(), \"2.0.0+\");\n  }\n}\n"
  },
  {
    "path": "edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.edge.core;\n\nimport org.apache.servicecomb.common.rest.route.Utils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestUtils {\n  @Test\n  public void testUtils() {\n    Assertions.assertEquals(\"/a/b/c\", Utils.findActualPath(\"/a/b/c\", -1));\n    Assertions.assertEquals(\"/a/b/c\", Utils.findActualPath(\"/a/b/c\", 0));\n    Assertions.assertEquals(\"/b/c\", Utils.findActualPath(\"/a/b/c\", 1));\n    Assertions.assertEquals(\"/c\", Utils.findActualPath(\"/a/b/c\", 2));\n    Assertions.assertEquals(\"\", Utils.findActualPath(\"/a/b/c\", 3));\n    Assertions.assertEquals(\"\", Utils.findActualPath(\"/a/b/c\", 100));\n  }\n}\n"
  },
  {
    "path": "edge/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>edge</artifactId>\n  <name>Java Chassis::Edge</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>edge-core</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "etc/code-templates.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<templates>\n  <template autoinsert=\"false\" context=\"filecomment_context\" deleted=\"false\"\n    description=\"Comment for created Java files\" enabled=\"true\"\n    id=\"org.eclipse.jdt.ui.text.codetemplates.filecomment\" name=\"filecomment\">/*&#13;\n * Licensed to the Apache Software Foundation (ASF) under one or more&#13;\n * contributor license agreements.  See the NOTICE file distributed with&#13;\n * this work for additional information regarding copyright ownership.&#13;\n * The ASF licenses this file to You under the Apache License, Version 2.0&#13;\n * (the \"License\"); you may not use this file except in compliance with&#13;\n * the License.  You may obtain a copy of the License at&#13;\n *&#13;\n *     http://www.apache.org/licenses/LICENSE-2.0&#13;\n *&#13;\n * Unless required by applicable law or agreed to in writing, software&#13;\n * distributed under the License is distributed on an \"AS IS\" BASIS,&#13;\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#13;\n * See the License for the specific language governing permissions and&#13;\n * limitations under the License.&#13;\n */\n  </template>\n</templates>\n"
  },
  {
    "path": "etc/eclipse-java-google-style.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!--\n  ~ Creative Commons Google Style Guides by Google is licensed under CC BY 3.0 / changed right margin\n  ~ https://github.com/google/styleguide\n  ~\n  ~ CC BY 3.0 license\n  ~ https://creativecommons.org/licenses/by/3.0/\n  -->\n<profiles version=\"13\">\n<profile kind=\"CodeFormatterProfile\" name=\"GoogleStyle\" version=\"13\">\n<setting id=\"org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.disabling_tag\" value=\"@formatter:off\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments.count_dependent\" value=\"16|-1|16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_field\" value=\"1\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.use_on_off_tags\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_prefer_two_fragments\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_ellipsis\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_comment_inline_tags\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_local_variable_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_multiple_fields\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter\" value=\"1040\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type.count_dependent\" value=\"1585|-1|1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_conditional_expression\" value=\"80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_multiple_fields.count_dependent\" value=\"16|-1|16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_binary_operator\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_array_initializer\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_after_package\" value=\"1\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression.count_dependent\" value=\"16|4|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration.count_dependent\" value=\"16|4|48\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.continuation_indentation\" value=\"2\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration.count_dependent\" value=\"16|4|49\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation\" value=\"80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk\" value=\"1\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_binary_operator\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_package\" value=\"0\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.compiler.source\" value=\"1.8\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration.count_dependent\" value=\"16|4|48\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.format_line_comments\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.join_wrapped_lines\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_non_simple_local_variable_annotation\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.align_type_members_on_columns\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_member_type\" value=\"0\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_enum_constants.count_dependent\" value=\"16|5|48\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation\" value=\"80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_unary_operator\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.indent_parameter_description\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.lineSplit\" value=\"120\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation.count_dependent\" value=\"16|4|48\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration\" value=\"0\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indentation.size\" value=\"4\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.enabling_tag\" value=\"@formatter:on\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package\" value=\"1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_assignment\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"error\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.tabulation.char\" value=\"space\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_statements_compare_to_body\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_method\" value=\"1\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_non_simple_type_annotation\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_field_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_method_declaration\" value=\"0\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_switch\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"error\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment_new_line_at_start_of_html_paragraph\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_ellipsis\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_block\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comment_prefix\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_method_declaration\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.compact_else_if\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_non_simple_parameter_annotation\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method\" value=\"1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.indent_root_tags\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_enum_constant\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.tabulation.size\" value=\"2\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation.count_dependent\" value=\"16|5|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter.count_dependent\" value=\"1040|-1|1040\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package.count_dependent\" value=\"1585|-1|1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_empty_lines\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.force_if_else_statement_brace\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_block_in_case\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve\" value=\"3\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_non_simple_package_annotation\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation.count_dependent\" value=\"16|-1|16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type\" value=\"1585\"/>\n<setting id=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.7\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer\" value=\"2\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_unary_operator\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_new_anonymous_class\" value=\"20\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable.count_dependent\" value=\"1585|-1|1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent\" value=\"1585|-1|1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration.count_dependent\" value=\"16|5|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_binary_expression\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"enabled\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_label\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.format_javadoc_comments\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant\" value=\"81\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent\" value=\"16|-1|16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.line_length\" value=\"100\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_between_import_groups\" value=\"1\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body\" value=\"0\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_before_binary_operator\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations\" value=\"2\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration\" value=\"49\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_statements_compare_to_block\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.join_lines_in_comments\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_compact_if\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_imports\" value=\"0\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field\" value=\"1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.format_html\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer.count_dependent\" value=\"16|5|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.format_source_code\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.7\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_resources_in_try\" value=\"80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.format_header\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.format_block_comments\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_enum_constants\" value=\"49\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration.count_dependent\" value=\"16|4|48\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method.count_dependent\" value=\"1585|-1|1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_type_declaration\" value=\"end_of_line\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_binary_expression.count_dependent\" value=\"16|-1|16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.wrap_non_simple_member_annotation\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable\" value=\"1585\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent\" value=\"16|5|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments.count_dependent\" value=\"16|-1|16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression.count_dependent\" value=\"16|5|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration.count_dependent\" value=\"16|5|80\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.blank_lines_after_imports\" value=\"1\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header\" value=\"true\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for\" value=\"insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.alignment_for_for_statement\" value=\"16\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments\" value=\"do not insert\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column\" value=\"false\"/>\n<setting id=\"org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line\" value=\"false\"/>\n</profile>\n</profiles>\n"
  },
  {
    "path": "etc/intellij-java-google-style.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Creative Commons Google Style Guides by Google is licensed under CC BY 3.0 / changed right margin\n  ~ https://github.com/google/styleguide\n  ~\n  ~ CC BY 3.0 license\n  ~ https://creativecommons.org/licenses/by/3.0/\n  -->\n<code_scheme name=\"GoogleStyle\">\n  <option name=\"OTHER_INDENT_OPTIONS\">\n    <value>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n      <option name=\"USE_TAB_CHARACTER\" value=\"false\" />\n      <option name=\"SMART_TABS\" value=\"false\" />\n      <option name=\"LABEL_INDENT_SIZE\" value=\"0\" />\n      <option name=\"LABEL_INDENT_ABSOLUTE\" value=\"false\" />\n      <option name=\"USE_RELATIVE_INDENTS\" value=\"false\" />\n    </value>\n  </option>\n  <option name=\"INSERT_INNER_CLASS_IMPORTS\" value=\"true\" />\n  <option name=\"CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"999\" />\n  <option name=\"NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"999\" />\n  <option name=\"PACKAGES_TO_USE_IMPORT_ON_DEMAND\">\n    <value />\n  </option>\n  <option name=\"IMPORT_LAYOUT_TABLE\">\n    <value>\n      <package name=\"\" withSubpackages=\"true\" static=\"true\" />\n      <emptyLine />\n      <package name=\"java\" withSubpackages=\"true\" static=\"false\" />\n      <emptyLine />\n      <package name=\"javax\" withSubpackages=\"true\" static=\"false\" />\n      <emptyLine />\n      <package name=\"org\" withSubpackages=\"true\" static=\"false\" />\n      <emptyLine />\n      <package name=\"com\" withSubpackages=\"true\" static=\"false\" />\n      <emptyLine />\n      <package name=\"brave\" withSubpackages=\"true\" static=\"false\" />\n      <package name=\"io\" withSubpackages=\"true\" static=\"false\" />\n      <package name=\"\" withSubpackages=\"true\" static=\"false\" />\n    </value>\n  </option>\n  <option name=\"RIGHT_MARGIN\" value=\"120\" />\n  <option name=\"ENABLE_JAVADOC_FORMATTING\" value=\"false\" />\n  <option name=\"JD_ALIGN_PARAM_COMMENTS\" value=\"false\" />\n  <option name=\"JD_ALIGN_EXCEPTION_COMMENTS\" value=\"false\" />\n  <option name=\"JD_P_AT_EMPTY_LINES\" value=\"false\" />\n  <option name=\"JD_KEEP_EMPTY_PARAMETER\" value=\"false\" />\n  <option name=\"JD_KEEP_EMPTY_EXCEPTION\" value=\"false\" />\n  <option name=\"JD_KEEP_EMPTY_RETURN\" value=\"false\" />\n  <option name=\"KEEP_CONTROL_STATEMENT_IN_ONE_LINE\" value=\"false\" />\n  <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n  <option name=\"BLANK_LINES_AFTER_CLASS_HEADER\" value=\"1\" />\n  <option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\" />\n  <option name=\"ALIGN_MULTILINE_FOR\" value=\"false\" />\n  <option name=\"CALL_PARAMETERS_WRAP\" value=\"1\" />\n  <option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\" />\n  <option name=\"EXTENDS_LIST_WRAP\" value=\"1\" />\n  <option name=\"THROWS_KEYWORD_WRAP\" value=\"1\" />\n  <option name=\"METHOD_CALL_CHAIN_WRAP\" value=\"1\" />\n  <option name=\"BINARY_OPERATION_WRAP\" value=\"1\" />\n  <option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\" />\n  <option name=\"TERNARY_OPERATION_WRAP\" value=\"1\" />\n  <option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\" />\n  <option name=\"FOR_STATEMENT_WRAP\" value=\"1\" />\n  <option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\" />\n  <option name=\"WRAP_COMMENTS\" value=\"true\" />\n  <option name=\"IF_BRACE_FORCE\" value=\"3\" />\n  <option name=\"DOWHILE_BRACE_FORCE\" value=\"3\" />\n  <option name=\"WHILE_BRACE_FORCE\" value=\"3\" />\n  <option name=\"FOR_BRACE_FORCE\" value=\"3\" />\n  <AndroidXmlCodeStyleSettings>\n    <option name=\"USE_CUSTOM_SETTINGS\" value=\"true\" />\n    <option name=\"LAYOUT_SETTINGS\">\n      <value>\n        <option name=\"INSERT_BLANK_LINE_BEFORE_TAG\" value=\"false\" />\n      </value>\n    </option>\n  </AndroidXmlCodeStyleSettings>\n  <JSCodeStyleSettings>\n    <option name=\"INDENT_CHAINED_CALLS\" value=\"false\" />\n  </JSCodeStyleSettings>\n  <Python>\n    <option name=\"USE_CONTINUATION_INDENT_FOR_ARGUMENTS\" value=\"true\" />\n  </Python>\n  <TypeScriptCodeStyleSettings>\n    <option name=\"INDENT_CHAINED_CALLS\" value=\"false\" />\n  </TypeScriptCodeStyleSettings>\n  <XML>\n    <option name=\"XML_ALIGN_ATTRIBUTES\" value=\"false\" />\n    <option name=\"XML_LEGACY_SETTINGS_IMPORTED\" value=\"true\" />\n  </XML>\n  <codeStyleSettings language=\"CSS\">\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"ECMA Script Level 4\">\n    <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n    <option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\" />\n    <option name=\"ALIGN_MULTILINE_FOR\" value=\"false\" />\n    <option name=\"CALL_PARAMETERS_WRAP\" value=\"1\" />\n    <option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\" />\n    <option name=\"EXTENDS_LIST_WRAP\" value=\"1\" />\n    <option name=\"BINARY_OPERATION_WRAP\" value=\"1\" />\n    <option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"TERNARY_OPERATION_WRAP\" value=\"1\" />\n    <option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"FOR_STATEMENT_WRAP\" value=\"1\" />\n    <option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\" />\n    <option name=\"IF_BRACE_FORCE\" value=\"3\" />\n    <option name=\"DOWHILE_BRACE_FORCE\" value=\"3\" />\n    <option name=\"WHILE_BRACE_FORCE\" value=\"3\" />\n    <option name=\"FOR_BRACE_FORCE\" value=\"3\" />\n    <option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\" />\n  </codeStyleSettings>\n  <codeStyleSettings language=\"HTML\">\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"JAVA\">\n    <option name=\"RIGHT_MARGIN\" value=\"120\" />\n    <option name=\"KEEP_CONTROL_STATEMENT_IN_ONE_LINE\" value=\"false\" />\n    <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n    <option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"0\" />\n    <option name=\"BLANK_LINES_AROUND_FIELD\" value=\"1\" />\n    <option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\" />\n    <option name=\"ALIGN_MULTILINE_RESOURCES\" value=\"false\" />\n    <option name=\"ALIGN_MULTILINE_FOR\" value=\"false\" />\n    <option name=\"SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE\" value=\"true\" />\n    <option name=\"CALL_PARAMETERS_WRAP\" value=\"1\" />\n    <option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\" />\n    <option name=\"EXTENDS_LIST_WRAP\" value=\"1\" />\n    <option name=\"THROWS_LIST_WRAP\" value=\"1\" />\n    <option name=\"THROWS_KEYWORD_WRAP\" value=\"1\" />\n    <option name=\"METHOD_CALL_CHAIN_WRAP\" value=\"1\" />\n    <option name=\"BINARY_OPERATION_WRAP\" value=\"1\" />\n    <option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"TERNARY_OPERATION_WRAP\" value=\"1\" />\n    <option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"FOR_STATEMENT_WRAP\" value=\"1\" />\n    <option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\" />\n    <option name=\"WRAP_COMMENTS\" value=\"true\" />\n    <option name=\"IF_BRACE_FORCE\" value=\"3\" />\n    <option name=\"DOWHILE_BRACE_FORCE\" value=\"3\" />\n    <option name=\"WHILE_BRACE_FORCE\" value=\"3\" />\n    <option name=\"FOR_BRACE_FORCE\" value=\"3\" />\n    <option name=\"VARIABLE_ANNOTATION_WRAP\" value=\"2\" />\n    <option name=\"ENUM_CONSTANTS_WRAP\" value=\"2\" />\n    <option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\" />\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"JSON\">\n    <indentOptions>\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"JavaScript\">\n    <option name=\"RIGHT_MARGIN\" value=\"80\" />\n    <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n    <option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\" />\n    <option name=\"ALIGN_MULTILINE_FOR\" value=\"false\" />\n    <option name=\"CALL_PARAMETERS_WRAP\" value=\"1\" />\n    <option name=\"METHOD_PARAMETERS_WRAP\" value=\"1\" />\n    <option name=\"BINARY_OPERATION_WRAP\" value=\"1\" />\n    <option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"TERNARY_OPERATION_WRAP\" value=\"1\" />\n    <option name=\"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"FOR_STATEMENT_WRAP\" value=\"1\" />\n    <option name=\"ARRAY_INITIALIZER_WRAP\" value=\"1\" />\n    <option name=\"IF_BRACE_FORCE\" value=\"3\" />\n    <option name=\"DOWHILE_BRACE_FORCE\" value=\"3\" />\n    <option name=\"WHILE_BRACE_FORCE\" value=\"3\" />\n    <option name=\"FOR_BRACE_FORCE\" value=\"3\" />\n    <option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\" />\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"PROTO\">\n    <option name=\"RIGHT_MARGIN\" value=\"80\" />\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"2\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"protobuf\">\n    <option name=\"RIGHT_MARGIN\" value=\"80\" />\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"2\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"Python\">\n    <option name=\"KEEP_BLANK_LINES_IN_CODE\" value=\"1\" />\n    <option name=\"RIGHT_MARGIN\" value=\"80\" />\n    <option name=\"ALIGN_MULTILINE_PARAMETERS\" value=\"false\" />\n    <option name=\"PARENT_SETTINGS_INSTALLED\" value=\"true\" />\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"SASS\">\n    <indentOptions>\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"SCSS\">\n    <indentOptions>\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"TypeScript\">\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n  </codeStyleSettings>\n  <codeStyleSettings language=\"XML\">\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"2\" />\n      <option name=\"TAB_SIZE\" value=\"2\" />\n    </indentOptions>\n    <arrangement>\n      <rules>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>xmlns:android</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>^$</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>xmlns:.*</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>^$</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:id</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>style</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>^$</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>^$</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:.*Style</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_width</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_height</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_weight</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_margin</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_marginTop</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_marginBottom</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_marginStart</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_marginEnd</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_marginLeft</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_marginRight</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:layout_.*</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:padding</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:paddingTop</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:paddingBottom</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:paddingStart</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:paddingEnd</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:paddingLeft</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*:paddingRight</NAME>\n                <XML_ATTRIBUTE />\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*</NAME>\n                <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*</NAME>\n                <XML_NAMESPACE>http://schemas.android.com/apk/res-auto</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*</NAME>\n                <XML_NAMESPACE>http://schemas.android.com/tools</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n        <section>\n          <rule>\n            <match>\n              <AND>\n                <NAME>.*</NAME>\n                <XML_NAMESPACE>.*</XML_NAMESPACE>\n              </AND>\n            </match>\n            <order>BY_NAME</order>\n          </rule>\n        </section>\n      </rules>\n    </arrangement>\n  </codeStyleSettings>\n  <Objective-C>\n    <option name=\"INDENT_NAMESPACE_MEMBERS\" value=\"0\" />\n    <option name=\"INDENT_C_STRUCT_MEMBERS\" value=\"2\" />\n    <option name=\"INDENT_CLASS_MEMBERS\" value=\"2\" />\n    <option name=\"INDENT_VISIBILITY_KEYWORDS\" value=\"1\" />\n    <option name=\"INDENT_INSIDE_CODE_BLOCK\" value=\"2\" />\n    <option name=\"KEEP_STRUCTURES_IN_ONE_LINE\" value=\"true\" />\n    <option name=\"FUNCTION_PARAMETERS_WRAP\" value=\"5\" />\n    <option name=\"FUNCTION_CALL_ARGUMENTS_WRAP\" value=\"5\" />\n    <option name=\"TEMPLATE_CALL_ARGUMENTS_WRAP\" value=\"5\" />\n    <option name=\"TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE\" value=\"true\" />\n    <option name=\"ALIGN_INIT_LIST_IN_COLUMNS\" value=\"false\" />\n    <option name=\"SPACE_BEFORE_SUPERCLASS_COLON\" value=\"false\" />\n  </Objective-C>\n  <Objective-C-extensions>\n    <option name=\"GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES\" value=\"ASK\" />\n    <option name=\"RELEASE_STYLE\" value=\"IVAR\" />\n    <option name=\"TYPE_QUALIFIERS_PLACEMENT\" value=\"BEFORE\" />\n    <file>\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Import\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Macro\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Typedef\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Enum\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Constant\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Global\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Struct\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"FunctionPredecl\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Function\" />\n    </file>\n    <class>\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Property\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"Synthesize\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InitMethod\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"StaticMethod\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"InstanceMethod\" />\n      <option name=\"com.jetbrains.cidr.lang.util.OCDeclarationKind\" value=\"DeallocMethod\" />\n    </class>\n    <extensions>\n      <pair source=\"cc\" header=\"h\" />\n      <pair source=\"c\" header=\"h\" />\n    </extensions>\n  </Objective-C-extensions>\n  <codeStyleSettings language=\"ObjectiveC\">\n    <option name=\"RIGHT_MARGIN\" value=\"80\" />\n    <option name=\"KEEP_BLANK_LINES_BEFORE_RBRACE\" value=\"1\" />\n    <option name=\"BLANK_LINES_BEFORE_IMPORTS\" value=\"0\" />\n    <option name=\"BLANK_LINES_AFTER_IMPORTS\" value=\"0\" />\n    <option name=\"BLANK_LINES_AROUND_CLASS\" value=\"0\" />\n    <option name=\"BLANK_LINES_AROUND_METHOD\" value=\"0\" />\n    <option name=\"BLANK_LINES_AROUND_METHOD_IN_INTERFACE\" value=\"0\" />\n    <option name=\"ALIGN_MULTILINE_BINARY_OPERATION\" value=\"false\" />\n    <option name=\"BINARY_OPERATION_SIGN_ON_NEXT_LINE\" value=\"true\" />\n    <option name=\"FOR_STATEMENT_WRAP\" value=\"1\" />\n    <option name=\"ASSIGNMENT_WRAP\" value=\"1\" />\n    <indentOptions>\n      <option name=\"INDENT_SIZE\" value=\"2\" />\n      <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n    </indentOptions>\n  </codeStyleSettings>\n</code_scheme>\n"
  },
  {
    "path": "foundations/foundation-common/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n    <artifactId>foundations</artifactId>\n  </parent>\n  <artifactId>foundation-common</artifactId>\n  <name>Java Chassis::Foundations::Common</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>com.sun.activation</groupId>\n      <artifactId>jakarta.activation</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.dataformat</groupId>\n      <artifactId>jackson-dataformat-xml</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-databind</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-annotations</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-context</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>slf4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.httpcomponents</groupId>\n      <artifactId>httpclient</artifactId>\n      <exclusions>\n        <exclusion>\n          <artifactId>commons-logging</artifactId>\n          <groupId>commons-logging</groupId>\n        </exclusion>\n      </exclusions>\n    </dependency>\n    <dependency>\n      <groupId>jakarta.ws.rs</groupId>\n      <artifactId>jakarta.ws.rs-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>commons-io</groupId>\n      <artifactId>commons-io</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>failureaccess</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>jakarta.servlet</groupId>\n      <artifactId>jakarta.servlet-api</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-spi</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.datatype</groupId>\n      <artifactId>jackson-datatype-jsr310</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/Cipher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.auth;\n\npublic interface Cipher {\n  String name();\n\n  char[] decrypt(char[] encrypted);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/DefaultCipher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.auth;\n\npublic final class DefaultCipher implements Cipher {\n  public static final String CIPHER_NAME = \"default\";\n\n  private static final DefaultCipher INSTANCE = new DefaultCipher();\n\n  public static DefaultCipher getInstance() {\n    return INSTANCE;\n  }\n\n  private DefaultCipher() {\n  }\n\n  @Override\n  public String name() {\n    return CIPHER_NAME;\n  }\n\n  @Override\n  public char[] decrypt(char[] encrypted) {\n    return encrypted;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/FoundationCommonAuthConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.auth;\n\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class FoundationCommonAuthConfiguration {\n  public ShaAKSKCipher scbShaAKSKCipher() {\n    return new ShaAKSKCipher();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/auth/ShaAKSKCipher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.auth;\n\npublic class ShaAKSKCipher implements Cipher {\n  public static final String CIPHER_NAME = \"ShaAKSKCipher\";\n\n  @Override\n  public String name() {\n    return CIPHER_NAME;\n  }\n\n  @Override\n  public char[] decrypt(char[] encrypted) {\n    return encrypted;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/AbstractObjectManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common;\n\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic abstract class AbstractObjectManager<KEY_OWNER, KEY, VALUE> {\n  protected Map<KEY, VALUE> objMap = new ConcurrentHashMap<>();\n\n  protected final Object lockObj = new Object();\n\n  public VALUE getOrCreate(KEY_OWNER keyOwner) {\n    KEY key = getKey(keyOwner);\n    VALUE value = objMap.get(key);\n    if (value == null) {\n      synchronized (lockObj) {\n        value = objMap.get(key);\n        if (value == null) {\n          value = create(keyOwner);\n          if (value == null) {\n            // 创建失败，下次重新创建\n            return null;\n          }\n          objMap.put(key, value);\n        }\n      }\n    }\n\n    return value;\n  }\n\n  public VALUE findByKey(KEY key) {\n    return objMap.get(key);\n  }\n\n  public VALUE findByContainer(KEY_OWNER keyOwner) {\n    KEY key = getKey(keyOwner);\n    return objMap.get(key);\n  }\n\n  public Set<KEY> keys() {\n    return objMap.keySet();\n  }\n\n  public Collection<VALUE> values() {\n    return objMap.values();\n  }\n\n  protected abstract KEY getKey(KEY_OWNER keyOwner);\n\n  /**\n   * 只会在锁的保护下执行\n   */\n  protected abstract VALUE create(KEY_OWNER keyOwner);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/CommonThread.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common;\n\npublic class CommonThread extends Thread {\n  protected volatile boolean shutdown;\n\n  public CommonThread() {\n    super();\n  }\n\n  public CommonThread(String name, long stackSize) {\n    super(null, null, name, stackSize);\n  }\n\n  public boolean isShutdown() {\n    return shutdown;\n  }\n\n  public boolean isRunning() {\n    return !shutdown;\n  }\n\n  public void shutdown() {\n    shutdown = true;\n    interrupt();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/DynamicObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.fasterxml.jackson.annotation.JsonAnyGetter;\nimport com.fasterxml.jackson.annotation.JsonAnySetter;\n\npublic class DynamicObject {\n  protected Map<String, Object> dynamic = new HashMap<>();\n\n  @JsonAnyGetter\n  public Map<String, Object> getDynamic() {\n    return dynamic;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getDynamic(String key) {\n    return (T) dynamic.get(key);\n  }\n\n  public void setDynamic(Map<String, Object> dynamic) {\n    this.dynamic = dynamic;\n  }\n\n  @JsonAnySetter\n  public DynamicObject putDynamic(String key, Object value) {\n    this.dynamic.put(key, value);\n    return this;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/Holder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common;\n\n// do not use javax.xml.ws.Holder, use this one. Because JDK 11 above do not have jakarta.ws.Holder\npublic final class Holder<T> {\n\n  /**\n   * The value contained in the holder.\n   */\n  public T value;\n\n  /**\n   * Creates a new holder with a <code>null</code> value.\n   */\n  public Holder() {\n  }\n\n  /**\n   * Create a new holder with the specified value.\n   *\n   * @param value The value to be stored in the holder.\n   */\n  public Holder(T value) {\n    this.value = value;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/LegacyPropertyFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common;\n\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n * Provider a convenient way to get property value in static context.\n *\n * NOTE: This way is not commented and only for legacy code without too much refactoring.\n *   And make sure to use this class when spring bean context is already initialized.\n */\npublic class LegacyPropertyFactory {\n  private static Environment environment;\n\n  public LegacyPropertyFactory(Environment environment) {\n    LegacyPropertyFactory.environment = environment;\n  }\n\n  @VisibleForTesting\n  public static void setEnvironment(Environment environment) {\n    LegacyPropertyFactory.environment = environment;\n  }\n\n  public static <T> T getProperty(String key, Class<T> targetType) {\n    return environment.getProperty(key, targetType);\n  }\n\n  public static <T> T getProperty(String key, Class<T> targetType, T defaultValue) {\n    return environment.getProperty(key, targetType, defaultValue);\n  }\n\n  public static boolean getBooleanProperty(String key, boolean defaultValue) {\n    return environment.getProperty(key, boolean.class, defaultValue);\n  }\n\n  public static int getIntProperty(String key, int defaultValue) {\n    return environment.getProperty(key, int.class, defaultValue);\n  }\n\n  public static long getLongProperty(String key, long defaultValue) {\n    return environment.getProperty(key, long.class, defaultValue);\n  }\n\n  public static String getStringProperty(String key) {\n    return environment.getProperty(key);\n  }\n\n  public static String getStringProperty(String key, String defaultValue) {\n    return environment.getProperty(key, defaultValue);\n  }\n\n  public static Environment getEnvironment() {\n    return environment;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/NamedThreadFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common;\n\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * 已命名线程工厂.\n * 获取新的名字有固定前缀的线程工厂.\n */\npublic class NamedThreadFactory implements ThreadFactory {\n\n  private final AtomicInteger threadNumber = new AtomicInteger();\n\n  private String prefix;\n\n  public NamedThreadFactory() {\n    this(\"Thread\");\n  }\n\n  public NamedThreadFactory(String prefix) {\n    this.prefix = prefix;\n  }\n\n  /**\n   * 获取新的名字以prefix为前缀的线程\n   */\n  @Override\n  public Thread newThread(Runnable r) {\n    Thread thread =  new Thread(r, prefix + \"-\" + threadNumber.getAndIncrement());\n    thread.setDaemon(true);\n    return thread;\n  }\n\n  public String getPrefix() {\n    return prefix;\n  }\n\n  public void setPrefix(String prefix) {\n    this.prefix = prefix;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/ParameterizedTypeUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.Objects;\nimport java.util.StringJoiner;\n\n/**\n * Utility class for creating ParameterizedType.\n */\npublic class ParameterizedTypeUtil implements ParameterizedType {\n  private final Type[] actualTypeArguments;\n\n  private final Class<?> rawType;\n\n  private ParameterizedTypeUtil(Class<?> rawType, Type[] actualTypeArguments) {\n    this.actualTypeArguments = actualTypeArguments;\n    this.rawType = rawType;\n  }\n\n  public static ParameterizedType make(Class<?> rawType, Type... actualTypeArguments) {\n    return new ParameterizedTypeUtil(rawType, actualTypeArguments);\n  }\n\n  @Override\n  public Type[] getActualTypeArguments() {\n    return this.actualTypeArguments;\n  }\n\n  @Override\n  public Type getRawType() {\n    return rawType;\n  }\n\n  @Override\n  public Type getOwnerType() {\n    return null;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o instanceof ParameterizedType that) {\n\n      if (this == that) {\n        return true;\n      }\n\n      Type thatRawType = that.getRawType();\n\n      return Objects.equals(rawType, thatRawType) &&\n          Arrays.equals(actualTypeArguments, that.getActualTypeArguments());\n    } else {\n      return false;\n    }\n  }\n\n  @Override\n  public int hashCode() {\n    return Arrays.hashCode(actualTypeArguments) ^\n        Objects.hashCode(rawType);\n  }\n\n  public String toString() {\n    StringBuilder sb = new StringBuilder();\n\n    sb.append(rawType.getName());\n\n    if (actualTypeArguments != null) {\n      StringJoiner sj = new StringJoiner(\", \", \"<\", \">\");\n      sj.setEmptyValue(\"\");\n      for (Type t : actualTypeArguments) {\n        sj.add(t.getTypeName());\n      }\n      sb.append(sj);\n    }\n\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/RegisterManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common;\n\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class RegisterManager<KEY, VALUE> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RegisterManager.class);\n\n  private final String name;\n\n  private String registerErrorFmt = \"Not allow register repeat data, name=%s, key=%s\";\n\n  private final Map<KEY, VALUE> objMap = new ConcurrentHashMap<>();\n\n  private final Object lockObj = new Object();\n\n  protected Map<KEY, VALUE> getObjMap() {\n    return objMap;\n  }\n\n  public RegisterManager(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public String getRegisterErrorFmt() {\n    return registerErrorFmt;\n  }\n\n  public void setRegisterErrorFmt(String registerErrorFmt) {\n    this.registerErrorFmt = registerErrorFmt;\n  }\n\n  public void register(KEY key, VALUE value) {\n    synchronized (lockObj) {\n      if (objMap.get(key) != null) {\n        // 不允许重复注册\n        String msg = String.format(registerErrorFmt, name, key);\n        LOGGER.error(msg);\n\n        // 禁止启动\n        throw new Error(msg);\n      }\n      objMap.put(key, value);\n    }\n  }\n\n  public VALUE findValue(KEY key) {\n    return objMap.get(key);\n  }\n\n  public VALUE ensureFindValue(KEY key) {\n    VALUE value = objMap.get(key);\n    if (value == null) {\n      String msg = String.format(\"Can not find value, name=%s, key=%s\", name, key);\n      throw new Error(msg);\n    }\n\n    return value;\n  }\n\n  public Collection<KEY> keys() {\n    return objMap.keySet();\n  }\n\n  public Collection<VALUE> values() {\n    return objMap.values();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/VendorExtensions.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common;\n\nimport java.util.Map;\nimport java.util.function.Function;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\npublic class VendorExtensions {\n  private final Map<Object, Object> store = new ConcurrentHashMapEx<>();\n\n  public Map<Object, Object> getStore() {\n    return store;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <V> V get(Object key) {\n    return (V) store.get(key);\n  }\n\n  public void put(Object key, Object value) {\n    store.put(key, value);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <V> V computeIfAbsent(Object key, Function<Object, Object> mappingFunction) {\n    return (V) store.computeIfAbsent(key, mappingFunction);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/Version.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common;\n\nimport java.util.Objects;\n\nimport org.apache.commons.lang3.ArrayUtils;\n\n// short version is enough\npublic class Version implements Comparable<Version> {\n  private static final String[] ZERO = new String[] {\"0\", \"0\", \"0\", \"0\"};\n\n  private final short major;\n\n  private final short minor;\n\n  private final short patch;\n\n  private final short build;\n\n  private final String version;\n\n  private final long numberVersion;\n\n  // 1\n  // 1.0\n  // 1.0.0\n  // 1.0.0.0\n  public Version(String version) {\n    Objects.requireNonNull(version);\n\n    String[] versions = version.split(\"\\\\.\", -1);\n    if (versions.length > 4) {\n      throw new IllegalStateException(String.format(\"Invalid version \\\"%s\\\".\", version));\n    }\n\n    if (versions.length < 4) {\n      versions = ArrayUtils.addAll(versions, ZERO);\n    }\n    this.major = parseNumber(\"major\", version, versions[0]);\n    this.minor = parseNumber(\"minor\", version, versions[1]);\n    this.patch = parseNumber(\"patch\", version, versions[2]);\n    this.build = parseNumber(\"build\", version, versions[3]);\n\n    this.version = combineStringVersion();\n    this.numberVersion = combineVersion();\n  }\n\n  private short parseNumber(String name, String allVersion, String version) {\n    short value = 0;\n    try {\n      value = Short.parseShort(version);\n    } catch (NumberFormatException e) {\n      throw new IllegalStateException(\n          String.format(\"Invalid %s \\\"%s\\\", version \\\"%s\\\".\", name, version, allVersion), e);\n    }\n\n    if (value < 0) {\n      throw new IllegalStateException(\n          String.format(\"%s \\\"%s\\\" can not be negative, version \\\"%s\\\".\", name, version, allVersion));\n    }\n\n    return value;\n  }\n\n  public Version(short major, short minor, short patch, short build) {\n    this.major = major;\n    this.minor = minor;\n    this.patch = patch;\n    this.build = build;\n    this.version = combineStringVersion();\n    this.numberVersion = combineVersion();\n  }\n\n  private String combineStringVersion() {\n    return major + \".\" + minor + \".\" + patch + \".\" + build;\n  }\n\n  // 1.0.0 equals 1.0.0.0\n  private long combineVersion() {\n    return (long) major << 48 | (long) minor << 32 | (long) patch << 16 | (long) build;\n  }\n\n  public short getMajor() {\n    return major;\n  }\n\n  public short getMinor() {\n    return minor;\n  }\n\n  public short getPatch() {\n    return patch;\n  }\n\n  public short getBuild() {\n    return build;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  @Override\n  public String toString() {\n    return version;\n  }\n\n  @Override\n  public int hashCode() {\n    return version.hashCode();\n  }\n\n  @Override\n  public boolean equals(Object other) {\n    if (other == this) {\n      return true;\n    }\n\n    if (!(other instanceof Version)) {\n      return false;\n    }\n\n    return numberVersion == ((Version) other).numberVersion;\n  }\n\n  @Override\n  public int compareTo(Version other) {\n    return Long.compare(numberVersion, other.numberVersion);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DescriptiveRunnable.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.base;\n\npublic interface DescriptiveRunnable extends Runnable {\n\n  String description();\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnum.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.base;\n\nimport java.util.Objects;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.jackson.annotation.JsonValue;\n\npublic abstract class DynamicEnum<T> {\n  private final T value;\n\n  @JsonIgnore\n  private boolean dynamic = false;\n\n  public DynamicEnum(T value) {\n    this.value = value;\n  }\n\n  @JsonValue\n  public T getValue() {\n    return value;\n  }\n\n  @JsonIgnore\n  public boolean isStatic() {\n    return !dynamic;\n  }\n\n  public boolean isDynamic() {\n    return dynamic;\n  }\n\n  public DynamicEnum<T> setDynamic(boolean dynamic) {\n    this.dynamic = dynamic;\n    return this;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }\n    DynamicEnum<?> that = (DynamicEnum<?>) o;\n    return Objects.equals(value, that.value);\n  }\n\n  @Override\n  public int hashCode() {\n    return Objects.hash(value);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnumCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.base;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.ParameterizedType;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class DynamicEnumCache<T extends DynamicEnum<?>> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DynamicEnumCache.class);\n\n  private final Class<T> cls;\n\n  private final Map<Object, T> values;\n\n  /**\n   *\n   * @param cls\n   */\n  private final Constructor<T> constructor;\n\n  public DynamicEnumCache(Class<T> cls) {\n    try {\n      this.cls = cls;\n      this.constructor = initFactory();\n      this.values = initValues();\n    } catch (Exception e) {\n      throw new IllegalStateException(\"failed to init dynamic enum, class=\" + cls.getName(), e);\n    }\n  }\n\n  private Constructor<T> initFactory() throws NoSuchMethodException {\n    ParameterizedType superClass = (ParameterizedType) cls.getGenericSuperclass();\n    Class<?> argument = (Class<?>) superClass.getActualTypeArguments()[0];\n    return cls.getConstructor(argument);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private Map<Object, T> initValues() {\n    Map<Object, T> values = new LinkedHashMap<>();\n    EnumUtils.findEnumFields(cls)\n        .map(field -> (T) EnumUtils.readEnum(field))\n        .forEach(oneEnum -> values.put(oneEnum.getValue(), oneEnum));\n    return Collections.unmodifiableMap(values);\n  }\n\n  public T fromValue(Object value) {\n    if (value == null) {\n      return null;\n    }\n\n    T instance = values.get(value);\n    if (instance != null) {\n      return instance;\n    }\n\n    try {\n      // do not cache unknown value to avoid attach\n      // if need to cache unknown value, should avoid cache too many values\n      instance = constructor.newInstance(value);\n      instance.setDynamic(true);\n      return instance;\n    } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {\n      LOGGER.error(\"failed to create enum, class={}, value={}.\", cls.getName(), value);\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/EnumUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.base;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.stream.Stream;\n\npublic interface EnumUtils {\n  @SuppressWarnings(\"unchecked\")\n  static <T> T readEnum(Field enumField) {\n    try {\n      return (T) enumField.get(null);\n    } catch (IllegalAccessException e) {\n      throw new IllegalStateException(\"failed to read enum, field=\" + enumField, e);\n    }\n  }\n\n  static boolean isEnumField(Class<?> cls, Field field) {\n    return Modifier.isStatic(field.getModifiers()) && cls.equals(field.getType());\n  }\n\n  static Stream<Field> findEnumFields(Class<?> cls) {\n    return Arrays.stream(cls.getFields())\n        .filter(field -> isEnumField(cls, field));\n  }\n\n  static boolean isDynamicEnum(Type cls) {\n    return cls instanceof DynamicEnum;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/ServiceCombConstants.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.base;\n\npublic interface ServiceCombConstants {\n  String CONFIG_TRACING_COLLECTOR_ADDRESS = \"servicecomb.tracing.collector.address\";\n\n  String CONFIG_TRACING_COLLECTOR_API_V1 = \"v1\";\n\n  String CONFIG_TRACING_COLLECTOR_API_V2 = \"v2\";\n\n  String CONFIG_TRACING_COLLECTOR_API_VERSION = \"servicecomb.tracing.collector.apiVersion\";\n\n  String CONFIG_TRACING_COLLECTOR_PATH = \"/api/{0}/spans\";\n\n  String DEFAULT_TRACING_COLLECTOR_ADDRESS = \"http://127.0.0.1:9411\";\n\n  String CONFIG_KEY_SPLITTER = \"_\";\n\n  String CONFIG_FRAMEWORK_DEFAULT_NAME = \"servicecomb-java-chassis\";\n\n  String CONFIG_DEFAULT_REGISTER_BY = \"SDK\";\n\n  String DEVELOPMENT_SERVICECOMB_ENV = \"development\";\n\n  String SERVICE_MAPPING = \"SERVICE_MAPPING\";\n\n  String VERSION_MAPPING = \"VERSION_MAPPING\";\n\n  String APP_MAPPING = \"APP_MAPPING\";\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/cache/VersionedCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.cache;\n\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n@SuppressWarnings(\"unchecked\")\npublic class VersionedCache {\n  protected static final AtomicInteger VERSION = new AtomicInteger();\n\n  interface IsEmpty {\n    boolean isEmpty();\n  }\n\n  protected volatile int cacheVersion;\n\n  // an optional name\n  protected String name;\n\n  protected Object data;\n\n  protected IsEmpty isEmpty = this::isCommonEmpty;\n\n  private boolean isCommonEmpty() {\n    return data == null;\n  }\n\n  private boolean isMapEmpty() {\n    return ((Map<?, ?>) data).isEmpty();\n  }\n\n  private boolean isCollectionEmpty() {\n    return ((Collection<?>) data).isEmpty();\n  }\n\n  private boolean isArrayEmpty() {\n    return ((Object[]) data).length == 0;\n  }\n\n  public int cacheVersion() {\n    return cacheVersion;\n  }\n\n  public <T extends VersionedCache> T autoCacheVersion() {\n    this.cacheVersion = VERSION.incrementAndGet();\n    return (T) this;\n  }\n\n  public <T extends VersionedCache> T cacheVersion(int cacheVersion) {\n    this.cacheVersion = cacheVersion;\n    return (T) this;\n  }\n\n  public String name() {\n    return name;\n  }\n\n  public <T extends VersionedCache> T name(String name) {\n    this.name = name;\n    return (T) this;\n  }\n\n  public <T extends VersionedCache> T subName(VersionedCache parent, String subName) {\n    Objects.requireNonNull(parent.name());\n    Objects.requireNonNull(subName);\n\n    this.name = parent.name + \"/\" + subName;\n    return (T) this;\n  }\n\n\n  public <T> T data() {\n    return (T) data;\n  }\n\n  // caller maker sure data is a map\n  public <K, V> Map<K, V> mapData() {\n    return (Map<K, V>) data;\n  }\n\n  // caller maker sure data is a collection\n  public <T> Collection<T> collectionData() {\n    return (Collection<T>) data;\n  }\n\n  //caller maker sure data is a array\n  public <T> T[] arrayData() {\n    return (T[]) data;\n  }\n\n  public <T extends VersionedCache> T data(Object data) {\n    this.data = data;\n\n    if (data == null) {\n      isEmpty = this::isCommonEmpty;\n    } else if (Map.class.isInstance(data)) {\n      isEmpty = this::isMapEmpty;\n    } else if (Collection.class.isInstance(data)) {\n      isEmpty = this::isCollectionEmpty;\n    } else if (data.getClass().isArray()) {\n      isEmpty = this::isArrayEmpty;\n    } else {\n      isEmpty = this::isCommonEmpty;\n    }\n    return (T) this;\n  }\n\n  // only newData is new than this, means expired.\n  public boolean isExpired(VersionedCache newCache) {\n    // cacheVersion maybe overflow, so must use decrease to determine\n    return newCache.cacheVersion - cacheVersion > 0;\n  }\n\n  public boolean isSameVersion(VersionedCache newCache) {\n    return newCache.cacheVersion == cacheVersion;\n  }\n\n  public boolean isEmpty() {\n    return isEmpty.isEmpty();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/concurrency/SuppressedRunnableWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.concurrency;\n\nimport java.util.function.Consumer;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * A wrapper for {@link Runnable}.\n * All the exceptions thrown from {@link Runnable#run()} are caught and handled.\n */\npublic class SuppressedRunnableWrapper implements Runnable {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(SuppressedRunnableWrapper.class);\n\n  private final Runnable target;\n\n  private final Consumer<Throwable> errorHandler;\n\n  public SuppressedRunnableWrapper(Runnable runnable) {\n    this(runnable, null);\n  }\n\n  public SuppressedRunnableWrapper(Runnable runnable, Consumer<Throwable> errorHandler) {\n    this.target = runnable;\n    this.errorHandler = errorHandler;\n  }\n\n  @Override\n  public void run() {\n    try {\n      target.run();\n    } catch (Throwable e) {\n      handleError(e);\n    }\n  }\n\n  private void handleError(Throwable e) {\n    if (null == errorHandler) {\n      LOGGER.error(\"task {} execute error!\", target, e);\n      return;\n    }\n    errorHandler.accept(e);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/concurrent/ConcurrentHashMapEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.concurrent;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.function.Function;\n\npublic class ConcurrentHashMapEx<K, V> extends ConcurrentHashMap<K, V> {\n  private static final long serialVersionUID = -7753722464102569902L;\n\n  public ConcurrentHashMapEx() {\n    super();\n  }\n\n  public ConcurrentHashMapEx(int initialCapacity) {\n    super(initialCapacity);\n  }\n\n  public ConcurrentHashMapEx(Map<? extends K, ? extends V> m) {\n    super(m);\n  }\n\n  public ConcurrentHashMapEx(int initialCapacity, float loadFactor) {\n    super(initialCapacity, loadFactor);\n  }\n\n  public ConcurrentHashMapEx(int initialCapacity,\n      float loadFactor, int concurrencyLevel) {\n    super(initialCapacity, loadFactor, concurrencyLevel);\n  }\n\n  // ConcurrentHashMap.computeIfAbsent always do \"synchronized\" operation\n  // so we wrap it to improve performance\n  @Override\n  public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {\n    V value = get(key);\n    if (value != null) {\n      return value;\n    }\n\n    return super.computeIfAbsent(key, mappingFunction);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/config/ConfigLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config;\n\npublic interface ConfigLoader {\n\n  <T> T load() throws Exception;\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/config/PaaSResourceUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Properties;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.config.impl.PropertiesLoader;\nimport org.springframework.core.io.Resource;\nimport org.springframework.core.io.support.PathMatchingResourcePatternResolver;\nimport org.springframework.core.io.support.ResourcePatternResolver;\n\n\npublic class PaaSResourceUtils extends org.springframework.util.ResourceUtils {\n  public static final String PROPERTIES_SUFFIX = \".properties\";\n\n  private static final ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();\n\n  /**\n   * 失败，则返回空数组\n   */\n  public static Resource[] getResources(String locationPattern) {\n    try {\n      return resourcePatternResolver.getResources(locationPattern);\n    } catch (IOException e) {\n      return new Resource[0];\n    }\n  }\n\n  /**\n   * 失败，则返回空列表\n   */\n  public static List<Resource> getResources(String... locationPatterns) {\n    List<Resource> ret = new ArrayList<>();\n    for (String locationPattern : locationPatterns) {\n      Resource[] resArr = getResources(locationPattern);\n      ret.addAll(Arrays.asList(resArr));\n    }\n\n    return ret;\n  }\n\n  /**\n   * 文件同名时，jar的优先级比较低\n   * jar: xxx.xml\n   * jar: xxx.model.xml\n   * file:xxx.xml\n   * 调用者保证，所有res的后缀都是suffix\n   * file文件应该只有一个，因为放在目录中的配置文件，应该是最终的部署定制文件\n   * 此时，还分多个，是不合适的\n   */\n  public static void sortResources(List<Resource> resList, String suffix) {\n    resList.sort((o1, o2) -> {\n      try {\n        // jar的优先级比较低\n        if (isJarURL(o1.getURL()) && isFileURL(o2.getURL())) {\n          return -1;\n        }\n\n        // 干掉后缀，再排序\n        String name1 = o1.getFilename();\n        String name2 = o2.getFilename();\n\n        //Resource.getFilename接口会返回null，当路径的文件名不存在时\n        //配置文件一定存在，并且Resource有合法的文件名，name1和name2不可能为空，\n        //这里做判断是为了处理CodeDEX报的null引用\n        if (StringUtils.isEmpty(name1) || StringUtils.isEmpty(name2)) {\n          throw new IOException(\n              String.format(\"Resource %s or %s is not a file\", o1.getURI(), o2.getURI()));\n        }\n\n        name1 = name1.substring(0, name1.length() - suffix.length());\n        name2 = name2.substring(0, name2.length() - suffix.length());\n\n        return name1.compareTo(name2);\n      } catch (IOException e) {\n        throw new RuntimeException(e);\n      }\n    });\n  }\n\n  public static void sortProperties(List<Resource> resList) {\n    sortResources(resList, PROPERTIES_SUFFIX);\n  }\n\n  public static List<Resource> getSortedResources(String locationPattern, String suffix) {\n    if (StringUtils.isEmpty(locationPattern)) {\n      throw new RuntimeException(\"Resource path must not be null or empty\");\n    }\n\n    if (!locationPattern.endsWith(suffix)) {\n      throw new RuntimeException(\"Resource path must ends with \" + suffix);\n    }\n\n    String prefix = locationPattern.substring(0, locationPattern.length() - suffix.length());\n\n    List<Resource> resList = PaaSResourceUtils.getResources(locationPattern, prefix + \".*\" + suffix);\n    sortResources(resList, suffix);\n    return resList;\n  }\n\n  public static List<Resource> getSortedProperties(String locationPattern) {\n    return getSortedResources(locationPattern, PROPERTIES_SUFFIX);\n  }\n\n  public static Properties loadMergedProperties(String locationPattern) throws Exception {\n    PropertiesLoader loader = new PropertiesLoader(Arrays.asList(locationPattern));\n    return loader.load();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/config/impl/AbstractLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config.impl;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.config.ConfigLoader;\n\npublic abstract class AbstractLoader implements ConfigLoader {\n  protected List<String> locationPatternList;\n\n  public AbstractLoader(List<String> locationPatternList) {\n    this.locationPatternList = locationPatternList;\n  }\n\n  public List<String> getLocationPatternList() {\n    return locationPatternList;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/config/impl/PaaSPropertiesLoaderUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config.impl;\n\nimport java.io.IOException;\nimport java.util.List;\nimport java.util.Properties;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.config.PaaSResourceUtils;\nimport org.springframework.core.io.Resource;\n\n\npublic class PaaSPropertiesLoaderUtils extends org.springframework.core.io.support.PropertiesLoaderUtils {\n\n  /**\n   * 使用内置规则\n   *  输入：/a/b/abc.properties\n   *  实际：\n   *  1./a/b/abc.properties\n   *   2./a/b/abc.[ext].properties\n   * @param locationPattern locationPattern\n   * @return Properties\n   * @throws IOException Exception\n   */\n  public static Properties loadMergedProperties(String locationPattern) throws IOException {\n    Properties prop = new Properties();\n    return fillMergedProperties(prop, locationPattern);\n  }\n\n  public static Properties fillMergedProperties(Properties prop, String locationPattern) throws IOException {\n    if (StringUtils.isEmpty(locationPattern)) {\n      throw new RuntimeException(\"Resource path must not be null or empty\");\n    }\n\n    String suffix = PaaSResourceUtils.PROPERTIES_SUFFIX;\n    if (!locationPattern.endsWith(suffix)) {\n      throw new RuntimeException(\"Resource path must ends with \" + suffix);\n    }\n\n    String prefix = locationPattern.substring(0, locationPattern.length() - suffix.length());\n\n    List<Resource> resList = PaaSResourceUtils.getResources(locationPattern, prefix + \".*\" + suffix);\n    PaaSResourceUtils.sortProperties(resList);\n    fillAllProperties(prop, resList);\n\n    return prop;\n  }\n\n  public static void fillAllProperties(Properties prop, List<Resource> resList) throws IOException {\n    for (Resource res : resList) {\n      PaaSPropertiesLoaderUtils.fillProperties(prop, res);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/config/impl/PropertiesLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config.impl;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Properties;\n\nimport org.apache.servicecomb.foundation.common.config.PaaSResourceUtils;\nimport org.springframework.core.io.Resource;\n\npublic class PropertiesLoader extends AbstractLoader {\n  private final List<Resource> foundResList = new ArrayList<>();\n\n  public PropertiesLoader(List<String> locationPatternList) {\n    super(locationPatternList);\n  }\n\n  public List<Resource> getFoundResList() {\n    return foundResList;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public <T> T load() throws Exception {\n    Properties props = new Properties();\n    for (String locationPattern : locationPatternList) {\n      List<Resource> resList = PaaSResourceUtils.getSortedProperties(locationPattern);\n      foundResList.addAll(resList);\n      PaaSPropertiesLoaderUtils.fillAllProperties(props, resList);\n    }\n\n    return (T) props;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/config/impl/XmlLoaderUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config.impl;\n\nimport java.io.IOException;\nimport java.net.URL;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\n\nimport org.apache.servicecomb.foundation.common.utils.FortifyUtils;\nimport org.springframework.core.io.Resource;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\nimport org.w3c.dom.Node;\nimport org.xml.sax.SAXException;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.dataformat.xml.XmlMapper;\n\npublic final class XmlLoaderUtils {\n  private XmlLoaderUtils() {\n  }\n\n  private static final ObjectMapper xmlMapper = new XmlMapper();\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T load(Resource res, Class<?> cls) throws Exception {\n    return (T) xmlMapper.readValue(res.getURL(), cls);\n  }\n\n  public static Document load(URL url) throws ParserConfigurationException, SAXException, IOException {\n    DocumentBuilderFactory dbf = FortifyUtils.getSecurityXmlDocumentFactory();\n    // CodeDEX要求xml必须校验\n    // 不过这都是用于加载内部配置的，申请例外吧\n    dbf.setValidating(false);\n    DocumentBuilder db = dbf.newDocumentBuilder();\n\n    return db.parse(url.toString());\n  }\n\n  public static Document load(Resource res) throws Exception {\n    return load(res.getURL());\n  }\n\n  public static Document newDoc() throws ParserConfigurationException {\n    DocumentBuilderFactory factory = FortifyUtils.getSecurityXmlDocumentFactory();\n    DocumentBuilder builder = factory.newDocumentBuilder();\n    return builder.newDocument();\n  }\n\n  public static void mergeElement(Element from, Element to) {\n    // attrs\n    for (int idx = 0; idx < from.getAttributes().getLength(); idx++) {\n      Node node = from.getAttributes().item(idx);\n      to.getAttributes().setNamedItem(node.cloneNode(false));\n    }\n\n    // children\n    for (int idx = 0; idx < from.getChildNodes().getLength(); idx++) {\n      Node node = from.getChildNodes().item(idx);\n\n      if (!Element.class.isInstance(node)) {\n        continue;\n      }\n\n      to.appendChild(node.cloneNode(true));\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/encrypt/Encryption.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.encrypt;\n\n/**\n * Interface for users to encode/decode confidential data\n */\npublic interface Encryption {\n  default int getOrder() {\n    return 0;\n  }\n\n  /**\n   * decode confidential data\n   * @param encrypted encrypted data\n   * @param tags extra information used to do something\n   * @return plain data\n   */\n  char[] decode(char[] encrypted, String tags);\n\n  /**\n   *\n   * @param plain plain data\n   * @param tags extra information used to do something\n   * @return encrypted data\n   */\n  char[] encode(char[] plain, String tags);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/encrypt/Encryptions.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.encrypt;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class Encryptions {\n  private static Encryption encryption = SPIServiceUtils.getPriorityHighestService(Encryption.class);\n\n  @VisibleForTesting\n  static void setEncryption(Encryption encryption) {\n    Encryptions.encryption = encryption;\n  }\n\n  @VisibleForTesting\n  static Encryption getEncryption() {\n    return encryption;\n  }\n\n  public static String decode(String encrypted, String tags) {\n    if (encrypted == null) {\n      return null;\n    }\n    char[] result = decode(encrypted.toCharArray(), tags);\n    if (result == null) {\n      return null;\n    }\n    return new String(result);\n  }\n\n  public static char[] decode(char[] encrypted, String tags) {\n    return encryption.decode(encrypted, tags);\n  }\n\n  public static String encode(String plain, String tags) {\n    if (plain == null) {\n      return null;\n    }\n    char[] result = encode(plain.toCharArray(), tags);\n    if (result == null) {\n      return null;\n    }\n    return new String(result);\n  }\n\n  public static char[] encode(char[] plain, String tags) {\n    return encryption.encode(plain, tags);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/encrypt/NoEncryption.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.encrypt;\n\npublic class NoEncryption implements Encryption {\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n\n  @Override\n  public char[] decode(char[] encrypted, String tags) {\n    return encrypted;\n  }\n\n  @Override\n  public char[] encode(char[] plain, String tags) {\n    return plain;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/AlarmEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.event;\n\npublic class AlarmEvent {\n\n  Type type;\n\n  public AlarmEvent(Type type) {\n    this.type = type;\n  }\n\n  public Type getType() {\n    return this.type;\n  }\n\n  public enum Type {\n    OPEN,\n    CLOSE\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EnableExceptionPropagation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.event;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * do not suppress exception\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\npublic @interface EnableExceptionPropagation {\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/EventManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.event;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\nimport com.google.common.eventbus.EventBus;\n\n/**\n * EventManager for chassis events\n *\n */\n@Configuration\npublic class EventManager {\n  public static EventBus eventBus = new SimpleEventBus();\n\n  public static EventBus getEventBus() {\n    return eventBus;\n  }\n\n  /**\n   * Registering listener.\n   */\n  public static void register(Object listener) {\n    eventBus.register(listener);\n  }\n\n  /**\n   * post event.\n   */\n  public static void post(Object event) {\n    eventBus.post(event);\n  }\n\n  /**\n   * Unregistering listener.\n   */\n  public static void unregister(Object listener) {\n    eventBus.unregister(listener);\n  }\n\n  @Bean\n  public EventBus scbEventBus() {\n    return eventBus;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/SimpleEventBus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.event;\n\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.reflect.MethodUtils;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\n/**\n * for register/unregister rarely\n */\npublic class SimpleEventBus extends EventBus {\n  private final Map<Object, List<SimpleSubscriber>> subscribersMap = new ConcurrentHashMapEx<>();\n\n  // key is event class\n  private Map<Class<?>, List<SimpleSubscriber>> subscribersCache = new ConcurrentHashMapEx<>();\n\n  private List<SimpleSubscriber> collectSubscribers(Object instance) {\n    List<SimpleSubscriber> subscribers = new ArrayList<>();\n    Method[] methods = MethodUtils.getMethodsWithAnnotation(instance.getClass(), Subscribe.class, true, true);\n    for (Method method : methods) {\n      SimpleSubscriber subscriber = new SimpleSubscriber(instance, method);\n      subscribers.add(subscriber);\n    }\n    return subscribers;\n  }\n\n  @Override\n  public void register(Object instance) {\n    subscribersMap.computeIfAbsent(instance, this::collectSubscribers);\n    // even ignored cause of duplicate register\n    // still reset cache\n    // this makes logic simpler\n    subscribersCache = new ConcurrentHashMapEx<>();\n  }\n\n  @Override\n  public void unregister(Object instance) {\n    if (subscribersMap.remove(instance) != null) {\n      subscribersCache = new ConcurrentHashMapEx<>();\n    }\n  }\n\n  @Override\n  public void post(Object event) {\n    // cache always reset after register/unregister\n    // so cache always match latest subscribersMap at last\n    // the worst scenes is invoke collectSubscriberForEvent multiple times, no problem\n    List<SimpleSubscriber> subscribers = subscribersCache\n        .computeIfAbsent(event.getClass(), this::collectSubscriberForEvent);\n    for (SimpleSubscriber subscriber : subscribers) {\n      subscriber.dispatchEvent(event);\n    }\n  }\n\n  /**\n   * subscribersMap almost stable<br>\n   * so we not care for performance of collectSubscriberForEvent\n   * @param eventClass\n   */\n  private List<SimpleSubscriber> collectSubscriberForEvent(Class<?> eventClass) {\n    List<SimpleSubscriber> subscribersForEvent = new ArrayList<>();\n    for (List<SimpleSubscriber> subscribers : subscribersMap.values()) {\n      for (SimpleSubscriber subscriber : subscribers) {\n        if (subscriber.getMethod().getParameterTypes()[0].isAssignableFrom(eventClass)) {\n          subscribersForEvent.add(subscriber);\n        }\n      }\n    }\n\n    subscribersForEvent.sort(Comparator.comparingInt(SimpleSubscriber::getOrder));\n    return subscribersForEvent;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/SimpleSubscriber.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.event;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.function.Consumer;\n\nimport org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\n\npublic class SimpleSubscriber {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubscriber.class);\n\n  private final Object instance;\n\n  private final Method method;\n\n  private int order;\n\n  private final boolean enableExceptionPropagation;\n\n  // generated from method\n  private Consumer<Object> lambda;\n\n  private Consumer<Object> dispatcher;\n\n  public SimpleSubscriber(Object instance, Method method) {\n    this.instance = instance;\n    this.method = method;\n\n    enableExceptionPropagation = method.getAnnotation(EnableExceptionPropagation.class) != null;\n    SubscriberOrder subscriberOrder = method.getAnnotation(SubscriberOrder.class);\n    if (subscriberOrder != null) {\n      order = subscriberOrder.value();\n    }\n\n    try {\n      lambda = LambdaMetafactoryUtils.createLambda(instance, method, Consumer.class);\n    } catch (Throwable throwable) {\n      // because enhance LambdaMetafactoryUtils to support ALL_MODES by reflect\n      // never run into this branch.\n      // otherwise create a listener instance of anonymous class will run into this branch\n      LOGGER.warn(\"Failed to create lambda for method: {}, fallback to reflect.\", method, throwable);\n\n      checkAccess(method);\n      lambda = event -> {\n        try {\n          method.invoke(instance, event);\n        } catch (Throwable e) {\n          LOGGER.warn(\"Failed to call event listener {}.\", method.getName());\n          throw new IllegalStateException(e);\n        }\n      };\n    }\n\n    dispatcher = this::syncDispatch;\n    if (method.getAnnotation(AllowConcurrentEvents.class) != null) {\n      dispatcher = this::concurrentDispatch;\n    }\n  }\n\n  private static void checkAccess(Method method) {\n    // This check is not accurate. Most of time package visible and protected access can be ignored, so simply do this.\n    if (!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {\n      throw new IllegalStateException(\n          String.format(\n              \"The event handler must be a public accessible method. NOTICE: \"\n                  + \"this is change from 2.0 and using higher version of JDK. \"\n                  + \"Declaring class is %s, method is %s\",\n              method.getDeclaringClass().getName(),\n              method.getName()));\n    }\n  }\n\n  public Object getInstance() {\n    return instance;\n  }\n\n  public Method getMethod() {\n    return method;\n  }\n\n  public int getOrder() {\n    return order;\n  }\n\n  public void dispatchEvent(Object event) {\n    try {\n      dispatcher.accept(event);\n    } catch (Throwable e) {\n      if (enableExceptionPropagation) {\n        throw e;\n      }\n      LOGGER.error(\"Event process should not throw exception when @EnableExceptionPropagation not set. \", e);\n    }\n  }\n\n  private void syncDispatch(Object event) {\n    synchronized (this) {\n      lambda.accept(event);\n    }\n  }\n\n  private void concurrentDispatch(Object event) {\n    lambda.accept(event);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/event/SubscriberOrder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.event;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * order of subscriber<br>\n *   lower values will run first\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\npublic @interface SubscriberOrder {\n  int value() default 0;\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/exceptions/ServiceCombException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.exceptions;\n\npublic class ServiceCombException extends RuntimeException {\n  private static final long serialVersionUID = -1085233183289520695L;\n\n  public ServiceCombException(String cause, Throwable throwable) {\n    super(cause, throwable);\n  }\n\n  public ServiceCombException(String cause) {\n    super(cause);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.http;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.Status.Family;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class HttpStatus implements StatusType {\n  public static boolean isSuccess(int code) {\n    return Status.Family.SUCCESSFUL.equals(Status.Family.familyOf(code));\n  }\n\n  public static boolean isSuccess(StatusType status) {\n    return Status.Family.SUCCESSFUL.equals(status.getFamily());\n  }\n\n  private final int statusCode;\n\n  private final String reason;\n\n  public HttpStatus(final int statusCode, final String reasonPhrase) {\n    this.statusCode = statusCode;\n    this.reason = reasonPhrase;\n  }\n\n  @Override\n  public int getStatusCode() {\n    return statusCode;\n  }\n\n  @Override\n  public Family getFamily() {\n    return Family.familyOf(statusCode);\n  }\n\n  @Override\n  public String getReasonPhrase() {\n    return reason;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpStatusManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.http;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\npublic class HttpStatusManager {\n  private final Map<Integer, StatusType> statusMap = new ConcurrentHashMap<>();\n\n  public HttpStatusManager() {\n    for (Status status : Status.values()) {\n      statusMap.put(status.getStatusCode(), status);\n    }\n\n    SPIServiceUtils.getAllService(StatusType.class).forEach(this::addStatusType);\n  }\n\n  public void addStatusType(StatusType status) {\n    if (statusMap.containsKey(status.getStatusCode())) {\n      throw new IllegalStateException(\"repeated status code: \" + status.getStatusCode());\n    }\n\n    statusMap.put(status.getStatusCode(), status);\n  }\n\n  public StatusType getOrCreateByStatusCode(int code) {\n    StatusType statusType = statusMap.get(code);\n    if (statusType != null) {\n      return statusType;\n    }\n\n    statusType = new HttpStatus(code, \"\");\n    addStatusType(statusType);\n\n    return statusType;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpStatusUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.http;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic final class HttpStatusUtils {\n  private static final HttpStatusManager MGR = new HttpStatusManager();\n\n  private HttpStatusUtils() {\n  }\n\n  public static StatusType getOrCreateByStatusCode(int code) {\n    return MGR.getOrCreateByStatusCode(code);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.http;\n\nimport java.io.File;\nimport java.net.URI;\nimport java.net.URISyntaxException;\n\n\nimport com.google.common.net.UrlEscapers;\nimport org.apache.commons.lang3.StringUtils;\n\npublic final class HttpUtils {\n  private HttpUtils() {\n  }\n\n  /**\n   * paramName is not case sensitive\n   * @param headerValue example: attachment;filename=a.txt\n   *\n   */\n  public static String parseParamFromHeaderValue(String headerValue, String paramName) {\n    if (StringUtils.isEmpty(headerValue)) {\n      return null;\n    }\n\n    for (String value : headerValue.split(\";\")) {\n      int idx = value.indexOf('=');\n      if (idx == -1) {\n        continue;\n      }\n      if (paramName.equalsIgnoreCase(value.substring(0, idx).trim())) {\n        return value.substring(idx + 1).replaceAll(\"\\\"\", \"\").trim();\n      }\n    }\n    return null;\n  }\n\n  /**\n   * <pre>\n   *          foo://example.com:8042/over/there?name=ferret#nose\n   *          \\_/   \\______________/\\_________/ \\_________/ \\__/\n   *           |           |            |            |        |\n   *        scheme     authority       path        query   fragment\n   *           |   _____________________|__\n   *          / \\ /                        \\\n   *          urn:example:animal:ferret:nose\n   * </pre>\n   * <p>the URI syntax components above is referred from <a href=\"https://tools.ietf.org/html/rfc3986#page-16\">RFC3986</a>.\n   * This method is used to encode the entire path part(e.g. /over/there in the example).</p>\n   * <em>In order to keep the structure of path, slash '/' will not be encoded. If you want to encode '/' into {@code %2F},\n   * please consider the {@link #encodePathParam(String)}\n   * </em>\n   *\n   * @param path the entire url path\n   * @return the encoded url path\n   */\n  public static String uriEncodePath(String path) {\n    try {\n      URI uri = new URI(null, null, path, null);\n      return uri.toASCIIString();\n    } catch (URISyntaxException e) {\n      throw new IllegalArgumentException(String.format(\"uriEncode failed, path=\\\"%s\\\".\", path), e);\n    }\n  }\n\n  /**\n   * Encode path params. For example, if the path of an operation is {@code /over/there/{pathParam}/tail}, this method\n   * should be used to encoded {@code {pathParam}}. In order to keep the path structure, the slash '/' will be encoded\n   * into {@code %2F} to avoid path matching problem.\n   *\n   * @see UrlEscapers#urlPathSegmentEscaper()\n   *\n   * @param pathParam the path param to be encoded\n   * @return the encoded path param\n   */\n  public static String encodePathParam(String pathParam) {\n    return UrlEscapers.urlPathSegmentEscaper().escape(pathParam);\n  }\n\n  public static String uriDecodePath(String path) {\n    if (path == null) {\n      return null;\n    }\n\n    try {\n      return new URI(path).getPath();\n    } catch (URISyntaxException e) {\n      throw new IllegalArgumentException(String.format(\"uriDecode failed, path=\\\"%s\\\".\", path), e);\n    }\n  }\n\n  /**\n   * only used by SDK to download from  serviceComb producer<br>\n   * no need to check rtf6266's \"filename*\" rule.\n   */\n  public static String parseFileNameFromHeaderValue(String headerValue) {\n    String fileName = parseParamFromHeaderValue(headerValue, \"filename\");\n    fileName = StringUtils.isEmpty(fileName) ? \"default\" : fileName;\n    fileName = uriDecodePath(fileName);\n    return new File(fileName).getName();\n  }\n\n  /**\n   * Parse the character encoding from the specified content type header.\n   * If the content type is null, or there is no explicit character encoding,\n   * <code>null</code> is returned.\n   *\n   * @param contentType a content type header\n   */\n  public static String getCharsetFromContentType(String contentType) {\n    if (contentType == null) {\n      return null;\n    }\n    int start = contentType.indexOf(\"charset=\");\n    if (start < 0) {\n      return null;\n    }\n    String encoding = contentType.substring(start + 8);\n    int end = encoding.indexOf(';');\n    if (end >= 0) {\n      encoding = encoding.substring(0, end);\n    }\n    encoding = encoding.trim();\n    if ((encoding.length() > 2) && (encoding.startsWith(\"\\\"\"))\n        && (encoding.endsWith(\"\\\"\"))) {\n      encoding = encoding.substring(1, encoding.length() - 1);\n    }\n    return encoding.trim();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/io/AsyncCloseable.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.io;\n\nimport java.util.concurrent.CompletableFuture;\n\npublic interface AsyncCloseable<T> {\n  CompletableFuture<T> close();\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/log/AbstractMarker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.log;\n\nimport java.util.Collections;\nimport java.util.Iterator;\n\nimport org.slf4j.Marker;\n\npublic abstract class AbstractMarker implements Marker {\n  private static final long serialVersionUID = -1L;\n\n  @Override\n  public void add(Marker reference) {\n\n  }\n\n  @Override\n  public boolean remove(Marker reference) {\n    return false;\n  }\n\n  @Deprecated\n  @Override\n  public boolean hasChildren() {\n    return false;\n  }\n\n  @Override\n  public boolean hasReferences() {\n    return false;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public Iterator<Marker> iterator() {\n    return Collections.EMPTY_LIST.iterator();\n  }\n\n  @Override\n  public boolean contains(Marker other) {\n    return false;\n  }\n\n  @Override\n  public boolean contains(String name) {\n    return false;\n  }\n\n  @Override\n  public String toString() {\n    return getName();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/IpPort.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.net;\n\nimport java.net.InetSocketAddress;\n\nimport com.google.common.base.Objects;\n\npublic class IpPort {\n  private volatile String hostOrIp;\n\n  private volatile int port;\n\n  private volatile InetSocketAddress socketAddress;\n\n  private final Object lock = new Object();\n\n  public IpPort() {\n\n  }\n\n  public IpPort(String hostOrIp, int port) {\n    this.hostOrIp = hostOrIp;\n    this.port = port;\n  }\n\n  public String getHostOrIp() {\n    return hostOrIp;\n  }\n\n  public void setHostOrIp(String hostOrIp) {\n    this.hostOrIp = hostOrIp;\n  }\n\n  public int getPort() {\n    return port;\n  }\n\n  public void setPort(int port) {\n    this.port = port;\n  }\n\n  @Override\n  public int hashCode() {\n    return Objects.hashCode(port, hostOrIp);\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }\n\n    IpPort ipPort = (IpPort) o;\n\n    if (port != ipPort.port) {\n      return false;\n    }\n    return hostOrIp.equals(ipPort.hostOrIp);\n  }\n\n  @Override\n  public String toString() {\n    return hostOrIp + \":\" + port;\n  }\n\n  public InetSocketAddress getSocketAddress() {\n    if (socketAddress == null) {\n      synchronized (lock) {\n        if (socketAddress == null) {\n          InetSocketAddress tmpSocketAddress = new InetSocketAddress(hostOrIp, port);\n          socketAddress = tmpSocketAddress;\n        }\n      }\n    }\n\n    return socketAddress;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/NetUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.net;\n\nimport java.io.IOException;\nimport java.net.Inet4Address;\nimport java.net.Inet6Address;\nimport java.net.InetAddress;\nimport java.net.NetworkInterface;\nimport java.net.ServerSocket;\nimport java.net.SocketException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic final class NetUtils {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(NetUtils.class);\n\n  private static final String IPV4_KEY = \"_v4\";\n\n  private static final String IPV6_KEY = \"_v6\";\n\n  private static final String PREFERRED_INTERFACE = \"eth\";\n\n  // one interface can bind to multiple address\n  // we only save one ip for each interface name.\n  // eg:\n  // 1. eth0 -> ip1 ip2\n  //    last data is eth0 -> ip2\n  // 2. eth0 -> ip1\n  //    eth0:0 -> ip2\n  //    eth0:1 -> ip3\n  //    on interface name conflict, all data saved\n\n  // key is network interface name and type\n  private static Map<String, InetAddress> allInterfaceAddresses = new HashMap<>();\n\n  private static String hostName;\n\n  private static String hostAddress;\n\n  private static String hostAddressIpv6;\n\n  static {\n    doGetHostNameAndHostAddress();\n  }\n\n  private static void doGetHostNameAndHostAddress() {\n    try {\n      doGetAddressFromNetworkInterface();\n      // getLocalHost will throw exception in some docker image and sometimes will do a hostname lookup and time consuming\n      InetAddress localHost = InetAddress.getLocalHost();\n      hostName = localHost.getHostName();\n      LOGGER.info(\"localhost hostName={}, hostAddress={}.\", hostName, localHost.getHostAddress());\n\n      if (!isLocalAddress(localHost)) {\n        if (Inet6Address.class.isInstance(localHost)) {\n          hostAddressIpv6 = trimIpv6(localHost.getHostAddress());\n          hostAddress = tryGetHostAddressFromNetworkInterface(false, localHost);\n          LOGGER.info(\"Host address info ipV4={}, ipV6={}.\", hostAddress, hostAddressIpv6);\n          return;\n        }\n        hostAddress = localHost.getHostAddress();\n        hostAddressIpv6 = trimIpv6(tryGetHostAddressFromNetworkInterface(true, localHost));\n        LOGGER.info(\"Host address info ipV4={}, ipV6={}.\", hostAddress, hostAddressIpv6);\n        return;\n      }\n      hostAddressIpv6 = trimIpv6(tryGetHostAddressFromNetworkInterface(true, localHost));\n      hostAddress = tryGetHostAddressFromNetworkInterface(false, localHost);\n      LOGGER.info(\"Host address info ipV4={}, ipV6={}.\", hostAddress, hostAddressIpv6);\n    } catch (Exception e) {\n      LOGGER.error(\"got exception when trying to get addresses:\", e);\n      if (allInterfaceAddresses.size() >= 1) {\n        InetAddress entry = allInterfaceAddresses.entrySet().iterator().next().getValue();\n        // get host name will do a reverse name lookup and is time consuming\n        hostName = entry.getHostName();\n        hostAddress = entry.getHostAddress();\n        LOGGER.info(\"add host name from interfaces:\" + hostName + \",host address:\" + hostAddress);\n      }\n    }\n  }\n\n  private static String tryGetHostAddressFromNetworkInterface(boolean isIpv6, InetAddress localhost) {\n    InetAddress result = null;\n    for (Entry<String, InetAddress> entry : allInterfaceAddresses.entrySet()) {\n      if (isIpv6 && entry.getKey().endsWith(IPV6_KEY)) {\n        result = entry.getValue();\n        if (entry.getKey().startsWith(PREFERRED_INTERFACE)) {\n          return result.getHostAddress();\n        }\n      } else if (!isIpv6 && entry.getKey().endsWith(IPV4_KEY)) {\n        result = entry.getValue();\n        if (entry.getKey().startsWith(PREFERRED_INTERFACE)) {\n          return result.getHostAddress();\n        }\n      }\n    }\n\n    if (result == null) {\n      return localhost.getHostAddress();\n    }\n\n    return result.getHostAddress();\n  }\n\n  private NetUtils() {\n  }\n\n  /**\n   * docker环境中，有时无法通过InetAddress.getLocalHost()获取 ，会报unknown host Exception， system error\n   * 此时，通过遍历网卡接口的方式规避，出来的数据不一定对\n   */\n  private static void doGetAddressFromNetworkInterface() throws SocketException {\n    Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();\n\n    while (networkInterfaces.hasMoreElements()) {\n      NetworkInterface network = networkInterfaces.nextElement();\n\n      if (!network.isUp() || network.isLoopback() || network.isVirtual()) {\n        continue;\n      }\n\n      Enumeration<InetAddress> addresses = network.getInetAddresses();\n      while (addresses.hasMoreElements()) {\n        InetAddress address = addresses.nextElement();\n\n        if (isLocalAddress(address)) {\n          continue;\n        }\n\n        if (address instanceof Inet4Address) {\n          LOGGER.info(\"add ipv4 network interface:\" + network.getName() + \",host address:\" + address.getHostAddress());\n          allInterfaceAddresses.put(network.getName() + IPV4_KEY, address);\n        } else if (address instanceof Inet6Address) {\n          LOGGER.info(\"add ipv6 network interface:\" + network.getName() + \",host address:\" + address.getHostAddress());\n          allInterfaceAddresses.put(network.getName() + IPV6_KEY, address);\n        }\n      }\n    }\n  }\n\n  private static String trimIpv6(String hostAddress) {\n    int index = hostAddress.indexOf(\"%\");\n    if (index >= 0) {\n      return hostAddress.substring(0, index);\n    }\n    return hostAddress;\n  }\n\n  private static boolean isLocalAddress(InetAddress address) {\n    return address.isAnyLocalAddress() || address.isLoopbackAddress() || address.isMulticastAddress();\n  }\n\n  /**\n   * The format of address should be {@code IPv4:port} or {@code [IPv6]:port}, or {@code host:port},\n   * or you will not get expected result.\n   *\n   * Note that the IPv6 address should be wrapped by square brackets.\n   * @return IpPort parsed from input param, or {@code null} if the param is null.\n   */\n  public static IpPort parseIpPort(String address) {\n    if (address == null) {\n      return null;\n    }\n\n    URI uri = URI.create(\"http://\" + address);\n    return parseIpPort(uri, true);\n  }\n\n  /**\n   * Parse a {@link URI} into an {@link IpPort}.\n   *\n   * <p>\n   *   A uri without port is allowed, in which case the port will be inferred from the scheme. {@code http} is 80, and\n   *   {@code https} is 443.\n   * </p>\n   * <p>\n   *   The host of the {@code uri} should not be null, or it will be treated as an illegal param,\n   *   and an {@link IllegalArgumentException} will be thrown.\n   * </p>\n   */\n  public static IpPort parseIpPort(URI uri) {\n    return parseIpPort(uri, false);\n  }\n\n  /**\n   * Parse a {@link URI} into an {@link IpPort}\n   * @param uri a uri representing {@link IpPort}\n   * @param ignorePortUndefined whether the port should be inferred from scheme, when the port part of {@code uri} is {@code -1}.\n   * If {@code true} the undefined port is ignored;\n   * otherwise a port will be inferred from scheme: {@code http} is 80, and {@code https} is 443.\n   */\n  public static IpPort parseIpPort(URI uri, boolean ignorePortUndefined) {\n    if (null == uri.getHost()) {\n      // if the format of address is legal but the value is out of range, URI#create(String) will not throw exception\n      // but return a URI with null host.\n      throw new IllegalArgumentException(\"Illegal uri: [\" + uri + \"]\");\n    }\n\n    IpPort ipPort = new IpPort(uri.getHost(), uri.getPort());\n    if (-1 != ipPort.getPort() || ignorePortUndefined) {\n      return ipPort;\n    }\n\n    if (uri.getScheme().equals(\"http\")) {\n      ipPort.setPort(80);\n    }\n    if (uri.getScheme().equals(\"https\")) {\n      ipPort.setPort(443);\n    }\n\n    return ipPort;\n  }\n\n  /**\n   * @param uriAddress the address containing IP and port info.\n   * @return IpPort parsed from input param, or {@code null} if the param is null.\n   */\n  public static IpPort parseIpPortFromURI(String uriAddress) {\n    if (uriAddress == null) {\n      return null;\n    }\n\n    try {\n      return parseIpPort(new URI(uriAddress));\n    } catch (URISyntaxException e) {\n      return null;\n    }\n  }\n\n  public static IpPort parseIpPort(String scheme, String authority) {\n    if (authority == null) {\n      return null;\n    }\n    return parseIpPort(URI.create(scheme + \"://\" + authority));\n  }\n\n  /**\n   * 对于配置为0.0.0.0的地址，let it go\n   * schema, e.g. http\n   * address, e.g 0.0.0.0:8080\n   * return 实际监听的地址\n   */\n  public static String getRealListenAddress(String schema, String address) {\n    if (address == null) {\n      return null;\n    }\n    try {\n      URI originalURI = new URI(schema + \"://\" + address);\n      // validate original url\n      NetUtils.parseIpPort(originalURI);\n\n      return originalURI.toString();\n    } catch (URISyntaxException e) {\n      LOGGER.error(\"address {} is not valid.\", address);\n      return null;\n    }\n  }\n\n  public static String getHostName() {\n    //If failed to get host name ,micro-service will registry failed\n    //So I add retry mechanism\n    if (hostName == null) {\n      doGetHostNameAndHostAddress();\n    }\n    return hostName;\n  }\n\n  @VisibleForTesting\n  static void resetHostName() {\n    hostName = null;\n  }\n\n  public static String getHostAddress() {\n    //If failed to get host address ,micro-service will registry failed\n    //So I add retry mechanism\n    if (hostAddress == null) {\n      doGetHostNameAndHostAddress();\n    }\n    return hostAddress;\n  }\n\n  public static String getIpv6HostAddress() {\n    //If failed to get host address ,micro-service will registry failed\n    //So I add retry mechanism\n    if (hostAddressIpv6 == null) {\n      doGetHostNameAndHostAddress();\n    }\n    return hostAddressIpv6;\n  }\n\n  public static InetAddress getInterfaceAddress(String interfaceName) {\n    return allInterfaceAddresses.get(interfaceName);\n  }\n\n  public static InetAddress ensureGetInterfaceAddress(String interfaceName) {\n    InetAddress address = allInterfaceAddresses.get(interfaceName);\n    if (address == null) {\n      throw new IllegalArgumentException(\"Can not find address for interface name: \" + interfaceName);\n    }\n    return address;\n  }\n\n  @SuppressWarnings({\"unused\", \"try\"})\n  public static boolean canTcpListen(InetAddress address, int port) {\n    try (ServerSocket ss = new ServerSocket(port, 0, address)) {\n      return true;\n    } catch (IOException e) {\n      return false;\n    }\n  }\n\n  public static String humanReadableBytes(long bytes) {\n    int unit = 1024;\n    if (bytes < unit) {\n      return String.valueOf(bytes);\n    }\n    int exp = (int) (Math.log(bytes) / Math.log(unit));\n    char pre = \"KMGTPE\".charAt(exp - 1);\n    return String.format(\"%.3f%c\", bytes / Math.pow(unit, exp), pre);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/URIEndpointObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.net;\n\nimport java.net.URI;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.NameValuePair;\nimport org.apache.http.client.utils.URLEncodedUtils;\n\n/**\n * transport公共的Endpoint Object，当transport使用URI表示的时候，可以转化为这个对象。\n */\npublic class URIEndpointObject extends IpPort {\n  private static final String SSL_ENABLED_KEY = \"sslEnabled\";\n\n  private static final String PROTOCOL_KEY = \"protocol\";\n\n  private static final String WEBSOCKET_ENABLED_KEY = \"websocketEnabled\";\n\n  private static final String HTTP2 = \"http2\";\n\n  private final boolean sslEnabled;\n\n  private boolean http2Enabled;\n\n  private boolean websocketEnabled;\n\n  private final Map<String, List<String>> queries;\n\n  private final String schema;\n\n  public URIEndpointObject(String endpoint) {\n    URI uri = URI.create(endpoint);\n    schema = uri.getScheme();\n    setHostOrIp(uri.getHost());\n    if (uri.getPort() < 0) {\n      // do not use default port\n      throw new IllegalArgumentException(\"port not specified.\");\n    }\n    setPort(uri.getPort());\n    queries = splitQuery(uri);\n    sslEnabled = Boolean.parseBoolean(getFirst(SSL_ENABLED_KEY));\n    websocketEnabled = Boolean.parseBoolean(getFirst(WEBSOCKET_ENABLED_KEY));\n    String httpVersion = getFirst(PROTOCOL_KEY);\n    if (HTTP2.equals(httpVersion)) {\n      http2Enabled = true;\n    }\n  }\n\n  public static Map<String, List<String>> splitQuery(URI uri) {\n    final Map<String, List<String>> queryPairs = new LinkedHashMap<>();\n    List<NameValuePair> pairs = URLEncodedUtils.parse(uri, StandardCharsets.UTF_8);\n    for (NameValuePair pair : pairs) {\n      List<String> list = queryPairs.computeIfAbsent(pair.getName(), name -> new ArrayList<>());\n      list.add(pair.getValue());\n    }\n    return queryPairs;\n  }\n\n  public boolean isSslEnabled() {\n    return sslEnabled;\n  }\n\n  public boolean isWebsocketEnabled() {\n    return websocketEnabled;\n  }\n\n  public boolean isHttp2Enabled() {\n    return http2Enabled;\n  }\n\n  public String getSchema() {\n    return this.schema;\n  }\n\n  public List<String> getQuery(String key) {\n    return queries.get(key);\n  }\n\n  public String getFirst(String key) {\n    List<String> values = queries.get(key);\n    // it's impossible that values is not null and size is 0\n    if (values == null) {\n      return null;\n    }\n\n    return values.get(0);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/AbstractPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Collection;\n\nimport javax.activation.MimetypesFileTypeMap;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class AbstractPart implements Part {\n  private static final MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();\n\n  protected String name;\n\n  private String submittedFileName;\n\n  protected String contentType;\n\n  @Override\n  public InputStream getInputStream() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getContentType() {\n    return contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T contentType(String contentType) {\n    this.contentType = contentType;\n    return (T) this;\n  }\n\n  @Override\n  public String getName() {\n    return name;\n  }\n\n  @Override\n  public String getSubmittedFileName() {\n    return submittedFileName;\n  }\n\n  public AbstractPart setSubmittedFileName(String submittedFileName) {\n    this.submittedFileName = submittedFileName;\n    updateContentType();\n    return this;\n  }\n\n  private void updateContentType() {\n    if (contentType != null || submittedFileName == null) {\n      return;\n    }\n\n    contentType = mimetypesFileTypeMap.getContentType(submittedFileName);\n  }\n\n  @Override\n  public long getSize() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void write(String fileName) throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void delete() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getHeader(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Collection<String> getHeaders(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Collection<String> getHeaderNames() {\n    throw new Error(\"not supported method\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.file.Files;\n\nimport org.apache.commons.io.FileUtils;\n\npublic class FilePart extends AbstractPart implements FilePartForSend {\n  private final File file;\n\n  private boolean deleteAfterFinished;\n\n  public FilePart(String name, String file) {\n    this(name, new File(file));\n  }\n\n  public FilePart(String name, File file) {\n    this.name = name;\n    this.file = file;\n    this.setSubmittedFileName(this.file.getName());\n  }\n\n  @Override\n  public InputStream getInputStream() throws IOException {\n    return Files.newInputStream(file.toPath());\n  }\n\n  @Override\n  public long getSize() {\n    return file.length();\n  }\n\n  @Override\n  public void write(String fileName) throws IOException {\n    FileUtils.copyFile(file, new File(fileName));\n  }\n\n  @Override\n  public void delete() throws IOException {\n    file.delete();\n  }\n\n  @Override\n  public boolean isDeleteAfterFinished() {\n    return deleteAfterFinished;\n  }\n\n  public FilePart setDeleteAfterFinished(boolean deleteAfterFinished) {\n    this.deleteAfterFinished = deleteAfterFinished;\n    return this;\n  }\n\n  @Override\n  public String getAbsolutePath() {\n    return file.getAbsolutePath();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/FilePartForSend.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.part;\n\nimport jakarta.servlet.http.Part;\n\npublic interface FilePartForSend extends Part {\n  boolean isDeleteAfterFinished();\n\n  String getAbsolutePath();\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/InputStreamPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.InputStream;\n\nimport org.springframework.core.io.InputStreamResource;\n\npublic class InputStreamPart extends ResourcePart {\n  public InputStreamPart(String name, InputStream inputStream) {\n    super(name, new InputStreamResource(inputStream));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/part/ResourcePart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport org.springframework.core.io.Resource;\n\npublic class ResourcePart extends AbstractPart {\n  private final Resource resource;\n\n  public ResourcePart(String name, Resource resource) {\n    this.name = name;\n    this.resource = resource;\n    this.setSubmittedFileName(resource.getFilename());\n  }\n\n  @Override\n  public InputStream getInputStream() throws IOException {\n    return resource.getInputStream();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/spring/PaasNamespaceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.spring;\n\nimport java.util.Map.Entry;\nimport java.util.Properties;\n\nimport org.apache.servicecomb.foundation.common.config.PaaSResourceUtils;\nimport org.apache.servicecomb.foundation.common.utils.FortifyUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.xml.BeanDefinitionParser;\nimport org.springframework.beans.factory.xml.NamespaceHandlerSupport;\n\n//根据各个jar提供的信息来注册parser\npublic class PaasNamespaceHandler extends NamespaceHandlerSupport {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PaasNamespaceHandler.class);\n\n  private static final String NAMESPACE_RES = \"classpath*:META-INF/spring/namespace.properties\";\n\n  // @Override\n  public void init() {\n    Properties properties = null;\n\n    try {\n      properties = PaaSResourceUtils.loadMergedProperties(NAMESPACE_RES);\n    } catch (Exception e) {\n      LOGGER.error(\"Failed to load namespace handler define, {}, {}\",\n          NAMESPACE_RES,\n          FortifyUtils.getErrorInfo(e));\n      return;\n    }\n\n    for (Entry<Object, Object> entry : properties.entrySet()) {\n      String className = entry.getValue().toString();\n      try {\n        Class<?> clazz = Class.forName(className);\n        Object instance = clazz.getDeclaredConstructor().newInstance();\n        registerBeanDefinitionParser(entry.getKey().toString(),\n            (BeanDefinitionParser) instance);\n      } catch (ReflectiveOperationException e) {\n        // 类找不到，说明没部署相应的jar包，这不一定是错误\n        // 可能是业务就选择不部署相应的jar包\n        // 所以只是打印个info日志\n\n        LOGGER.info(\"Failed to create BeanDefinitionParser instance of {}\", className);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/AbstractRestObjectMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\npublic abstract class AbstractRestObjectMapper extends ObjectMapper {\n  private static final long serialVersionUID = 189026839992490564L;\n\n  public AbstractRestObjectMapper() {\n    super();\n  }\n\n  public AbstractRestObjectMapper(RestObjectMapper src) {\n    super(src);\n  }\n\n  public abstract String convertToString(Object value) throws Exception;\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/AsyncUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\n\npublic final class AsyncUtils {\n  private AsyncUtils() {\n  }\n\n  public static <T> CompletableFuture<T> tryCatchSupplier(Supplier<T> supplier) {\n    try {\n      T value = supplier.get();\n      return CompletableFuture.completedFuture(value);\n    } catch (Throwable e) {\n      return completeExceptionally(e);\n    }\n  }\n\n  public static <T> CompletableFuture<T> tryCatchSupplierFuture(Supplier<CompletableFuture<T>> supplier) {\n    try {\n      return supplier.get();\n    } catch (Throwable e) {\n      return completeExceptionally(e);\n    }\n  }\n\n  public static <T> CompletableFuture<T> completeExceptionally(Throwable throwable) {\n    CompletableFuture<T> future = new CompletableFuture<>();\n    future.completeExceptionally(throwable);\n    return future;\n  }\n\n  /**\n   * throws {@code exception} as RuntimeException.\n   *\n   * @param exception exception which will be rethrow\n   */\n  public static RuntimeException rethrow(Throwable exception) {\n    if (exception instanceof RuntimeException) {\n      return (RuntimeException) exception;\n    }\n    return new ServiceCombException(\"Not declared exception\", exception);\n  }\n\n  public static <T> T toSync(CompletableFuture<T> future) {\n    try {\n      return future.get();\n    } catch (ExecutionException executionException) {\n      throw rethrow(executionException.getCause());\n    } catch (Throwable e) {\n      throw rethrow(e);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/BeanUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.springframework.aop.framework.AopProxyUtils;\nimport org.springframework.context.ApplicationContext;\n\n\npublic final class BeanUtils {\n  private static ApplicationContext context;\n\n  private BeanUtils() {\n  }\n\n  public static ApplicationContext getContext() {\n    return context;\n  }\n\n  public static void setContext(ApplicationContext applicationContext) {\n    context = applicationContext;\n  }\n\n  /**\n   * 不应该在业务流程中频繁调用，因为内部必然会加一个锁做互斥，会影响并发度\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T getBean(String name) {\n    return (T) context.getBean(name);\n  }\n\n  public static <T> Map<String, T> getBeansOfType(Class<T> type) {\n    if (context == null) {\n      // for some test case\n      return Collections.emptyMap();\n    }\n    return context.getBeansOfType(type);\n  }\n\n  public static <T> T getBean(Class<T> type) {\n    if (context == null) {\n      // for some test case\n      return null;\n    }\n    return context.getBean(type);\n  }\n\n  /**\n   * Get the implemented class of the given instance\n   * @param bean the instance to get implemented class from\n   * @return the implemented class (if the checked class is proxied, return the ultimate target class)\n   * @see org.springframework.aop.framework.AopProxyUtils#ultimateTargetClass\n   */\n  public static Class<?> getImplClassFromBean(Object bean) {\n    return AopProxyUtils.ultimateTargetClass(bean);\n  }\n\n  public static <T extends SPIOrder & SPIEnabled> void addBeans(Class<T> cls, List<T> exists) {\n    if (context == null) {\n      return;\n    }\n\n    for (T instance : exists) {\n      context.getAutowireCapableBeanFactory().autowireBean(instance);\n    }\n    for (T bean : context.getBeansOfType(cls).values()) {\n      if (bean.enabled()) {\n        exists.add(bean);\n      }\n    }\n    exists.sort(Comparator.comparingInt(SPIOrder::getOrder));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/ClassLoaderScopeContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n* class loader scope property is used when users run java-chassis in an class loader separated environment.\n*\n* For examples, deploy two war's to web container, or deploy two bundles in an OSGI container.\n*\n* Now java chassis not testing this feature carefully, but we will support users doing so.\n*\n* users who using this feature can feed back your problems in issues.\n*\n*/\npublic class ClassLoaderScopeContext {\n\n  private static final Map<String, String> CLASS_LOADER_SCOPE_CONTEXT = new HashMap<>();\n\n  public static void setClassLoaderScopeProperty(String key, String value) {\n    CLASS_LOADER_SCOPE_CONTEXT.put(key, value);\n  }\n\n  public static String getClassLoaderScopeProperty(String key) {\n    return CLASS_LOADER_SCOPE_CONTEXT.get(key);\n  }\n\n  @VisibleForTesting\n  public static void clearClassLoaderScopeProperty() {\n    CLASS_LOADER_SCOPE_CONTEXT.clear();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/ConditionWaiter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\n\npublic class ConditionWaiter<T> {\n  private final AtomicReference<T> dataReference;\n\n  private final AtomicBoolean isComplete;\n\n  private final long sleepDuration;\n\n  private final TimeUnit timeUnit;\n\n  private final ExecutorService executorService;\n\n  public ConditionWaiter(T initialData, long sleepDuration, TimeUnit timeUnit) {\n    this.dataReference = new AtomicReference<>(initialData);\n    this.isComplete = new AtomicBoolean(false);\n    this.sleepDuration = sleepDuration;\n    this.timeUnit = timeUnit;\n    this.executorService = Executors.newSingleThreadExecutor();\n  }\n\n  public T waitForCompletion() {\n    while (!isComplete.get()) {\n      SleepUtil.sleep(sleepDuration, timeUnit);\n    }\n    return dataReference.get();\n  }\n\n  public void setData(T newData) {\n    dataReference.set(newData);\n  }\n\n  public void executeTaskAsync(Callable<T> task) {\n    CompletableFuture.supplyAsync(() -> {\n      try {\n        return task.call();\n      } catch (Exception e) {\n        throw new RuntimeException(\"Task execution failed\", e);\n      }\n    }, executorService).thenAccept(result -> {\n      setData(result);\n      isComplete.set(true);\n    });\n  }\n\n  public static class SleepUtil {\n    public static void sleep(long duration, TimeUnit timeUnit) {\n      try {\n        timeUnit.sleep(duration);\n      } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n        System.out.println(\"Thread was interrupted during sleep!\");\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/ExceptionUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic class ExceptionUtils {\n  private static final int DEPTH = 5;\n\n  private ExceptionUtils() {\n\n  }\n\n  public static String getExceptionMessageWithoutTrace(Throwable e) {\n    StringBuilder result = new StringBuilder();\n    appendExceptionInfo(e, result);\n    Throwable cause = e.getCause();\n    int depth = DEPTH;\n    while (cause != null && depth-- > 0) {\n      result.append(\";\");\n      appendExceptionInfo(cause, result);\n      cause = cause.getCause();\n    }\n    return result.toString();\n  }\n\n  private static void appendExceptionInfo(Throwable e, StringBuilder result) {\n    result.append(\"cause:\");\n    result.append(e.getClass().getSimpleName());\n    result.append(\",message:\");\n    result.append(e.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/FilePerm.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.FileSystem;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.attribute.AclEntryPermission;\nimport java.nio.file.attribute.PosixFileAttributes;\nimport java.nio.file.attribute.PosixFilePermission;\nimport java.nio.file.attribute.PosixFilePermissions;\nimport java.util.Arrays;\nimport java.util.EnumSet;\nimport java.util.Set;\n\npublic final class FilePerm {\n  private FilePerm() {\n  }\n\n  /**\n   * owner 可读\n   */\n  public static final int FILE_PERM_UREAD = 256;\n\n  /**\n   * owner 可写\n   */\n  public static final int FILE_PERM_UWRITE = 128;\n\n  /**\n   * owner 可执行\n   */\n  public static final int FILE_PERM_UEXEC = 64;\n\n  /**\n   * 同组可读\n   */\n  public static final int FILE_PERM_GREAD = 32;\n\n  /**\n   * 同组可写\n   */\n  public static final int FILE_PERM_GWRITE = 16;\n\n  /**\n   * 同组可执行\n   */\n  public static final int FILE_PERM_GEXEC = 8;\n\n  /**\n   * 其他可读\n   */\n  public static final int FILE_PERM_OREAD = 4;\n\n  /**\n   * 其他可写\n   */\n  public static final int FILE_PERM_OWRITE = 2;\n\n  /**\n   * 其他可执行\n   */\n  public static final int FILE_PERM_OEXEC = 1;\n\n  /**\n   * mask\n   */\n  public static final int FILE_PERM_MASK = 511;\n\n  private static final AclEntryPermission[] permList = new AclEntryPermission[] {\n      AclEntryPermission.READ_DATA,\n      AclEntryPermission.READ_ATTRIBUTES,\n      AclEntryPermission.READ_NAMED_ATTRS,\n      AclEntryPermission.READ_ACL,\n      AclEntryPermission.WRITE_DATA,\n      AclEntryPermission.APPEND_DATA,\n      AclEntryPermission.WRITE_ATTRIBUTES,\n      AclEntryPermission.WRITE_NAMED_ATTRS,\n      AclEntryPermission.WRITE_ACL,\n      AclEntryPermission.SYNCHRONIZE\n  };\n\n  /**\n   * 获取默认Posix权限:640\n   */\n  public static Set<PosixFilePermission> getDefaultPosixPerm() {\n    return PosixFilePermissions.fromString(\"rw-r-----\");\n  }\n\n  /**\n   * 获取Posix权限\n   */\n  public static Set<PosixFilePermission> getPosixPerm(int perm) {\n    StringBuilder permStr = new StringBuilder();\n\n    permStr.append(uCanRead(perm) ? \"r\" : \"-\");\n    permStr.append(uCanWrite(perm) ? \"w\" : \"-\");\n    permStr.append(uCanExec(perm) ? \"x\" : \"-\");\n    permStr.append(gCanRead(perm) ? \"r\" : \"-\");\n    permStr.append(gCanWrite(perm) ? \"w\" : \"-\");\n    permStr.append(gCanExec(perm) ? \"x\" : \"-\");\n    permStr.append(oCanRead(perm) ? \"r\" : \"-\");\n    permStr.append(oCanWrite(perm) ? \"w\" : \"-\");\n    permStr.append(oCanExec(perm) ? \"x\" : \"-\");\n\n    return PosixFilePermissions.fromString(permStr.toString());\n  }\n\n  /**\n   * 获取默认acl权限\n   */\n  public static Set<AclEntryPermission> getDefaultAclPerm() {\n\n    Set<AclEntryPermission> perms = EnumSet.noneOf(AclEntryPermission.class);\n    perms.addAll(Arrays.asList(permList));\n\n    return perms;\n  }\n\n  /**\n   * owner是否可读\n   */\n  public static boolean uCanRead(int perm) {\n    return (FILE_PERM_UREAD & perm) > 0;\n  }\n\n  /**\n   * owner是否可写\n   */\n  public static boolean uCanWrite(int perm) {\n    return (FILE_PERM_UWRITE & perm) > 0;\n  }\n\n  /**\n   * owner是否可执行\n   */\n  public static boolean uCanExec(int perm) {\n    return (FILE_PERM_UEXEC & perm) > 0;\n  }\n\n  /**\n   * 同组是否可读\n   */\n  public static boolean gCanRead(int perm) {\n    return (FILE_PERM_GREAD & perm) > 0;\n  }\n\n  /**\n   * 同组是否可写\n   */\n  public static boolean gCanWrite(int perm) {\n    return (FILE_PERM_GWRITE & perm) > 0;\n  }\n\n  /**\n   * 同组是否可执行\n   */\n  public static boolean gCanExec(int perm) {\n    return (FILE_PERM_GEXEC & perm) > 0;\n  }\n\n  /**\n   * 其他是否可读\n   */\n  public static boolean oCanRead(int perm) {\n    return (FILE_PERM_GREAD & perm) > 0;\n  }\n\n  /**\n   * 其他是否可写\n   */\n  public static boolean oCanWrite(int perm) {\n    return (FILE_PERM_GWRITE & perm) > 0;\n  }\n\n  /**\n   * 其他是否可执行\n   */\n  public static boolean oCanExec(int perm) {\n    return (FILE_PERM_GEXEC & perm) > 0;\n  }\n\n  /**\n   * 设置文件权限。前提：必须支持PosixFileAttributeView.\n   */\n  public static void setFilePerm(File file, String perm) {\n    if (filePermSupported()) {\n      try {\n        Set<PosixFilePermission> perms = PosixFilePermissions.fromString(perm);\n        PosixFileAttributes attr = Files.readAttributes(file.toPath(), PosixFileAttributes.class);\n        attr.permissions().clear();\n        Files.setPosixFilePermissions(file.toPath(), perms);\n      } catch (IOException e) {\n        throw new IllegalStateException(e);\n      }\n    }\n  }\n\n  public static boolean filePermSupported() {\n    FileSystem system = FileSystems.getDefault();\n    for (String name : system.supportedFileAttributeViews()) {\n      // see javadoc for PosixFileAttributeView.\n      if (\"posix\".equals(name)) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/FortifyUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\nimport javax.xml.XMLConstants;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\n\n/**\n * 规避fortify问题，仅仅是规避，如\n * e.getMessage\n * e.printStackTrace\n * 调用会报安全问题（敏感信息泄露）\n *\n *\n */\npublic final class FortifyUtils {\n\n  private static final Method getMessageMethod;\n\n  private static final Method printStackTraceMethod;\n\n  static {\n    try {\n      getMessageMethod = Throwable.class.getMethod(\"getMessage\");\n      printStackTraceMethod = Throwable.class.getMethod(\"printStackTrace\", PrintWriter.class);\n    } catch (Exception e) {\n      throw new Error(e);\n    }\n  }\n\n  private FortifyUtils() {\n  }\n\n  public static String getErrorMsg(Throwable e) {\n    if (e == null) {\n      return \"\";\n    }\n\n    try {\n      return (String) getMessageMethod.invoke(e);\n    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {\n      return \"\";\n    }\n  }\n\n  public static String getErrorStack(Throwable e) {\n    if (null == e) {\n      return \"\";\n    }\n\n    try {\n      StringWriter errors = new StringWriter();\n      printStackTraceMethod.invoke(e, new PrintWriter(errors));\n      return errors.toString();\n    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {\n      return \"\";\n    }\n  }\n\n  public static String getErrorInfo(Throwable e) {\n    return getErrorInfo(e, true);\n  }\n\n  public static String getErrorInfo(Throwable e, boolean isPrintMsg) {\n    StringBuilder error = new StringBuilder(System.lineSeparator());\n    error.append(\"Exception: \").append(e.getClass().getName()).append(\"; \");\n\n    if (isPrintMsg) {\n      error.append(getErrorMsg(e)).append(System.lineSeparator());\n    }\n    error.append(getErrorStack(e));\n\n    return error.toString();\n  }\n\n  public static DocumentBuilderFactory getSecurityXmlDocumentFactory() throws ParserConfigurationException {\n    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\n    factory.setFeature(\"http://apache.org/xml/features/disallow-doctype-decl\", true);\n    factory.setXIncludeAware(false);\n    factory.setExpandEntityReferences(false);\n    factory.setFeature(\"http://xml.org/sax/features/external-parameter-entities\", false);\n    factory.setFeature(\"http://xml.org/sax/features/external-general-entities\", false);\n    factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);\n    factory.setValidating(true);\n\n    return factory;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/GenericsUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\n\npublic final class GenericsUtils {\n  /**\n   * check if XXX.class is generic type. see TestGenericsUtils for details meaning.\n   * This method is provided for API compatibility for RestTemplate. Following code:\n   * <p>\n   *{@code\n   * List<GenericObjectParam<List<RecursiveObjectParam>>> response = consumers.getSCBRestTemplate()\n   * postForObject(\"/testListObjectParam\", request, List.class);\n   * }\n   *\n   * should work for versions of 1.*. This is because java-chassis can read type info from swaggers.\n   * <p>\n   * Start from 2.x, the best practise to write this code is to use ParameterizedTypeReference provided by RestTemplate\n   * exchange method.\n   */\n  public static boolean isGenericResponseType(Type type) {\n    if (type instanceof ParameterizedType) {\n      return false;\n    }\n    if (type instanceof Class<?>) {\n      return ((Class<?>) type).getTypeParameters().length > 0;\n    }\n    return true;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/IOUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.Closeable;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class IOUtils {\n  @SuppressWarnings(\"deprecation\")\n  public static void closeQuietly(final Closeable closeable) {\n    org.apache.commons.io.IOUtils.closeQuietly(closeable);\n  }\n\n  public static String anonymousPath(String path) {\n    if (StringUtils.isEmpty(path)) {\n      return path;\n    }\n    StringBuilder result = new StringBuilder();\n    char separator = path.contains(\"/\") ? '/' : '\\\\';\n    char[] tokens = path.toCharArray();\n    boolean byPass = false;\n    boolean fileName = true;\n    for (int i = tokens.length - 1; i >= 0; i--) {\n      if (tokens[i] == separator) {\n        fileName = false;\n        byPass = false;\n        result.append(separator);\n        continue;\n      }\n      if (!byPass || fileName) {\n        result.append(tokens[i]);\n        byPass = true;\n      }\n    }\n    return result.reverse().toString();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JsonUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.core.json.JsonWriteFeature;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\npublic final class JsonUtils {\n  public static final ObjectMapper OBJ_MAPPER;\n  private static final ObjectMapper UNICODE_OBJ_MAPPER;\n\n  static {\n    OBJ_MAPPER = new RestObjectMapper();\n\n    UNICODE_OBJ_MAPPER = OBJ_MAPPER.copy();\n    UNICODE_OBJ_MAPPER.enable(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature());\n  }\n\n  private JsonUtils() {\n  }\n\n  public static <T> T readValue(byte[] src, Class<T> valueType) throws IOException {\n    return OBJ_MAPPER.readValue(src, valueType);\n  }\n\n  public static <T> T readValue(InputStream is, Class<T> valueType) throws IOException {\n    return OBJ_MAPPER.readValue(is, valueType);\n  }\n\n  public static <T> T readValue(InputStream is, JavaType valueType) throws IOException {\n    return OBJ_MAPPER.readValue(is, valueType);\n  }\n\n  public static byte[] writeValueAsBytes(Object value) throws JsonProcessingException {\n    return OBJ_MAPPER.writeValueAsBytes(value);\n  }\n\n  public static String writeValueAsString(Object value) throws JsonProcessingException {\n    return OBJ_MAPPER.writeValueAsString(value);\n  }\n\n  public static String writeUnicodeValueAsString(Object value) throws JsonProcessingException {\n    return UNICODE_OBJ_MAPPER.writeValueAsString(value);\n  }\n\n  public static <T> T convertValue(Object fromValue, Class<T> toValueType) {\n    return OBJ_MAPPER.convertValue(fromValue, toValueType);\n  }\n\n  public static <T> T convertValue(Object fromValue, JavaType toValueType) {\n    return OBJ_MAPPER.convertValue(fromValue, toValueType);\n  }\n\n  public static void writeValue(OutputStream out, Object value) throws IOException {\n    OBJ_MAPPER.writeValue(out, value);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.File;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.util.jar.JarFile;\nimport java.util.jar.Manifest;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic final class JvmUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(JvmUtils.class);\n\n  // available for oracle jdk/ open jdk, and maybe others\n  @VisibleForTesting\n  static final String SUN_JAVA_COMMAND = \"sun.java.command\";\n\n  private JvmUtils() {\n  }\n\n  /**\n   *\n   * @return main class or null, never throw exception.\n   * Note that this method does not ensure that the scbMainClass can be returned correctly in the some scene.\n   */\n  public static Class<?> findMainClassByStackTrace() {\n    String mainClass = null;\n    StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();\n    if (stackTrace != null && stackTrace.length > 0) {\n      for (StackTraceElement stackTraceElement : stackTrace) {\n        if (\"main\".equals(stackTraceElement.getMethodName())) {\n          mainClass = stackTraceElement.getClassName();\n          break;\n        }\n      }\n    }\n    if (StringUtils.isEmpty(mainClass)) {\n      LOGGER.info(\"Can't found main class by stackTrace.\");\n      return null;\n    }\n    try {\n      Class<?> cls = Class.forName(mainClass);\n      LOGGER.info(\"Found main class \\\"{}\\\" by stackTrace.\", mainClass);\n      return cls;\n    } catch (Throwable e) {\n      LOGGER.warn(\"\\\"{}\\\" is not a valid class.\", mainClass, e);\n      return null;\n    }\n  }\n\n  /**\n   *\n   * @return main class or null, never throw exception.\n   * Note that this method does not ensure that the scbMainClass can be returned correctly in the some scene,like \"mvn spring-boot:run\".\n   */\n  public static Class<?> findMainClass() {\n    //Get the mainClass from the call stack\n    String mainClass = null;\n    // 1.run with java -cp ......\n    //   command is main class and args\n    // 2.run with java -jar ......\n    //   command is jar file name and args\n    String command = System.getProperty(SUN_JAVA_COMMAND);\n    if (StringUtils.isNotEmpty(command)) {\n      String mainClassOrJar = command.trim().split(\" \")[0];\n      mainClass = readFromJar(mainClassOrJar);\n    }\n    if (StringUtils.isEmpty(mainClass)) {\n      LOGGER.info(\"Can't found main class by manifest.\");\n      return null;\n    }\n    try {\n      Class<?> cls = Class.forName(mainClass);\n      LOGGER.info(\"Found main class \\\"{}\\\".\", mainClass);\n      return cls;\n    } catch (Throwable e) {\n      LOGGER.warn(\"\\\"{}\\\" is not a valid class.\", mainClass, e);\n      return null;\n    }\n  }\n\n  private static String readFromJar(String mainClassOrJar) {\n    if (!mainClassOrJar.endsWith(\".jar\")) {\n      return mainClassOrJar;\n    }\n\n    String manifestUri = \"jar:file:\" + new File(mainClassOrJar).getAbsolutePath() + \"!/\" + JarFile.MANIFEST_NAME;\n\n    try {\n      URL url = new URL(manifestUri);\n      try (InputStream inputStream = url.openStream()) {\n        Manifest manifest = new Manifest(inputStream);\n        String startClass = manifest.getMainAttributes().getValue(\"Start-Class\");\n        if (StringUtils.isNotEmpty(startClass)) {\n          return startClass;\n        }\n        return manifest.getMainAttributes().getValue(\"Main-Class\");\n      }\n    } catch (Throwable e) {\n      LOGGER.warn(\"Failed to read Main-Class from \\\"{}\\\".\", manifestUri, e);\n      return null;\n    }\n  }\n\n  /**\n   * find a property class loader to avoid null\n   */\n  public static ClassLoader correctClassLoader(ClassLoader classLoader) {\n    ClassLoader targetClassLoader = classLoader;\n    if (targetClassLoader == null) {\n      targetClassLoader = Thread.currentThread().getContextClassLoader();\n    }\n    if (targetClassLoader == null) {\n      targetClassLoader = JvmUtils.class.getClassLoader();\n    }\n    return targetClassLoader;\n  }\n\n  public static ClassLoader findClassLoader() {\n    return correctClassLoader(null);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/KeyPairEntry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\n\npublic final class KeyPairEntry {\n\n  private final PrivateKey privateKey;\n\n  private final PublicKey publicKey;\n\n  private final String publicKeyEncoded;\n\n  public KeyPairEntry(PrivateKey privateKey, PublicKey publicKey, String publicKeyEncoded) {\n    this.privateKey = privateKey;\n    this.publicKey = publicKey;\n    this.publicKeyEncoded = publicKeyEncoded;\n  }\n\n  public PrivateKey getPrivateKey() {\n    return privateKey;\n  }\n\n  public PublicKey getPublicKey() {\n    return publicKey;\n  }\n\n  public String getPublicKeyEncoded() {\n    return publicKeyEncoded;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/KeyPairUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.nio.charset.StandardCharsets;\nimport java.security.InvalidKeyException;\nimport java.security.KeyFactory;\nimport java.security.KeyPair;\nimport java.security.KeyPairGenerator;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\nimport java.security.SecureRandom;\nimport java.security.Signature;\nimport java.security.SignatureException;\nimport java.security.spec.InvalidKeySpecException;\nimport java.security.spec.X509EncodedKeySpec;\nimport java.util.Base64;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class KeyPairUtils {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(KeyPairUtils.class);\n\n  private static final String KEY_GENERATOR_ALGORITHM = LegacyPropertyFactory.getStringProperty(\n      \"servicecomb.publicKey.accessControl.keyGeneratorAlgorithm\", \"RSA\");\n\n  private static final String SIGN_ALG = LegacyPropertyFactory.getStringProperty(\n      \"servicecomb.publicKey.accessControl.signAlgorithm\", \"SHA256withRSA\");\n\n  private static final int KEY_SIZE = LegacyPropertyFactory.getIntProperty(\n      \"servicecomb.publicKey.accessControl.keySize\", 2048);\n\n  private static final Base64.Encoder encoder = Base64.getEncoder();\n\n  private static final Base64.Decoder decoder = Base64.getDecoder();\n\n  private static KeyFactory kf = null;\n\n  static {\n\n    try {\n      kf = KeyFactory.getInstance(KEY_GENERATOR_ALGORITHM);\n    } catch (NoSuchAlgorithmException e) {\n      LOGGER.error(\"init keyfactory error\");\n    }\n  }\n\n  public static KeyPairEntry generateALGKeyPair() {\n    try {\n      KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(KEY_GENERATOR_ALGORITHM);\n      keyGenerator.initialize(KEY_SIZE, new SecureRandom());\n      KeyPair keyPair = keyGenerator.generateKeyPair();\n      PublicKey pubKey = keyPair.getPublic();\n      PrivateKey privKey = keyPair.getPrivate();\n      return new KeyPairEntry(privKey, pubKey, encoder.encodeToString(pubKey.getEncoded()));\n    } catch (NoSuchAlgorithmException e) {\n      LOGGER.error(\"generate rsa keypair failed\");\n      throw new IllegalStateException(\"perhaps error occurred on jre\");\n    }\n  }\n\n  /**\n   * if has performance problem ,change Signature to ThreadLocal instance\n   */\n  public static String sign(String content, PrivateKey privateKey)\n      throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\n    Signature signature = Signature.getInstance(SIGN_ALG);\n    signature.initSign(privateKey);\n    signature.update(content.getBytes(StandardCharsets.UTF_8));\n    byte[] signByte = signature.sign();\n    return encoder.encodeToString(signByte);\n  }\n\n  /**\n   *\n   * if has performance problem ,change Signature to ThreadLocal instance\n   * @param publicKey public key after base64 encode\n   * @param sign 签名\n   * @param content original content\n   * @return verify result\n   * @throws NoSuchAlgorithmException\n   * @throws InvalidKeySpecException\n   * @throws InvalidKeyException\n   * @throws SignatureException\n   */\n  public static boolean verify(String publicKey, String sign, String content)\n      throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {\n    if (null == kf) {\n      throw new NoSuchAlgorithmException(KEY_GENERATOR_ALGORITHM + \" KeyFactory not available\");\n    }\n    byte[] bytes = decoder.decode(publicKey);\n    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);\n    PublicKey pubKey = kf.generatePublic(keySpec);\n    Signature signature = Signature.getInstance(SIGN_ALG);\n    signature.initVerify(pubKey);\n    signature.update(content.getBytes(StandardCharsets.UTF_8));\n    return signature.verify(decoder.decode(sign));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.lang.invoke.CallSite;\nimport java.lang.invoke.LambdaMetafactory;\nimport java.lang.invoke.MethodHandle;\nimport java.lang.invoke.MethodHandles;\nimport java.lang.invoke.MethodHandles.Lookup;\nimport java.lang.invoke.MethodType;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.BoolGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.BoolSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ByteGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ByteSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.CharGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.CharSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.DoubleGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.DoubleSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.FloatGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.FloatSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ShortGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ShortSetter;\n\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\n\npublic final class LambdaMetafactoryUtils {\n  private static final Lookup LOOKUP = MethodHandles.lookup();\n\n  private static final Map<Class<?>, Class<?>> GETTER_MAP = new HashMap<>();\n\n  private static final Map<Class<?>, Class<?>> SETTER_MAP = new HashMap<>();\n\n  static {\n    initGetterSetterMap();\n  }\n\n  private static void initGetterSetterMap() {\n    GETTER_MAP.put(boolean.class, BoolGetter.class);\n    GETTER_MAP.put(byte.class, ByteGetter.class);\n    GETTER_MAP.put(char.class, CharGetter.class);\n    GETTER_MAP.put(short.class, ShortGetter.class);\n    GETTER_MAP.put(int.class, IntGetter.class);\n    GETTER_MAP.put(long.class, LongGetter.class);\n    GETTER_MAP.put(float.class, FloatGetter.class);\n    GETTER_MAP.put(double.class, DoubleGetter.class);\n\n    SETTER_MAP.put(boolean.class, BoolSetter.class);\n    SETTER_MAP.put(byte.class, ByteSetter.class);\n    SETTER_MAP.put(char.class, CharSetter.class);\n    SETTER_MAP.put(short.class, ShortSetter.class);\n    SETTER_MAP.put(int.class, IntSetter.class);\n    SETTER_MAP.put(long.class, LongSetter.class);\n    SETTER_MAP.put(float.class, FloatSetter.class);\n    SETTER_MAP.put(double.class, DoubleSetter.class);\n  }\n\n  private LambdaMetafactoryUtils() {\n  }\n\n  private static Method findAbstractMethod(Class<?> functionalInterface) {\n    for (Method method : functionalInterface.getMethods()) {\n      if ((method.getModifiers() & Modifier.ABSTRACT) != 0) {\n        return method;\n      }\n    }\n\n    return null;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T createLambda(Object instance, Method instanceMethod, Class<?> functionalIntfCls) {\n    try {\n      Method intfMethod = findAbstractMethod(functionalIntfCls);\n      MethodHandle methodHandle = LOOKUP.unreflect(instanceMethod);\n\n      MethodType intfMethodType = MethodType.methodType(intfMethod.getReturnType(), intfMethod.getParameterTypes());\n      MethodType instanceMethodType = MethodType\n          .methodType(instanceMethod.getReturnType(), instanceMethod.getParameterTypes());\n      CallSite callSite = LambdaMetafactory.metafactory(\n          LOOKUP,\n          intfMethod.getName(),\n          MethodType.methodType(functionalIntfCls, instance.getClass()),\n          intfMethodType,\n          methodHandle,\n          instanceMethodType);\n\n      return (T) callSite.getTarget().bindTo(instance).invoke();\n    } catch (Throwable e) {\n      throw new IllegalStateException(\"Failed to create lambda from \" + instanceMethod, e);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T createLambda(Method instanceMethod, Class<?> functionalIntfCls) {\n    if (Modifier.isNative(instanceMethod.getModifiers())) {\n      // fix \"Failed to create lambda from public final native java.lang.Class java.lang.Object.getClass()\"\n      return null;\n    }\n    try {\n      Method intfMethod = findAbstractMethod(functionalIntfCls);\n      MethodHandle methodHandle = LOOKUP.unreflect(instanceMethod);\n\n      MethodType intfMethodType = MethodType.methodType(intfMethod.getReturnType(), intfMethod.getParameterTypes());\n\n      // the return type of fluent setter is object instead of void, but we can assume the return type is void. it doesn't matter\n      MethodType instanceMethodType = MethodType\n          .methodType(intfMethod.getReturnType(), methodHandle.type().parameterList());\n      CallSite callSite = LambdaMetafactory.metafactory(\n          LOOKUP,\n          intfMethod.getName(),\n          MethodType.methodType(functionalIntfCls),\n          intfMethodType,\n          methodHandle,\n          instanceMethodType);\n\n      return (T) callSite.getTarget().invoke();\n    } catch (Throwable e) {\n      throw new IllegalStateException(\"Failed to create lambda from \" + instanceMethod, e);\n    }\n  }\n\n  public static <T> T createGetter(Method getMethod) {\n    Class<?> getterCls = GETTER_MAP.getOrDefault(getMethod.getReturnType(), Getter.class);\n    return createLambda(getMethod, getterCls);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static Getter<Object, Object> createObjectGetter(Method getMethod) {\n    return createLambda(getMethod, Getter.class);\n  }\n\n  public static Getter<Object, Object> createObjectGetter(BeanPropertyDefinition propertyDefinition) {\n    if (propertyDefinition.hasGetter()) {\n      return createObjectGetter(propertyDefinition.getGetter().getAnnotated());\n    }\n\n    return createGetter(propertyDefinition.getField().getAnnotated());\n  }\n\n  // slower than reflect directly\n  @SuppressWarnings(\"unchecked\")\n  public static <C, F> Getter<C, F> createGetter(Field field) {\n    checkAccess(field);\n    return instance -> {\n      try {\n        return (F) field.get(instance);\n      } catch (IllegalAccessException e) {\n        throw new RuntimeException(e);\n      }\n    };\n  }\n\n  private static void checkAccess(Field field) {\n    // This check is not accurate. Most of time package visible and protected access can be ignored, so simply do this.\n    if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {\n      throw new IllegalStateException(\n          String.format(\"Can not access field, a public field or accessor is required.\"\n                  + \"Declaring class is %s, field is %s\",\n              field.getDeclaringClass().getName(),\n              field.getName()));\n    }\n  }\n\n  public static <T> T createSetter(Method setMethod) {\n    Class<?> setterCls = SETTER_MAP.getOrDefault(setMethod.getParameterTypes()[0], Setter.class);\n    return createLambda(setMethod, setterCls);\n  }\n\n  // just for avoid java 9~11 bug: https://bugs.openjdk.java.net/browse/JDK-8174983\n  // otherwise can be replaced by: createLambda(setMethod, Setter.class)\n  @SuppressWarnings(\"unchecked\")\n  public static Setter<Object, Object> createObjectSetter(Method setMethod) {\n    Object setter = createSetter(setMethod);\n    if (setter instanceof BoolSetter) {\n      return (Instance, value) -> ((BoolSetter) setter).set(Instance, (boolean) value);\n    }\n    if (setter instanceof ByteSetter) {\n      return (Instance, value) -> ((ByteSetter) setter).set(Instance, (byte) value);\n    }\n    if (setter instanceof CharSetter) {\n      return (Instance, value) -> ((CharSetter) setter).set(Instance, (char) value);\n    }\n    if (setter instanceof DoubleSetter) {\n      return (Instance, value) -> ((DoubleSetter) setter).set(Instance, (double) value);\n    }\n    if (setter instanceof FloatSetter) {\n      return (Instance, value) -> ((FloatSetter) setter).set(Instance, (float) value);\n    }\n    if (setter instanceof IntSetter) {\n      return (Instance, value) -> ((IntSetter) setter).set(Instance, (int) value);\n    }\n    if (setter instanceof LongSetter) {\n      return (Instance, value) -> ((LongSetter) setter).set(Instance, (long) value);\n    }\n    if (setter instanceof ShortSetter) {\n      return (Instance, value) -> ((ShortSetter) setter).set(Instance, (short) value);\n    }\n\n    return (Setter<Object, Object>) setter;\n  }\n\n  public static Setter<Object, Object> createObjectSetter(BeanPropertyDefinition propertyDefinition) {\n    if (propertyDefinition.hasSetter()) {\n      return createObjectSetter(propertyDefinition.getSetter().getAnnotated());\n    }\n\n    return createSetter(propertyDefinition.getField().getAnnotated());\n  }\n\n  // slower than reflect directly\n  public static <C, F> Setter<C, F> createSetter(Field field) {\n    checkAccess(field);\n    return (instance, value) -> {\n      try {\n        field.set(instance, value);\n      } catch (IllegalAccessException e) {\n        throw new RuntimeException(e);\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.function.Consumer;\n\npublic class LambdaUtils {\n\n  public static <T> Consumer<T> ignoreException(Consumer<T> consumer) {\n    return item -> {\n      try {\n        consumer.accept(item);\n      } catch (Throwable e) {\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/MimeTypesUtils.java",
    "content": "/*\n * Copyright 2014 Red Hat, Inc.\n *\n *  All rights reserved. This program and the accompanying materials\n *  are made available under the terms of the Eclipse Public License v1.0\n *  and Apache License v2.0 which accompanies this distribution.\n *\n *  The Eclipse Public License is available at\n *  http://www.eclipse.org/legal/epl-v10.html\n *\n *  The Apache License v2.0 is available at\n *  http://www.opensource.org/licenses/apache2.0.php\n *\n *  You may elect to redistribute this code under either of these licenses.\n *\n */\n\n/*\n * Forked from https://github.com/vert-x3/vertx-web/blob/927ed057ddc028eb09a168db621de3d72fd85ed4/vertx-web/src/main/java/io/vertx/ext/web/impl/Utils.java\n * Because we uses getSortedAcceptableMimeTypes method which is removed by vertx.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.regex.Pattern;\n\npublic class MimeTypesUtils {\n  private static final Pattern COMMA_SPLITTER = Pattern.compile(\" *, *\");\n\n  private static final Pattern SEMICOLON_SPLITTER = Pattern.compile(\" *; *\");\n\n  private static final Pattern EQUAL_SPLITTER = Pattern.compile(\" *= *\");\n\n  private static final Comparator<String> ACCEPT_X_COMPARATOR = (o1, o2) -> Float.compare(getQuality(o2), getQuality(o1));\n\n  private static float getQuality(String s) {\n    if (s == null) {\n      return 0;\n    }\n\n    String[] params = SEMICOLON_SPLITTER.split(s);\n    for (int i = 1; i < params.length; i++) {\n      String[] q = EQUAL_SPLITTER.split(params[1]);\n      if (\"q\".equals(q[0])) {\n        return Float.parseFloat(q[1]);\n      }\n    }\n    return 1;\n  }\n\n  public static List<String> getSortedAcceptableMimeTypes(String acceptHeader) {\n    // accept anything when accept is not present\n    if (acceptHeader == null) {\n      return Collections.emptyList();\n    }\n\n    // parse\n    String[] items = COMMA_SPLITTER.split(acceptHeader);\n    // sort on quality\n    Arrays.sort(items, ACCEPT_X_COMPARATOR);\n\n    List<String> list = new ArrayList<>(items.length);\n\n    for (String item : items) {\n      // find any ; e.g.: \"application/json;q=0.8\"\n      int space = item.indexOf(';');\n\n      if (space != -1) {\n        list.add(item.substring(0, space));\n      } else {\n        list.add(item);\n      }\n    }\n\n    return list;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/MuteExceptionUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.function.Supplier;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class MuteExceptionUtil {\n\n  public interface FunctionWithException<T, R> {\n    R apply(T t) throws Exception;\n  }\n\n  public interface FunctionWithDoubleParam<T1, T2, R> {\n    R apply(T1 t1, T2 t2) throws Exception;\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(MuteExceptionUtil.class);\n\n  public static class MuteExceptionUtilBuilder {\n\n    private String logMessage;\n\n    private Object[] customMessageParams;\n\n    public MuteExceptionUtilBuilder withLog(String message, Object... params) {\n      this.logMessage = message;\n      this.customMessageParams = params;\n      return this;\n    }\n\n    private String getLogMessage(String defaultMessage) {\n      return logMessage != null ? logMessage : defaultMessage;\n    }\n\n    public <T, R> R executeFunction(FunctionWithException<T, R> function, T t) {\n      try {\n        return function.apply(t);\n      } catch (Exception e) {\n        LOGGER.error(getLogMessage(\"execute Function failure...\"), customMessageParams, e);\n        return null;\n      }\n    }\n\n    public <T> T executeSupplier(Supplier<T> supplier) {\n      try {\n        return supplier.get();\n      } catch (Exception e) {\n        LOGGER.error(getLogMessage(\"execute Supplier failure...\"), customMessageParams, e);\n        return null;\n      }\n    }\n\n    public <T> T executeCompletableFuture(CompletableFuture<T> completableFuture) {\n      try {\n        return completableFuture.get();\n      } catch (Exception e) {\n        LOGGER.error(getLogMessage(\"execute CompletableFuture failure...\"), customMessageParams, e);\n        return null;\n      }\n    }\n\n    public <T1, T2, R> R executeFunctionWithDoubleParam(FunctionWithDoubleParam<T1, T2, R> function, T1 t1, T2 t2) {\n      try {\n        return function.apply(t1, t2);\n      } catch (Exception e) {\n        LOGGER.error(getLogMessage(\"execute FunctionWithDoubleParam failure...\"), customMessageParams, e);\n        return null;\n      }\n    }\n  }\n\n  public static MuteExceptionUtilBuilder builder() {\n    return new MuteExceptionUtilBuilder();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/PartUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.File;\nimport java.io.InputStream;\n\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.apache.servicecomb.foundation.common.part.InputStreamPart;\nimport org.apache.servicecomb.foundation.common.part.ResourcePart;\nimport org.springframework.core.io.ByteArrayResource;\nimport org.springframework.core.io.Resource;\n\nimport jakarta.servlet.http.Part;\n\npublic final class PartUtils {\n  private PartUtils() {\n  }\n\n  public static Part getSinglePart(String name, Object value) {\n    if (value == null) {\n      return null;\n    }\n\n    if (value instanceof Part) {\n      return (Part) value;\n    }\n\n    if (value instanceof InputStream) {\n      return new InputStreamPart(name, (InputStream) value);\n    }\n\n    if (value instanceof Resource) {\n      return new ResourcePart(name, (Resource) value);\n    }\n\n    if (value instanceof File) {\n      return new FilePart(name, (File) value);\n    }\n\n    if (value instanceof byte[]) {\n      return new ResourcePart(name, new ByteArrayResource((byte[]) value));\n    }\n\n    throw new IllegalStateException(\n        String.format(\"File input parameter of %s could be %s / %s / %s / byte[] or %s, but got %s.\",\n            name,\n            Part.class.getName(),\n            InputStream.class.getName(),\n            Resource.class.getName(),\n            File.class.getName(),\n            value.getClass().getName()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/ReflectUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.lang.reflect.Array;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.GenericArrayType;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport org.springframework.util.ReflectionUtils;\n\nimport com.google.common.reflect.TypeToken;\n\npublic final class ReflectUtils {\n  private ReflectUtils() {\n\n  }\n\n  public static void setField(Object instance, String fieldName, Object value) {\n    setField(instance.getClass(), instance, fieldName, value);\n  }\n\n  public static void setField(Class<?> cls, Object instance, String fieldName, Object value) {\n    Field field = ReflectionUtils.findField(cls, fieldName);\n    try {\n      field.setAccessible(true);\n      field.set(instance, value);\n    } catch (Exception e) {\n      throw new Error(e);\n    }\n  }\n\n  // 根据方法名，忽略参数查找method，调用此函数的前提是没有重载\n  public static Method findMethod(Class<?> cls, String methodName) {\n    for (Method method : cls.getMethods()) {\n      if (method.getName().equals(methodName)) {\n        return method;\n      }\n    }\n\n    return null;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> Class<T> getFieldArgument(Class<?> genericCls, String fieldName) {\n    try {\n      Type generic = FieldUtils.getField(genericCls, fieldName).getGenericType();\n      TypeToken<?> token = TypeToken.of(genericCls).resolveType(generic);\n      Type fieldType = token.getType();\n      Type argument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];\n      if (argument instanceof GenericArrayType) {\n        return (Class<T>) TypeToken.of(argument).getRawType();\n      }\n\n      return (Class<T>) argument;\n    } catch (Throwable e) {\n      throw new IllegalStateException(\"Failed to get generic argument.\", e);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T constructArrayType(Class<?> cls) {\n    return (T) Array.newInstance(cls, 0).getClass();\n  }\n\n  public static Class<?> getClassByName(String clsName) {\n    try {\n      return Class.forName(clsName);\n    } catch (ClassNotFoundException e) {\n      ClassLoader classLoader = JvmUtils.correctClassLoader(null);\n      try {\n        return classLoader.loadClass(clsName);\n      } catch (ClassNotFoundException e1) {\n        return null;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/ResourceUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.nio.file.FileSystem;\nimport java.nio.file.FileSystems;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.function.Predicate;\nimport java.util.stream.Stream;\n\npublic final class ResourceUtil {\n\n  private ResourceUtil() {\n  }\n\n  /**\n   * Search the specified location in classpath, and returns the resources with the specified suffix.\n   */\n  public static List<URI> findResourcesBySuffix(String resourceLocation, String fileNameSuffix)\n      throws IOException, URISyntaxException {\n    return findResources(resourceLocation, path -> path.toString().endsWith(fileNameSuffix));\n  }\n\n  /**\n   * Search the specified location in classpath, all the resources found are collected and returned.\n   */\n  public static List<URI> findResources(String resourceLocation) throws IOException, URISyntaxException {\n    return findResources(resourceLocation, p -> true);\n  }\n\n  /**\n   * Search the specified location in classpath, which can be a directory or the exact file location,\n   * and returns a list of URIs pointing to the matched resources.\n   *\n   * @param resourceLocation in which location the resources are searched\n   * @param filter to pick out those matched resources\n   */\n  public static List<URI> findResources(String resourceLocation, Predicate<Path> filter)\n      throws IOException, URISyntaxException {\n    ArrayList<URI> result = new ArrayList<>();\n\n    Enumeration<URL> dirURLs = JvmUtils.findClassLoader().getResources(resourceLocation);\n    while (dirURLs.hasMoreElements()) {\n      URL dirURL = dirURLs.nextElement();\n      if (\"file\".equals(dirURL.getProtocol())) {\n        Path dirPath = Paths.get(dirURL.toURI());\n        collectResourcesFromPath(dirPath, filter, result);\n        continue;\n      }\n\n      try (FileSystem fileSystem = FileSystems.newFileSystem(dirURL.toURI(), Collections.emptyMap())) {\n        Path dirPath = fileSystem.getPath(resourceLocation);\n        if (Files.exists(dirPath)) {\n          // normal jar files like : xxx.jar!/resourceLocation\n          collectResourcesFromPath(dirPath, filter, result);\n        } else {\n          // spring boot fat jar files like : xxx.jar!/BOOT-INF/!classes/resourceLocation\n          dirPath = fileSystem.getPath(\"BOOT-INF\", \"classes\", resourceLocation);\n          if (Files.exists(dirPath)) {\n            collectResourcesFromPath(dirPath, filter, result);\n          }\n        }\n      }\n    }\n\n    return result;\n  }\n\n  private static void collectResourcesFromPath(Path path, Predicate<Path> filter, Collection<URI> resources)\n      throws IOException {\n    try (Stream<Path> dirContentTraversalStream = Files.walk(path)) {\n      dirContentTraversalStream\n          .filter(filter)\n          .map(Path::toUri)\n          .forEach(resources::add);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/RestObjectMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.IOException;\n\nimport com.fasterxml.jackson.core.JsonGenerator;\nimport com.fasterxml.jackson.core.JsonParser.Feature;\nimport com.fasterxml.jackson.databind.DeserializationFeature;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.JsonSerializer;\nimport com.fasterxml.jackson.databind.MapperFeature;\nimport com.fasterxml.jackson.databind.SerializationFeature;\nimport com.fasterxml.jackson.databind.SerializerProvider;\nimport com.fasterxml.jackson.databind.module.SimpleModule;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;\n\nimport io.vertx.core.json.JsonObject;\n\npublic class RestObjectMapper extends AbstractRestObjectMapper {\n\n  private static class JsonObjectSerializer extends JsonSerializer<JsonObject> {\n    @Override\n    public void serialize(JsonObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException {\n      jgen.writeObject(value.getMap());\n    }\n  }\n\n  private static final long serialVersionUID = -8158869347066287575L;\n\n  private static final JavaType STRING_JAVA_TYPE = TypeFactory.defaultInstance().constructType(String.class);\n\n  public RestObjectMapper() {\n    super();\n    getFactory().disable(Feature.AUTO_CLOSE_SOURCE);\n    // Enable features that can tolerance errors and not enable those make more constraints for compatible reasons.\n    // Developers can use validation api to do more checks.\n    disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);\n    disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);\n    // no view annotations shouldn't be included in JSON\n    this._deserializationConfig = this._deserializationConfig.without(MapperFeature.DEFAULT_VIEW_INCLUSION);\n    this._serializationConfig = this._serializationConfig.without(MapperFeature.DEFAULT_VIEW_INCLUSION);\n    disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);\n    enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);\n    enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);\n\n    SimpleModule module = new SimpleModule();\n    // custom types\n    module.addSerializer(JsonObject.class, new JsonObjectSerializer());\n    registerModule(module);\n    registerModule(new JavaTimeModule());\n  }\n\n  public RestObjectMapper(RestObjectMapper src) {\n    super(src);\n  }\n  @Override\n  public RestObjectMapper copy() {\n    this._checkInvalidCopy(RestObjectMapper.class);\n    return new RestObjectMapper(this);\n  }\n\n  @Override\n  public String convertToString(Object value) throws Exception {\n    return convertValue(value, STRING_JAVA_TYPE);\n  }\n\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public <T> T convertValue(Object fromValue, JavaType toValueType) throws IllegalArgumentException {\n    // After jackson 2.10.*, will by pass the following check when convert value. But this is useful\n    // for java chassis applications and do not need to convert to keep performance. So add the check here.(conversion is\n    // not necessary and will cause some trouble in some user applications that depend on this)\n    if (fromValue == null) {\n      return null;\n    } else {\n      Class<?> targetType = toValueType.getRawClass();\n      if (targetType != Object.class\n          && !toValueType.hasGenericTypes()\n          && targetType.isAssignableFrom(fromValue.getClass())) {\n        return (T) fromValue;\n      }\n    }\n\n    return super.convertValue(fromValue, toValueType);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/StringBuilderUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic final class StringBuilderUtils {\n  private StringBuilderUtils() {\n  }\n\n  public static void appendLine(StringBuilder sb, String fmt, Object... args) {\n    sb.append(String.format(fmt, args)).append(\"\\n\");\n  }\n\n  public static StringBuilder deleteLast(StringBuilder sb, int count) {\n    int min = Math.min(sb.length(), count);\n    sb.setLength(sb.length() - min);\n    return sb;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/TimeUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.time.Clock;\n\npublic final class TimeUtils {\n  private TimeUtils() {\n  }\n\n  private static final Clock systemDefaultZoneClock = Clock.systemDefaultZone();\n\n  /**\n   * @return Singleton system default zone clock\n   */\n  public static Clock getSystemDefaultZoneClock() {\n    return systemDefaultZoneClock;\n  }\n\n\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/TypesUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n/**\n * common utils to convert java types.\n */\npublic class TypesUtil {\n  private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER = new HashMap<>();\n\n  static {\n    PRIMITIVE_TO_WRAPPER.put(byte.class, Byte.class);\n    PRIMITIVE_TO_WRAPPER.put(short.class, Short.class);\n    PRIMITIVE_TO_WRAPPER.put(int.class, Integer.class);\n    PRIMITIVE_TO_WRAPPER.put(long.class, Long.class);\n    PRIMITIVE_TO_WRAPPER.put(float.class, Float.class);\n    PRIMITIVE_TO_WRAPPER.put(double.class, Double.class);\n    PRIMITIVE_TO_WRAPPER.put(boolean.class, Boolean.class);\n    PRIMITIVE_TO_WRAPPER.put(char.class, Character.class);\n  }\n\n\n  private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE = new HashMap<>();\n\n  static {\n    WRAPPER_TO_PRIMITIVE.put(Byte.class, byte.class);\n    WRAPPER_TO_PRIMITIVE.put(Short.class, short.class);\n    WRAPPER_TO_PRIMITIVE.put(Integer.class, int.class);\n    WRAPPER_TO_PRIMITIVE.put(Long.class, long.class);\n    WRAPPER_TO_PRIMITIVE.put(Float.class, float.class);\n    WRAPPER_TO_PRIMITIVE.put(Double.class, double.class);\n    WRAPPER_TO_PRIMITIVE.put(Boolean.class, boolean.class);\n    WRAPPER_TO_PRIMITIVE.put(Character.class, char.class);\n  }\n\n  public static final JavaType PRIMITIVE_BYTE = TypeFactory.defaultInstance().constructType(byte.class);\n\n  public static final JavaType PRIMITIVE_SHORT = TypeFactory.defaultInstance().constructType(short.class);\n\n  public static final JavaType PRIMITIVE_INT = TypeFactory.defaultInstance().constructType(int.class);\n\n  public static final JavaType PRIMITIVE_LONG = TypeFactory.defaultInstance().constructType(long.class);\n\n  public static final JavaType PRIMITIVE_FLOAT = TypeFactory.defaultInstance().constructType(float.class);\n\n  public static final JavaType PRIMITIVE_DOUBLE = TypeFactory.defaultInstance().constructType(double.class);\n\n  public static final JavaType PRIMITIVE_BOOLEAN = TypeFactory.defaultInstance().constructType(boolean.class);\n\n  public static final JavaType PRIMITIVE_CHAR = TypeFactory.defaultInstance().constructType(char.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_BYTE = TypeFactory.defaultInstance().constructType(Byte.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_SHORT = TypeFactory.defaultInstance().constructType(Short.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_INT = TypeFactory.defaultInstance().constructType(Integer.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_LONG = TypeFactory.defaultInstance().constructType(Long.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_FLOAT = TypeFactory.defaultInstance().constructType(Float.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_DOUBLE = TypeFactory.defaultInstance().constructType(Double.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_BOOLEAN = TypeFactory.defaultInstance().constructType(Boolean.class);\n\n  public static final JavaType PRIMITIVE_WRAPPER_CHAR = TypeFactory.defaultInstance().constructType(Character.class);\n\n\n  private static final Map<JavaType, JavaType> PRIMITIVE_TO_WRAPPER_JAVATYPE = new HashMap<>();\n\n  static {\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_BYTE, PRIMITIVE_WRAPPER_BYTE);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_SHORT, PRIMITIVE_WRAPPER_SHORT);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_INT, PRIMITIVE_WRAPPER_INT);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_LONG, PRIMITIVE_WRAPPER_LONG);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_FLOAT, PRIMITIVE_WRAPPER_FLOAT);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_DOUBLE, PRIMITIVE_WRAPPER_DOUBLE);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_BOOLEAN, PRIMITIVE_WRAPPER_BOOLEAN);\n    PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_CHAR, PRIMITIVE_WRAPPER_CHAR);\n  }\n\n  private static final Map<JavaType, JavaType> WRAPPER_TO_PRIMITIVE_JAVATYPE = new HashMap<>();\n\n  static {\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_BYTE, PRIMITIVE_BYTE);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_SHORT, PRIMITIVE_SHORT);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_INT, PRIMITIVE_INT);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_LONG, PRIMITIVE_LONG);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_FLOAT, PRIMITIVE_FLOAT);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_DOUBLE, PRIMITIVE_DOUBLE);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_BOOLEAN, PRIMITIVE_BOOLEAN);\n    WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_CHAR, PRIMITIVE_CHAR);\n  }\n\n  public static Class<?> primitiveTypeToWrapper(Class<?> primitiveType) {\n    return PRIMITIVE_TO_WRAPPER.get(primitiveType);\n  }\n\n  public static Class<?> wrapperTypeToPrimitive(Class<?> wrapperType) {\n    return WRAPPER_TO_PRIMITIVE.get(wrapperType);\n  }\n\n  public static JavaType primitiveJavaTypeToWrapper(JavaType primitiveType) {\n    return PRIMITIVE_TO_WRAPPER_JAVATYPE.get(primitiveType);\n  }\n\n  public static JavaType wrapperJavaTypeToPrimitive(JavaType wrapperType) {\n    return WRAPPER_TO_PRIMITIVE_JAVATYPE.get(wrapperType);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/ArrayGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic class ArrayGetter<T> implements Getter<T[], T> {\n  private final int idx;\n\n  public ArrayGetter(int idx) {\n    this.idx = idx;\n  }\n\n  @Override\n  public T get(T[] instance) {\n    return instance[idx];\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/ArraySetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic class ArraySetter<T> implements Setter<T[], T> {\n  private final int idx;\n\n  public ArraySetter(int idx) {\n    this.idx = idx;\n  }\n\n  @Override\n  public void set(T[] instance, T value) {\n    instance[idx] = value;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/BoolGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface BoolGetter<T> {\n  boolean get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/BoolSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface BoolSetter<T> {\n  void set(T instance, boolean value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/ByteGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface ByteGetter<T> {\n  byte get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/ByteSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface ByteSetter<T> {\n  void set(T instance, byte value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/CharGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface CharGetter<T> {\n  char get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/CharSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface CharSetter<T> {\n  void set(T instance, char value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/DoubleGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface DoubleGetter<T> {\n  double get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/DoubleSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface DoubleSetter<T> {\n  void set(T instance, double value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/FloatGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface FloatGetter<T> {\n  float get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/FloatSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface FloatSetter<T> {\n  void set(T instance, float value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Getter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface Getter<C, F> {\n  F get(C instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/IntGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface IntGetter<T> {\n  int get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/IntSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface IntSetter<T> {\n  void set(T instance, int value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/LongGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface LongGetter<T> {\n  long get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/LongSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface LongSetter<T> {\n  void set(T instance, long value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\nimport java.util.Map;\n\npublic class MapGetter<K, V> implements Getter<Map<K, V>, V> {\n  private final K key;\n\n  public MapGetter(K key) {\n    this.key = key;\n  }\n\n  @Override\n  public V get(Map<K, V> instance) {\n    return instance.get(key);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/MapSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\nimport java.util.Map;\n\npublic class MapSetter<K, V> implements Setter<Map<K, V>, V> {\n  private final K key;\n\n  public MapSetter(K key) {\n    this.key = key;\n  }\n\n  @Override\n  public void set(Map<K, V> instance, V value) {\n    instance.put(key, value);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/Setter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface Setter<C, F> {\n  void set(C instance, F value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/ShortGetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface ShortGetter<T> {\n  short get(T instance);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/bean/ShortSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.bean;\n\npublic interface ShortSetter<T> {\n  void set(T instance, short value);\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/json/JavaxServletPartDeserializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils.json;\n\nimport java.io.IOException;\n\nimport com.fasterxml.jackson.core.JsonParser;\nimport com.fasterxml.jackson.databind.DeserializationContext;\nimport com.fasterxml.jackson.databind.JsonDeserializer;\n\nimport jakarta.servlet.http.Part;\n\npublic class JavaxServletPartDeserializer extends JsonDeserializer<Part> {\n  @Override\n  public Part deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {\n    final Object currentValue = p.getEmbeddedObject();\n    return (Part) currentValue;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/json/JavaxServletPartSerializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils.json;\n\nimport java.io.IOException;\n\nimport com.fasterxml.jackson.core.JsonGenerator;\nimport com.fasterxml.jackson.core.ObjectCodec;\nimport com.fasterxml.jackson.databind.SerializerProvider;\nimport com.fasterxml.jackson.databind.ser.std.StdSerializer;\nimport com.fasterxml.jackson.databind.util.TokenBuffer;\n\nimport jakarta.servlet.http.Part;\n\n// 什么情况下用？\npublic class JavaxServletPartSerializer extends StdSerializer<Part> {\n  private static final long serialVersionUID = 348443113789878443L;\n\n  public JavaxServletPartSerializer() {\n    this(null);\n  }\n\n  protected JavaxServletPartSerializer(Class<Part> t) {\n    super(t);\n  }\n\n  @Override\n  public void serialize(Part value, JsonGenerator gen, SerializerProvider provider) throws IOException {\n    ObjectCodec preservedCodec = ((TokenBuffer) gen).asParser().getCodec();\n    // set codec as null to avoid recursive dead loop\n    // JsonGenerator is instantiated for each serialization, so there should be no thread safe issue\n    gen.setCodec(null);\n    gen.writeObject(value);\n    gen.setCodec(preservedCodec);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/json/PartModule.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils.json;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\nimport com.fasterxml.jackson.databind.module.SimpleModule;\n\nimport jakarta.servlet.http.Part;\n\npublic class PartModule extends SimpleModule implements SPIOrder {\n  private static final long serialVersionUID = 4201325332650814739L;\n\n  public PartModule() {\n    super(\"javax-servlet-part\");\n\n    addSerializer(Part.class, new JavaxServletPartSerializer());\n    addDeserializer(Part.class, new JavaxServletPartDeserializer());\n  }\n\n  @Override\n  public Object getTypeId() {\n    return getModuleName();\n  }\n\n  @Override\n  public int getOrder() {\n    return Short.MAX_VALUE;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/token/Keypair4Auth.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.token;\n\nimport java.security.PrivateKey;\nimport java.security.PublicKey;\n\n/**\n * 进程级别公私钥对\n *\n */\npublic class Keypair4Auth {\n\n  private Keypair4Auth() {\n  }\n\n  private PrivateKey privateKey;\n\n  private PublicKey publicKey;\n\n  private String publicKeyEncoded;\n\n\n  public PrivateKey getPrivateKey() {\n    return privateKey;\n  }\n\n\n  public void setPrivateKey(PrivateKey privateKey) {\n    this.privateKey = privateKey;\n  }\n\n\n  public PublicKey getPublicKey() {\n    return publicKey;\n  }\n\n\n  public void setPublicKey(PublicKey publicKey) {\n    this.publicKey = publicKey;\n  }\n\n\n  public String getPublicKeyEncoded() {\n    return publicKeyEncoded;\n  }\n\n\n  public void setPublicKeyEncoded(String publicKeyEncoded) {\n    this.publicKeyEncoded = publicKeyEncoded;\n  }\n\n  public static Keypair4Auth INSTANCE = new Keypair4Auth();\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/main/resources/META-INF/mime.types",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\napplication/octet-stream                    bin\napplication/astound                         asd,asn\napplication/fastman                         lcc\napplication/java-archive                    jar\napplication/java-serialized-object          ser\napplication/java-vm                         class\napplication/mac-binhex40                    hqx\napplication/x-stuffit                       sit\napplication/mbedlet                         mbd\napplication/msword                          doc,dot,wiz,rtf\napplication/oda                             oda\napplication/pdf                             pdf\napplication/postscript                      ai,eps,ps\napplication/studiom                         smp\napplication/timbuktu                        tbt\napplication/vnd.ms-excel                    xls,xlw,xla,xlc,xlm,xlt\napplication/vnd.ms-powerpoint               ppt,pps,pot\napplication/vnd.ms-project                  mpp\napplication/winhlp                          hlp\napplication/x-javascript                    js\napplication/x-javascript;charset=UTF-8      jsu\napplication/x-java-jnlp-file                jnlp\napplication/x-aim                           aim\napplication/x-asap                          asp\napplication/x-csh                           csh\napplication/x-dvi                           dvi\napplication/x-earthtime                     etc\napplication/x-envoy                         evy\napplication/x-gtar                          gtar\napplication/x-cpio                          cpio\napplication/x-hdf                           hdf\napplication/x-latex                         latex\napplication/x-javascript-config             jsc\napplication/x-maker                         fm\napplication/x-mif                           mif,mi\napplication/x-mocha                         mocha,moc\napplication/x-msaccess                      mdb\napplication/x-mscardfile                    crd\napplication/x-msclip                        clp\napplication/x-msmediaview                   m13,m14\napplication/x-msmetafile                    wmf\napplication/x-msmoney                       mny\napplication/x-mspublisher                   pub\napplication/x-msschedule                    scd\napplication/x-msterminal                    trm\napplication/x-mswrite                       wri\napplication/x-NET-Install                   ins\napplication/x-netcdf                        nc,cdf\napplication/x-ns-proxy-autoconfig           proxy\napplication/x-salsa                         slc\napplication/x-sh                            sh\napplication/x-shar                          shar\napplication/x-sprite                        spr,sprite\napplication/x-tar                           tar\napplication/x-tcl                           tcl\napplication/x-perl                          pl\napplication/x-tex                           tex\napplication/x-texinfo                       texinfo,texi\napplication/x-timbuktu                      tbp\napplication/x-tkined                        tki,tkined\napplication/x-troff-man                     man\napplication/x-troff-me                      me\napplication/x-troff-ms                      ms\napplication/x-troff                         t,tr,roff\napplication/x-wais-source                   src\napplication/zip                             zip\napplication/pre-encrypted                   enc\napplication/x-pkcs7-crl                     crl\napplication/x-fortezza-ckl                  ckl\napplication/xml-dtd                         dtd\n\naudio/basic                                 au,snd\naudio/echospeech                            es,esl\naudio/midi                                  midi,mid\naudio/x-aiff                                aif,aiff,aifc\naudio/x-wav                                 wav\naudio/x-pn-realaudio                        ra,ram\naudio/x-pac                                 pac\naudio/x-epac                                pae\naudio/x-liveaudio                           lam\n\ndrawing/x-dwf                               dwf\n\nimage/fif                                   fif\nimage/x-icon                                ico\nimage/gif                                   gif\nimage/ief                                   ief\nimage/ifs                                   ifs\nimage/jpeg                                  jpeg,jpg,jpe,jfif,pjpeg,pjp\nimage/png                                   png\nimage/tiff                                  tiff,tif\nimage/vnd                                   dwg,svf\nimage/wavelet                               wi\nimage/bmp                                   bmp\nimage/x-photo-cd                            pcd\nimage/x-cmu-raster                          ras\nimage/x-portable-anymap                     pnm\nimage/x-portable-bitmap                     pbm\nimage/x-portable-graymap                    pgm\nimage/x-portable-pixmap                     ppm\nimage/x-rgb                                 rgb\nimage/x-xbitmap                             xbm\nimage/x-xpixmap                             xpm\nimage/x-xwindowdump                         xwd\n\ntext/css                                    css\n\ntext/html                                   htm,html\ntext/plain                                  txt\ntext/richtext                               rtx\ntext/tab-separated-values                   tsv\ntext/x-setext                               etx\ntext/x-speech                               talk\ntext/xml                                    xml\ntext/xul                                    xul\n\nvideo/isivideo                              fvi\nvideo/mpeg                                  mpeg,mpg,mpe,mpv,vbs,mpegv\nvideo/x-mpeg2                               mpv2,mp2v\nvideo/msvideo                               avi\nvideo/quicktime                             qt,mov,moov\nvideo/vivo                                  viv,vivo\nvideo/wavelet                               wv\nvideo/x-sgi-movie                           movie\n\nx-world/x-svr                               svr\nx-world/x-vrml                              wrl\nx-world/x-vrt                               vrt\n\nx-conference/x-cooltalk                     ice\n\nmagnus-internal/imagemap                    map\nmagnus-internal/parsed-html                 shtml\nmagnus-internal/cgi                         cgi,exe,bat\n\napplication/x-x509-ca-cert                  cacert\n\napplication/x-x509-server-cert              scert\napplication/x-x509-user-cert                ucert\napplication/x-x509-email-cert               ecert\n"
  },
  {
    "path": "foundations/foundation-common/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.common.encrypt.Encryption",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.foundation.common.encrypt.NoEncryption\n"
  },
  {
    "path": "foundations/foundation-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.foundation.auth.FoundationCommonAuthConfiguration\norg.apache.servicecomb.foundation.common.event.EventManager\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/DynamicObjectTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Test;\n\nimport io.vertx.core.json.Json;\nimport io.vertx.core.json.jackson.DatabindCodec;\n\nclass DynamicObjectTest {\n  @Test\n  void should_support_json_encode_decode() {\n    Map<String, Object> map = new HashMap<>();\n    map.put(\"k\", \"v\");\n\n    DynamicObject dynamicObject = DatabindCodec.mapper().convertValue(map, DynamicObject.class);\n\n    assertThat(dynamicObject.getDynamic()).isNotSameAs(map);\n    assertThat(dynamicObject.getDynamic()).isEqualTo(map);\n    assertThat(Json.encode(dynamicObject)).isEqualTo(\"{\\\"k\\\":\\\"v\\\"}\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/base/DynamicEnumTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.base;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport org.junit.jupiter.api.Test;\n\nimport com.fasterxml.jackson.annotation.JsonCreator;\n\nimport io.vertx.core.json.Json;\nimport io.vertx.core.json.jackson.DatabindCodec;\n\nclass DynamicEnumTest {\n  static final String UNKNOWN_COLOR = \"\\\"UNKNOWN-COLOR\\\"\";\n\n  static class Color extends DynamicEnum<String> {\n    public static final Color RED = new Color(\"RED\");\n\n    public static final Color BLUE = new Color(\"BLUE\");\n\n    private static final DynamicEnumCache<Color> CACHE = new DynamicEnumCache<>(Color.class);\n\n    public Color(String value) {\n      super(value);\n    }\n\n    @JsonCreator\n    public static Color fromValue(String value) {\n      return CACHE.fromValue(value);\n    }\n  }\n\n  static class ColorModel {\n    public Color color;\n  }\n\n  @Test\n  void should_be_dynamic_for_unknown_value() {\n    Color color = Color.fromValue(\"unknown\");\n    assertThat(color.isDynamic()).isTrue();\n    assertThat(color.isStatic()).isFalse();\n  }\n\n  @Test\n  void should_be_static_for_known_value() {\n    Color color = Color.fromValue(\"RED\");\n    assertThat(color.isDynamic()).isFalse();\n    assertThat(color.isStatic()).isTrue();\n  }\n\n  @Test\n  void should_encode() {\n    assertThat(Json.encode(Color.RED)).isEqualTo(\"\\\"RED\\\"\");\n  }\n\n  @Test\n  void should_be_null_when_convert_from_null() {\n    assertThat(DatabindCodec.mapper().convertValue(null, Color.class)).isNull();\n  }\n\n  @Test\n  void should_be_null_when_decode_from_null() {\n    ColorModel model = Json.decodeValue(Json.encode(new ColorModel()), ColorModel.class);\n    assertThat(model.color).isNull();\n  }\n\n  @Test\n  void should_decode_from_known_value() {\n    Color color = Json.decodeValue(Json.encode(Color.RED), Color.class);\n    assertThat(color).isEqualTo(Color.RED);\n  }\n\n  @Test\n  void should_decode_from_unknown_value() {\n    Color color = Json.decodeValue(UNKNOWN_COLOR, Color.class);\n    assertThat(color).isEqualTo(Color.fromValue(\"UNKNOWN-COLOR\"));\n  }\n\n  @Test\n  void should_not_cache_unknown_value() {\n    Color value1 = Json.decodeValue(UNKNOWN_COLOR, Color.class);\n    Color value2 = Json.decodeValue(UNKNOWN_COLOR, Color.class);\n    assertThat(value1).isNotSameAs(value2);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/cache/TestVersionedCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.cache;\n\nimport java.util.Collections;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport mockit.Deencapsulation;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestVersionedCache {\n  private static final AtomicInteger VERSION = Deencapsulation.getField(VersionedCache.class, \"VERSION\");\n\n  @Test\n  public void construct() {\n    VersionedCache cache = new VersionedCache();\n\n    Assertions.assertNull(cache.data());\n    Assertions.assertNull(cache.arrayData());\n    Assertions.assertTrue(cache.isEmpty());\n  }\n\n  @Test\n  public void autoCacheVersion() {\n    VersionedCache cache = new VersionedCache().autoCacheVersion();\n\n    Assertions.assertEquals(VERSION.get(), cache.cacheVersion());\n  }\n\n  @Test\n  public void setCacheVersion() {\n    VersionedCache parent = new VersionedCache().autoCacheVersion();\n    VersionedCache cache = new VersionedCache().cacheVersion(parent.cacheVersion());\n\n    Assertions.assertEquals(parent.cacheVersion(), cache.cacheVersion());\n  }\n\n  @Test\n  public void setName() {\n    VersionedCache cache = new VersionedCache().name(\"n\");\n\n    Assertions.assertEquals(\"n\", cache.name());\n  }\n\n  @Test\n  public void setSubName() {\n    VersionedCache parent = new VersionedCache().name(\"parent\");\n    VersionedCache child = new VersionedCache().subName(parent, \"child\");\n\n    Assertions.assertEquals(\"parent/child\", child.name());\n  }\n\n  @Test\n  public void setMapData() {\n    VersionedCache cache = new VersionedCache().data(Collections.emptyMap());\n\n    Assertions.assertSame(Collections.emptyMap(), cache.data());\n    Assertions.assertSame(Collections.emptyMap(), cache.mapData());\n    Assertions.assertTrue(cache.isEmpty());\n\n    cache.data(Collections.singletonMap(\"k\", \"v\"));\n    Assertions.assertFalse(cache.isEmpty());\n  }\n\n  @Test\n  public void setCollectionData() {\n    VersionedCache cache = new VersionedCache().data(Collections.emptyList());\n\n    Assertions.assertSame(Collections.emptyList(), cache.data());\n    Assertions.assertSame(Collections.emptyList(), cache.collectionData());\n    Assertions.assertTrue(cache.isEmpty());\n\n    cache.data(Collections.singletonList(\"v\"));\n    Assertions.assertFalse(cache.isEmpty());\n  }\n\n  @Test\n  public void setArrayData() {\n    Object[] array = Collections.emptyList().toArray();\n    VersionedCache cache = new VersionedCache().data(array);\n\n    Assertions.assertSame(array, cache.data());\n    Assertions.assertSame(array, cache.arrayData());\n    Assertions.assertTrue(cache.isEmpty());\n\n    cache.data(new String[] {\"a\", \"b\"});\n    Assertions.assertFalse(cache.isEmpty());\n  }\n\n  @Test\n  public void setCommonData() {\n    VersionedCache cache = new VersionedCache().data(null);\n\n    Assertions.assertNull(cache.data());\n    Assertions.assertNull(cache.arrayData());\n    Assertions.assertTrue(cache.isEmpty());\n\n    cache.data(\"a\");\n    Assertions.assertFalse(cache.isEmpty());\n  }\n\n  @Test\n  public void isExpired() {\n    VersionedCache cacheOld = new VersionedCache().autoCacheVersion();\n    VersionedCache cacheNew = new VersionedCache().autoCacheVersion();\n\n    Assertions.assertTrue(cacheOld.isExpired(cacheNew));\n    Assertions.assertFalse(cacheOld.isExpired(cacheOld));\n    Assertions.assertFalse(cacheNew.isExpired(cacheOld));\n  }\n\n  @Test\n  public void isSameVersion() {\n    VersionedCache cacheOld = new VersionedCache().autoCacheVersion();\n    VersionedCache cacheNew = new VersionedCache().autoCacheVersion();\n    VersionedCache cacheSame = new VersionedCache().cacheVersion(cacheNew.cacheVersion());\n\n    Assertions.assertFalse(cacheOld.isSameVersion(cacheNew));\n    Assertions.assertTrue(cacheSame.isSameVersion(cacheNew));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/concurrency/RunnableWrapperTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.concurrency;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.ScheduledThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class RunnableWrapperTest {\n  /**\n   * {@link SuppressedRunnableWrapper} should ensure that any {@link Throwable} thrown from {@link Runnable}\n   * should not interrupt the scheduled tasks.\n   */\n  @Test\n  public void run() {\n    ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);\n    CountDownLatch countDownLatch = new CountDownLatch(3);\n\n    try {\n      scheduledThreadPoolExecutor.scheduleAtFixedRate(\n          new SuppressedRunnableWrapper(\n              () -> {\n                countDownLatch.countDown();\n                switch ((int) countDownLatch.getCount()) {\n                  case 2:\n                    throw new Error(\"Normal case, this is a mocked error\");\n                  case 1:\n                    throw new IllegalStateException(\"Normal case, this is a mocked exception\");\n                  default:\n                }\n              }\n          ),\n          1,\n          1,\n          TimeUnit.MILLISECONDS);\n\n      countDownLatch.await(1, TimeUnit.SECONDS);\n    } catch (InterruptedException e) {\n      System.out.println(\"get an InterruptedException! \" + e.getMessage());\n      e.printStackTrace();\n    } finally {\n      scheduledThreadPoolExecutor.shutdownNow();\n    }\n\n    Assertions.assertEquals(0, countDownLatch.getCount());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/config/BeanProp.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.config;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class BeanProp {\n  @JsonProperty(value = \"1.2\")\n  private String test;\n\n  public String getTest() {\n    return test;\n  }\n\n  public void setTest(String test) {\n    this.test = test;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/encrypt/TestEncryptions.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.encrypt;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestEncryptions {\n  static class MyEncryption implements Encryption {\n\n    @Override\n    public char[] decode(char[] encrypted, String tags) {\n      if (tags == null) {\n        return null;\n      }\n      return encrypted;\n    }\n\n    @Override\n    public char[] encode(char[] plain, String tags) {\n      if (tags == null) {\n        return null;\n      }\n      return plain;\n    }\n  }\n\n  @Test\n  public void testEncryptions() {\n    Assertions.assertNull(Encryptions.decode((String) null, \"\"));\n    Assertions.assertEquals(Encryptions.decode(\"abcd\", \"\"), \"abcd\");\n    Assertions.assertEquals(Encryptions.decode(\"abcd\", null), \"abcd\");\n    Assertions.assertNull(Encryptions.encode((String) null, \"\"));\n    Assertions.assertEquals(Encryptions.encode(\"abcd\", \"\"), \"abcd\");\n    Assertions.assertEquals(Encryptions.decode(\"abcd\", null), \"abcd\");\n  }\n\n  @Test\n  public void testEncryptionsMy() {\n    Encryption old = Encryptions.getEncryption();\n    Encryptions.setEncryption(new MyEncryption());\n    Assertions.assertNull(Encryptions.decode((String) null, \"\"));\n    Assertions.assertEquals(Encryptions.decode(\"abcd\", \"\"), \"abcd\");\n    Assertions.assertNull(Encryptions.decode(\"abcd\", null));\n    Assertions.assertNull(Encryptions.encode((String) null, \"\"));\n    Assertions.assertEquals(Encryptions.encode(\"abcd\", \"\"), \"abcd\");\n    Assertions.assertNull(Encryptions.encode(\"abcd\", null));\n    Encryptions.setEncryption(old);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventBus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.event;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\nimport org.junit.jupiter.api.Test;\n\npublic class TestEventBus {\n  private final EventBus eventBus = new SimpleEventBus();\n\n  private final List<Object> events = new ArrayList<>();\n\n  public static class SubscriberForTest {\n    private final List<Object> events;\n\n    public SubscriberForTest(List<Object> events) {\n      this.events = events;\n    }\n    @Subscribe\n    @AllowConcurrentEvents\n    public void s1(Integer event) {\n      events.add(event);\n    }\n\n    @Subscribe\n    public void s2(String event) {\n      events.add(event);\n    }\n  }\n\n  public static class SubscriberWithOrderForTest {\n    private final List<Object> events;\n\n    public SubscriberWithOrderForTest(List<Object> events) {\n      this.events = events;\n    }\n\n    @Subscribe\n    @SubscriberOrder(100)\n    public void s1(String event) {\n      events.add(\"s1:\" + event);\n    }\n\n    @Subscribe\n    @SubscriberOrder(-100)\n    public void s2(String event) {\n      events.add(\"s2:\" + event);\n    }\n  }\n\n  @Test\n  public void order() {\n    eventBus.register(new SubscriberWithOrderForTest(events));\n\n    eventBus.post(\"value\");\n    MatcherAssert.assertThat(events, Matchers.contains(\"s2:value\", \"s1:value\"));\n  }\n\n  @Test\n  public void unregister() {\n    Object obj = new SubscriberForTest(events);\n\n    eventBus.register(obj);\n    eventBus.unregister(obj);\n  }\n\n  @Test\n  public void oneSubscriber() {\n    Object obj = new SubscriberForTest(events);\n\n    eventBus.register(obj);\n\n    eventBus.post(0.1);\n    eventBus.post(1);\n    eventBus.post(\"str\");\n    MatcherAssert.assertThat(events, Matchers.contains(1, \"str\"));\n\n    eventBus.unregister(obj);\n\n    events.clear();\n    eventBus.post(0.1);\n    eventBus.post(1);\n    eventBus.post(\"str\");\n    MatcherAssert.assertThat(events, Matchers.empty());\n  }\n\n  @Test\n  public void twoSubscriber() {\n    Object obj1 = new SubscriberForTest(events);\n    Object obj2 = new SubscriberForTest(events);\n\n    eventBus.register(obj1);\n    eventBus.register(obj2);\n\n    eventBus.post(0.1);\n    eventBus.post(1);\n    eventBus.post(\"str\");\n    MatcherAssert.assertThat(events, Matchers.contains(1, 1, \"str\", \"str\"));\n\n    events.clear();\n    eventBus.unregister(obj1);\n    eventBus.post(0.1);\n    eventBus.post(1);\n    eventBus.post(\"str\");\n    MatcherAssert.assertThat(events, Matchers.contains(1, \"str\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.event;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\n\nimport com.google.common.eventbus.Subscribe;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestEventManager {\n  private int objCount = 0;\n\n  private int iCount = 0;\n\n  public void test(Object listener) {\n    EventManager.register(listener);\n    EventManager.post(\"a\");\n    EventManager.post(1);\n    Assertions.assertEquals(2, objCount);\n    Assertions.assertEquals(1, iCount);\n\n    EventManager.unregister(listener);\n    EventManager.post(\"a\");\n    EventManager.post(1);\n    Assertions.assertEquals(2, objCount);\n    Assertions.assertEquals(1, iCount);\n  }\n\n  @Test\n  public void normalListener() {\n    LogCollector collector = new LogCollector();\n\n    test(this);\n    Assertions.assertTrue(collector.getEvents().isEmpty()); // ensure no warning logs\n    collector.tearDown();\n  }\n\n  @Test\n  public void anonymousListener() {\n    LogCollector collector = new LogCollector();\n    Object listener = new Object() {\n      @Subscribe\n      private void onObject(Object obj) {\n        objCount++;\n      }\n\n      @Subscribe\n      void onInt(Integer obj) {\n        iCount++;\n      }\n    };\n    try {\n      test(listener);\n      Assertions.fail();\n    } catch (IllegalStateException e) {\n      Assertions.assertTrue(true);\n    }\n\n    collector.tearDown();\n  }\n\n  @Test\n  public void anonymousListenerPublic() {\n    LogCollector collector = new LogCollector();\n    Object listener = new Object() {\n      @Subscribe\n      public void onObject(Object obj) {\n        objCount++;\n      }\n\n      @Subscribe\n      public void onInt(Integer obj) {\n        iCount++;\n      }\n    };\n    try {\n      test(listener);\n      Assertions.fail();\n    } catch (IllegalStateException e) {\n      Assertions.assertTrue(true);\n    }\n\n    // ensure logs: \"LOGGER.warn(\"Failed to create lambda for method: {}, fallback to reflect.\", method, throwable);\"\n    Assertions.assertFalse(collector.getEvents().isEmpty());\n    collector.tearDown();\n  }\n\n  @Subscribe\n  public void onObject(Object obj) {\n    objCount++;\n  }\n\n  @Subscribe\n  public void onInt(Integer obj) {\n    iCount++;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.http;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.Status.Family;\n\npublic class TestHttpStatus {\n  @Test\n  public void testIsSuccessCode() {\n    Assertions.assertTrue(HttpStatus.isSuccess(200));\n    Assertions.assertFalse(HttpStatus.isSuccess(300));\n  }\n\n  @Test\n  public void testIsSuccessType() {\n    Assertions.assertTrue(HttpStatus.isSuccess(Status.OK));\n    Assertions.assertFalse(HttpStatus.isSuccess(Status.BAD_REQUEST));\n  }\n\n  @Test\n  public void testGetStatusCode() {\n    HttpStatus status = new HttpStatus(200, \"ok\");\n    Assertions.assertEquals(200, status.getStatusCode());\n  }\n\n  @Test\n  public void testGetFamily() {\n    HttpStatus status = new HttpStatus(200, \"ok\");\n    Assertions.assertEquals(Family.familyOf(200), status.getFamily());\n  }\n\n  @Test\n  public void testGetReasonPhrase() {\n    HttpStatus status = new HttpStatus(200, \"ok\");\n    Assertions.assertEquals(\"ok\", status.getReasonPhrase());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpStatusUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.http;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestHttpStatusUtils {\n  HttpStatusManager mgr = new HttpStatusManager();\n\n  StatusType st;\n\n  @Test\n  public void testStandard() {\n    st = HttpStatusUtils.getOrCreateByStatusCode(200);\n    Assertions.assertEquals(200, st.getStatusCode());\n  }\n\n  @Test\n  public void testNotStandard() {\n    st = mgr.getOrCreateByStatusCode(250);\n    Assertions.assertEquals(250, st.getStatusCode());\n  }\n\n  @Test\n  public void testAddRepeat() {\n    IllegalStateException illegalStateException = Assertions.assertThrows(IllegalStateException.class,\n            () -> mgr.addStatusType(new HttpStatus(200, \"ok\")));\n    Assertions.assertEquals(\"repeated status code: 200\", illegalStateException.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.http;\n\nimport java.net.URISyntaxException;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestHttpUtils {\n\n  @Test\n  public void parseParamFromHeaderValue_normal() {\n    Assertions.assertEquals(\"a\", HttpUtils.parseParamFromHeaderValue(\"key1=a;key2=b\", \"key1\"));\n    Assertions.assertEquals(\"b\", HttpUtils.parseParamFromHeaderValue(\"key1=a;key2= b\", \"key2\"));\n    Assertions.assertEquals(\"b\", HttpUtils.parseParamFromHeaderValue(\"key1=a; key2=b\", \"key2\"));\n    Assertions.assertEquals(\"a\", HttpUtils.parseParamFromHeaderValue(\"key1=\\\"a\\\";key2=\\\"b\\\"\", \"key1\"));\n    Assertions.assertEquals(\"b\", HttpUtils.parseParamFromHeaderValue(\"key1=\\\"a\\\";key2=\\\" b\\\"\", \"key2\"));\n    Assertions.assertEquals(\"b\", HttpUtils.parseParamFromHeaderValue(\"key1=\\\"a\\\"; key2=\\\"b\\\"\", \"key2\"));\n    Assertions.assertEquals(\"b c.txt\", HttpUtils.parseParamFromHeaderValue(\"key1=\\\"a\\\"; key2=\\\"b c.txt\\\"\", \"key2\"));\n  }\n\n  @Test\n  public void parseParamFromHeaderValue_null() {\n    Assertions.assertNull(HttpUtils.parseParamFromHeaderValue(null, \"key\"));\n    Assertions.assertNull(HttpUtils.parseParamFromHeaderValue(\"key1=a; key2=b\", \"key\"));\n  }\n\n  @Test\n  public void parseParamFromHeaderValue_emptyStr() {\n    Assertions.assertEquals(\"\", HttpUtils.parseParamFromHeaderValue(\"key1=a; key2=\", \"key2\"));\n  }\n\n  @Test\n  public void uriEncode_null() {\n    Assertions.assertEquals(\"\", HttpUtils.uriEncodePath(null));\n  }\n\n  @Test\n  public void uriDecode_null() {\n    Assertions.assertNull(HttpUtils.uriDecodePath(null));\n  }\n\n  @Test\n  public void uriEncode_chineseAndSpace() {\n    String encoded = HttpUtils.uriEncodePath(\"测 试\");\n    Assertions.assertEquals(\"%E6%B5%8B%20%E8%AF%95\", encoded);\n    Assertions.assertEquals(\"测 试\", HttpUtils.uriDecodePath(encoded));\n  }\n\n  @Test\n  public void uriEncode_failed() {\n    IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class,\n            () -> HttpUtils.uriEncodePath(\":\"));\n    Assertions.assertEquals(\"uriEncode failed, path=\\\":\\\".\", illegalArgumentException.getMessage());\n    Assertions.assertTrue(illegalArgumentException.getCause() instanceof URISyntaxException);\n  }\n\n  @Test\n  public void uriEncode_plus() {\n    String encoded = HttpUtils.uriEncodePath(\"a+b\");\n    Assertions.assertEquals(\"a+b\", encoded);\n    Assertions.assertEquals(\"a+b\", HttpUtils.uriDecodePath(encoded));\n  }\n\n  @Test\n  public void uriEncode_encodeEntirePath() {\n    String encoded = HttpUtils.uriEncodePath(\"a%%'+b/def\");\n    Assertions.assertEquals(\"a%25%25'+b/def\", encoded);\n  }\n\n  @Test\n  public void pathParamEncode() {\n    Assertions.assertEquals(\"a+b\", HttpUtils.encodePathParam(\"a+b\"));\n    Assertions.assertEquals(\"a%25b\", HttpUtils.encodePathParam(\"a%b\"));\n    Assertions.assertEquals(\"a%25%25b\", HttpUtils.encodePathParam(\"a%%b\"));\n    Assertions.assertEquals(\"%3C%20%3E'%22%EF%BC%88)&%2F%20%20\", HttpUtils.encodePathParam(\"< >'\\\"（)&/  \"));\n    Assertions.assertEquals(\"%E6%B5%8B%20%E8%AF%95\", HttpUtils.encodePathParam(\"测 试\"));\n  }\n\n  /**\n   * SafeChar: the characters that are not encoded.\n   * This test is to show those safe chars excepting 0..9, a..z and A..Z\n   */\n  @Test\n  public void pathParamEncode_SafeChar() {\n    Assertions.assertEquals(\"-._~!$'()*,;&=@:+\", HttpUtils.encodePathParam(\"-._~!$'()*,;&=@:+\"));\n  }\n\n  @Test\n  public void uriDecode_failed() {\n    IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class,\n            () -> HttpUtils.uriDecodePath(\":\"));\n    Assertions.assertEquals(\"uriDecode failed, path=\\\":\\\".\", illegalArgumentException.getMessage());\n    Assertions.assertTrue(illegalArgumentException.getCause() instanceof URISyntaxException);\n  }\n\n  @Test\n  public void parseFileNameFromHeaderValue() {\n    String fileName = \"测 试.txt\";\n    String encoded = HttpUtils.uriEncodePath(fileName);\n    Assertions.assertEquals(fileName, HttpUtils.parseFileNameFromHeaderValue(\"xx;filename=\" + encoded));\n  }\n\n  @Test\n  public void parseFileNameFromHeaderValue_defaultName() {\n    Assertions.assertEquals(\"default\", HttpUtils.parseFileNameFromHeaderValue(\"xx\"));\n  }\n\n  @Test\n  public void parseFileNameFromHeaderValue_ignorePath() {\n    Assertions.assertEquals(\"a.txt\", HttpUtils.parseFileNameFromHeaderValue(\"xx;filename=../../a.txt\"));\n  }\n\n  @Test\n  public void getCharsetFromContentType_noContentType() {\n    String character = HttpUtils.getCharsetFromContentType(null);\n\n    Assertions.assertNull(character);\n  }\n\n  @Test\n  public void getCharsetFromContentType_noCharset() {\n    String character = HttpUtils.getCharsetFromContentType(MediaType.APPLICATION_JSON);\n\n    Assertions.assertNull(character);\n  }\n\n  @Test\n  public void getCharsetFromContentType_noSemicolonEnd() {\n    String character = HttpUtils.getCharsetFromContentType(MediaType.APPLICATION_JSON + \";charset=utf-8\");\n\n    Assertions.assertEquals(\"utf-8\", character);\n  }\n\n  @Test\n  public void getCharsetFromContentType_semicolonEnd() {\n    String character = HttpUtils.getCharsetFromContentType(MediaType.APPLICATION_JSON + \";charset=utf-8;\");\n\n    Assertions.assertEquals(\"utf-8\", character);\n  }\n\n  @Test\n  public void getCharsetFromContentType_needTrim() {\n    String character = HttpUtils.getCharsetFromContentType(MediaType.APPLICATION_JSON + \";charset= utf-8 ;\");\n\n    Assertions.assertEquals(\"utf-8\", character);\n  }\n\n  @Test\n  public void getCharsetFromContentType_quotationMarks() {\n    String character = HttpUtils.getCharsetFromContentType(MediaType.APPLICATION_JSON + \";charset=\\\"utf-8\\\";\");\n\n    Assertions.assertEquals(\"utf-8\", character);\n  }\n\n  @Test\n  public void getCharsetFromContentType_quotationMarks_needTrim() {\n    String character = HttpUtils.getCharsetFromContentType(MediaType.APPLICATION_JSON + \";charset=\\\" utf-8 \\\";\");\n\n    Assertions.assertEquals(\"utf-8\", character);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestIpPort.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.net;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestIpPort {\n  @Test\n  public void testIpPort() {\n    IpPort inst1 = new IpPort();\n    inst1.setHostOrIp(\"localhost\");\n    inst1.setPort(3333);\n    IpPort inst2 = new IpPort(\"localhost\", 3333);\n    Assertions.assertEquals(inst1.getHostOrIp(), inst2.getHostOrIp());\n    Assertions.assertEquals(inst1.getPort(), inst2.getPort());\n    Assertions.assertEquals(inst1.getSocketAddress().getHostName(), inst2.getSocketAddress().getHostName());\n    Assertions.assertEquals(inst1, inst1);\n    Assertions.assertEquals(inst1, inst2);\n    Assertions.assertEquals(inst1.toString(), \"localhost:3333\");\n    Assertions.assertNotEquals(inst1, new Object());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestNetUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.net;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.ServerSocket;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.function.Consumer;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport mockit.Deencapsulation;\n\npublic class TestNetUtils {\n  @Test\n  public void testFindProperHostAddress() {\n    NetUtils.resetHostName();\n    String result = NetUtils.getHostName();\n    System.out.println(result);\n    Assertions.assertNotNull(result);\n\n    result = NetUtils.getHostAddress();\n    System.out.println(result);\n    Assertions.assertNotNull(result);\n\n    result = NetUtils.getIpv6HostAddress();\n    System.out.println(result);\n    if (result != null) {\n      Assertions.assertFalse(result.contains(\"%\"));\n    }\n  }\n\n  @Test\n  public void testIpPort() {\n    IpPort oIPPort = new IpPort(\"10.145.154.45\", 8080);\n    Assertions.assertEquals(\"10.145.154.45\", oIPPort.getHostOrIp());\n    Assertions.assertEquals(8080, oIPPort.getPort());\n    oIPPort.setPort(9090);\n    Assertions.assertEquals(9090, oIPPort.getPort());\n    Assertions.assertNotEquals(null, oIPPort.getSocketAddress());\n  }\n\n  @Test\n  public void testNetUtils() {\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPort(\"127.0.0.1:8080\").getHostOrIp());\n    Assertions.assertEquals(8080, NetUtils.parseIpPort(\"127.0.0.1:8080\").getPort());\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPort(\"127.0.0.1\").getHostOrIp());\n    Assertions.assertEquals(-1, NetUtils.parseIpPort(\"127.0.0.1\").getPort());\n    Assertions.assertNull(NetUtils.parseIpPort((String) null));\n    Assertions.assertNull(NetUtils.parseIpPortFromURI(null));\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPortFromURI(\"rest://127.0.0.1:8080\").getHostOrIp());\n    Assertions.assertEquals(8080, NetUtils.parseIpPortFromURI(\"http://127.0.0.1:8080\").getPort());\n    Assertions.assertEquals(80, NetUtils.parseIpPortFromURI(\"http://127.0.0.1\").getPort());\n    Assertions.assertEquals(8080, NetUtils.parseIpPortFromURI(\"https://127.0.0.1:8080\").getPort());\n    Assertions.assertEquals(443, NetUtils.parseIpPortFromURI(\"https://127.0.0.1\").getPort());\n\n    Assertions.assertEquals(30000, NetUtils.parseIpPort(\"http\", \"127.0.0.1:30000\").getPort());\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPort(\"http\", \"127.0.0.1:30000\").getHostOrIp());\n    Assertions.assertEquals(30000, NetUtils.parseIpPort(\"https\", \"127.0.0.1:30000\").getPort());\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPort(\"https\", \"127.0.0.1:30000\").getHostOrIp());\n    Assertions.assertEquals(80, NetUtils.parseIpPort(\"http\", \"127.0.0.1\").getPort());\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPort(\"http\", \"127.0.0.1\").getHostOrIp());\n    Assertions.assertEquals(443, NetUtils.parseIpPort(\"https\", \"127.0.0.1\").getPort());\n    Assertions.assertEquals(\"127.0.0.1\", NetUtils.parseIpPort(\"https\", \"127.0.0.1\").getHostOrIp());\n    Assertions.assertNull(NetUtils.parseIpPort(\"http\", null));\n\n    checkException(v -> NetUtils.parseIpPort(\"127.0.0.18080\"));\n    checkException(v -> NetUtils.parseIpPortFromURI(\"ss\"));\n  }\n\n  @Test\n  public void testNetUtilsIPv6() {\n    Assertions.assertEquals(\"[::1]\", NetUtils.parseIpPort(\"[::1]:8080\").getHostOrIp());\n    Assertions.assertEquals(\"[::]\", NetUtils.parseIpPort(\"[::]:8080\").getHostOrIp());\n    Assertions.assertEquals(\"[fe80::f816:3eff:feda:38cd%eth0]\",\n        NetUtils.parseIpPort(\"[fe80::f816:3eff:feda:38cd%eth0]:8080\").getHostOrIp());\n    Assertions.assertEquals(\"[fe80::38f7:44b8:8ab1:468%16]\",\n        NetUtils.parseIpPort(\"[fe80::38f7:44b8:8ab1:468%16]:8080\").getHostOrIp());\n    Assertions.assertEquals(8080, NetUtils.parseIpPort(\"[::1]:8080\").getPort());\n    Assertions.assertEquals(8080, NetUtils.parseIpPort(\"[::]:8080\").getPort());\n    Assertions.assertEquals(8080, NetUtils.parseIpPort(\"[fe80::f816:3eff:feda:38cd%eth0]:8080\").getPort());\n    Assertions.assertEquals(8080, NetUtils.parseIpPort(\"[fe80::38f7:44b8:8ab1:468%16]:8080\").getPort());\n\n    Assertions.assertEquals(\"[::1]\", NetUtils.parseIpPortFromURI(\"rest://[::1]:8080\").getHostOrIp());\n    Assertions.assertEquals(\"[::]\", NetUtils.parseIpPortFromURI(\"rest://[::]:8080\").getHostOrIp());\n    Assertions.assertEquals(\"[fe80::f816:3eff:feda:38cd%eth0]\",\n        NetUtils.parseIpPortFromURI(\"rest://[fe80::f816:3eff:feda:38cd%eth0]:8080\").getHostOrIp());\n    Assertions.assertEquals(\"[fe80::38f7:44b8:8ab1:468%16]\",\n        NetUtils.parseIpPortFromURI(\"rest://[fe80::38f7:44b8:8ab1:468%16]:8080\").getHostOrIp());\n    Assertions.assertEquals(8080, NetUtils.parseIpPortFromURI(\"rest://[::1]:8080\").getPort());\n    Assertions.assertEquals(80, NetUtils.parseIpPortFromURI(\"http://[::1]\").getPort());\n    Assertions.assertEquals(8080, NetUtils.parseIpPortFromURI(\"https://[::1]:8080\").getPort());\n    Assertions.assertEquals(443, NetUtils.parseIpPortFromURI(\"https://[::1]\").getPort());\n\n    Assertions.assertEquals(30000, NetUtils.parseIpPort(\"http\", \"[fe80::f816:3eff:feda:38cd%eth0]:30000\").getPort());\n    Assertions.assertEquals(\"[fe80::f816:3eff:feda:38cd%eth0]\",\n        NetUtils.parseIpPort(\"http\", \"[fe80::f816:3eff:feda:38cd%eth0]:30000\").getHostOrIp());\n    Assertions.assertEquals(30000, NetUtils.parseIpPort(\"https\", \"[fe80::f816:3eff:feda:38cd%eth0]:30000\").getPort());\n    Assertions.assertEquals(\"[fe80::f816:3eff:feda:38cd%eth0]\",\n        NetUtils.parseIpPort(\"https\", \"[fe80::f816:3eff:feda:38cd%eth0]:30000\").getHostOrIp());\n    Assertions.assertEquals(80, NetUtils.parseIpPort(\"http\", \"[fe80::f816:3eff:feda:38cd%eth0]\").getPort());\n    Assertions.assertEquals(\"[fe80::f816:3eff:feda:38cd%eth0]\",\n        NetUtils.parseIpPort(\"http\", \"[fe80::f816:3eff:feda:38cd%eth0]\").getHostOrIp());\n    Assertions.assertEquals(443, NetUtils.parseIpPort(\"https\", \"[fe80::f816:3eff:feda:38cd%eth0]\").getPort());\n    Assertions.assertEquals(\"[fe80::f816:3eff:feda:38cd%eth0]\",\n        NetUtils.parseIpPort(\"https\", \"[fe80::f816:3eff:feda:38cd%eth0]\").getHostOrIp());\n  }\n\n  @Test\n  public void testFullOperation() {\n    Assertions.assertNotNull(NetUtils.getHostAddress());\n    Assertions.assertNotNull(NetUtils.getHostName());\n  }\n\n  @Test\n  public void testGetRealListenAddress() {\n    Assertions.assertNull(NetUtils.getRealListenAddress(\"http\", null));\n    Assertions.assertEquals(\"http://1.1.1.1:8080\", NetUtils.getRealListenAddress(\"http\", \"1.1.1.1:8080\"));\n\n    checkException(v -> NetUtils.getRealListenAddress(\"http:1\", \"1.1.1.1:8080\"));\n  }\n\n  @Test\n  public void testNetworkInterface() {\n    Map<String, InetAddress> org = Deencapsulation.getField(NetUtils.class, \"allInterfaceAddresses\");\n\n    Map<String, InetAddress> newValue = new HashMap<>();\n    InetAddress addr = Mockito.mock(InetAddress.class);\n    newValue.put(\"eth100\", addr);\n    Deencapsulation.setField(NetUtils.class, \"allInterfaceAddresses\", newValue);\n\n    Assertions.assertEquals(addr, NetUtils.getInterfaceAddress(\"eth100\"));\n    Assertions.assertEquals(addr, NetUtils.ensureGetInterfaceAddress(\"eth100\"));\n\n    try {\n      NetUtils.ensureGetInterfaceAddress(\"xxx\");\n      Assertions.fail(\"must throw exception\");\n    } catch (IllegalArgumentException e) {\n      Assertions.assertEquals(\"Can not find address for interface name: xxx\", e.getMessage());\n    }\n\n    Deencapsulation.setField(NetUtils.class, \"allInterfaceAddresses\", org);\n  }\n\n  @Test\n  public void testCanTcpListenNo() throws IOException {\n    InetAddress address = InetAddress.getByName(\"127.0.0.1\");\n    try (ServerSocket ss = new ServerSocket(0, 0, address)) {\n      Assertions.assertFalse(NetUtils.canTcpListen(address, ss.getLocalPort()));\n    }\n  }\n\n  @Test\n  public void testCanTcpListenYes() throws IOException {\n    InetAddress address = InetAddress.getByName(\"127.0.0.1\");\n    ServerSocket ss = new ServerSocket(0, 0, address);\n    int port = ss.getLocalPort();\n    ss.close();\n\n    Assertions.assertTrue(NetUtils.canTcpListen(address, port));\n  }\n\n  @Test\n  public void humanReadableBytes() {\n    Assertions.assertEquals(\"0\", NetUtils.humanReadableBytes(0L));\n    Assertions.assertEquals(\"1\", NetUtils.humanReadableBytes(1L));\n    Assertions.assertEquals(\"1023\", NetUtils.humanReadableBytes(1023L));\n\n    Assertions.assertEquals(\"1.000K\", NetUtils.humanReadableBytes(1024L));\n    Assertions.assertEquals(\"1.001K\", NetUtils.humanReadableBytes(1025L));\n    Assertions.assertEquals(\"1023.999K\", NetUtils.humanReadableBytes(1024L * 1024 - 1));\n\n    Assertions.assertEquals(\"1.000M\", NetUtils.humanReadableBytes(1024L * 1024));\n    Assertions.assertEquals(\"1.000M\", NetUtils.humanReadableBytes(1024L * 1024 + 1));\n    Assertions.assertEquals(\"1.001M\", NetUtils.humanReadableBytes(1024L * 1024 + 1024));\n    Assertions.assertEquals(\"1023.999M\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 - 1024));\n    Assertions.assertEquals(\"1024.000M\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 - 1));\n    Assertions.assertEquals(\"1.000G\", NetUtils.humanReadableBytes(1024L * 1024 * 1024));\n    Assertions.assertEquals(\"1.000G\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 + 1));\n    Assertions.assertEquals(\"1.000G\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 + 1024));\n    Assertions.assertEquals(\"1023.999G\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 - 1024 * 1024));\n    Assertions.assertEquals(\"1024.000G\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 - 1024));\n    Assertions.assertEquals(\"1.000T\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024));\n    Assertions.assertEquals(\"1.001T\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 + 1024 * 1024 * 1024));\n    Assertions.assertEquals(\"1023.999T\",\n        NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 * 1024 - 1024L * 1024 * 1024));\n\n    Assertions.assertEquals(\"1.000P\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 * 1024));\n    Assertions.assertEquals(\"1.001P\",\n        NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 * 1024 + 1024L * 1024 * 1024 * 1024));\n    Assertions.assertEquals(\"1023.999P\",\n        NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 * 1024 * 1024 - 1024L * 1024 * 1024 * 1024));\n\n    Assertions.assertEquals(\"1.000E\", NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 * 1024 * 1024));\n    Assertions.assertEquals(\"1.001E\",\n        NetUtils.humanReadableBytes(1024L * 1024 * 1024 * 1024 * 1024 * 1024 + 1024L * 1024 * 1024 * 1024 * 1024));\n    Assertions.assertEquals(\"8.000E\", NetUtils.humanReadableBytes(Long.MAX_VALUE));\n  }\n\n  @Test\n  public void testGetHostName() {\n    Assertions.assertNotEquals(null, NetUtils.getHostName());\n    Deencapsulation.setField(NetUtils.class, \"hostName\", null);\n    Assertions.assertNotEquals(null, NetUtils.getHostName());\n  }\n\n  @Test\n  public void testGetHostAddress() {\n    Assertions.assertNotEquals(null, NetUtils.getHostAddress());\n    Deencapsulation.setField(NetUtils.class, \"hostAddress\", null);\n    Assertions.assertNotEquals(null, NetUtils.getHostAddress());\n  }\n\n  public void checkException(Consumer<Void> testedBehavior) {\n    try {\n      testedBehavior.accept(null);\n      Assertions.fail(\"IllegalArgumentException is expected!\");\n    } catch (Exception e) {\n      Assertions.assertEquals(IllegalArgumentException.class, e.getClass());\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestURIEndpointObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.net;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.Map;\n\nimport mockit.Deencapsulation;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestURIEndpointObject {\n  @Test\n  public void testRestEndpointObject() {\n    URIEndpointObject obj = new URIEndpointObject(\"http://127.0.2.0:8080\");\n    Assertions.assertEquals(\"127.0.2.0\", obj.getHostOrIp());\n    Assertions.assertEquals(8080, obj.getPort());\n    Assertions.assertFalse(obj.isSslEnabled());\n\n    obj = new URIEndpointObject(\"http://127.0.2.0:8080?sslEnabled=true\");\n    Assertions.assertEquals(\"127.0.2.0\", obj.getHostOrIp());\n    Assertions.assertEquals(8080, obj.getPort());\n    Assertions.assertTrue(obj.isSslEnabled());\n    Assertions.assertNull(obj.getFirst(\"notExist\"));\n\n    obj = new URIEndpointObject(\"http://127.0.2.0:8080?sslEnabled=true&protocol=http2\");\n    Assertions.assertEquals(\"127.0.2.0\", obj.getHostOrIp());\n    Assertions.assertEquals(8080, obj.getPort());\n    Assertions.assertTrue(obj.isSslEnabled());\n    Assertions.assertTrue(obj.isHttp2Enabled());\n    Assertions.assertNull(obj.getFirst(\"notExist\"));\n\n    obj = new URIEndpointObject(\"rest://127.0.2.0:8080?urlPrefix=%2Froot\");\n    Assertions.assertEquals(\"127.0.2.0\", obj.getHostOrIp());\n    Assertions.assertEquals(8080, obj.getPort());\n    Assertions.assertEquals(\"/root\", obj.getQuery(\"urlPrefix\").get(0));\n  }\n\n  @Test\n  public void testRestEndpointObjectException() {\n    Assertions.assertThrows(IllegalArgumentException.class, () -> new URIEndpointObject(\"http://127.0.2.0\"));\n  }\n\n  @Test\n  public void testQueryChineseAndSpaceAndEmpty() throws UnsupportedEncodingException {\n    String strUri =\n        \"cse://1.1.1.1:1234/abc?a=1&b=&country=\" + URLEncoder.encode(\"中 国\", StandardCharsets.UTF_8.name());\n    URIEndpointObject ep = new URIEndpointObject(strUri);\n\n    Map<String, List<String>> queries = Deencapsulation.getField(ep, \"queries\");\n    Assertions.assertEquals(3, queries.size());\n\n    Assertions.assertEquals(1, ep.getQuery(\"a\").size());\n    Assertions.assertEquals(\"1\", ep.getFirst(\"a\"));\n\n    Assertions.assertEquals(1, ep.getQuery(\"b\").size());\n    Assertions.assertEquals(\"\", ep.getFirst(\"b\"));\n\n    Assertions.assertEquals(1, ep.getQuery(\"country\").size());\n    Assertions.assertEquals(\"中 国\", ep.getFirst(\"country\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestAbstractPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.IOException;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestAbstractPart {\n  AbstractPart part = new AbstractPart();\n\n  private void checkError(Error error) {\n    Assertions.assertEquals(\"not supported method\", error.getMessage());\n  }\n\n  @Test\n  public void getInputStream() throws IOException {\n    Error error = Assertions.assertThrows(Error.class, () -> part.getInputStream());\n    checkError(error);\n  }\n\n  @Test\n  public void getContentType() throws IOException {\n    Assertions.assertEquals(MediaType.APPLICATION_OCTET_STREAM, part.getContentType());\n\n    String contentType = \"abc\";\n    part.contentType(contentType);\n    Assertions.assertEquals(contentType, part.getContentType());\n  }\n\n  @Test\n  public void getName() throws IOException {\n    Assertions.assertNull(part.getName());\n\n    String name = \"abc\";\n    part.name = name;\n    Assertions.assertEquals(name, part.getName());\n  }\n\n  @Test\n  public void getSubmittedFileName() throws IOException {\n    Assertions.assertNull(part.getSubmittedFileName());\n\n    String submittedFileName = \"abc\";\n    part.setSubmittedFileName(submittedFileName);\n    Assertions.assertEquals(submittedFileName, part.getSubmittedFileName());\n  }\n\n  @Test\n  public void setSubmittedFileName_contentTypeNotNull() {\n    part.contentType(MediaType.TEXT_PLAIN);\n    part.setSubmittedFileName(\"a.zip\");\n\n    Assertions.assertEquals(MediaType.TEXT_PLAIN, part.getContentType());\n  }\n\n  @Test\n  public void setSubmittedFileName_setNull() {\n    part.setSubmittedFileName(null);\n\n    Assertions.assertEquals(MediaType.APPLICATION_OCTET_STREAM, part.getContentType());\n  }\n\n  @Test\n  public void setSubmittedFileName_setNormal() {\n    part.setSubmittedFileName(\"a.zip\");\n\n    Assertions.assertEquals(\"application/zip\", part.getContentType());\n  }\n\n  @Test\n  public void getSize() {\n    Error error = Assertions.assertThrows(Error.class, () -> part.getSize());\n    checkError(error);\n  }\n\n  @Test\n  public void write() throws IOException {\n    Error error = Assertions.assertThrows(Error.class, () -> part.write(\"file\"));\n    checkError(error);\n  }\n\n  @Test\n  public void delete() throws IOException {\n    Error error = Assertions.assertThrows(Error.class, () -> part.delete());\n    checkError(error);\n  }\n\n  @Test\n  public void getHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> part.getHeader(\"header\"));\n    checkError(error);\n  }\n\n  @Test\n  public void getHeaders() {\n    Error error = Assertions.assertThrows(Error.class, () -> part.getHeaders(\"header\"));\n    checkError(error);\n  }\n\n  @Test\n  public void getHeaderNames() {\n    Error error = Assertions.assertThrows(Error.class, () -> part.getHeaderNames());\n    checkError(error);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestFilePart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.io.IOUtils;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\n\npublic class TestFilePart {\n  static File file = new File(\"testFilePart.txt\");\n\n  static String content = \"testFilePart content\";\n\n  String name = \"paramName\";\n\n  FilePart part = new FilePart(name, file.getAbsolutePath());\n\n  @BeforeAll\n  public static void setup() throws IOException {\n    file.delete();\n    FileUtils.write(file, content, StandardCharsets.UTF_8);\n  }\n\n  @AfterAll\n  public static void teardown() {\n    file.delete();\n  }\n\n  @Test\n  public void getName() {\n    Assertions.assertEquals(name, part.getName());\n  }\n\n  @Test\n  public void getInputStream() throws IOException {\n    try (InputStream is = part.getInputStream()) {\n      Assertions.assertEquals(content, IOUtils.toString(is, StandardCharsets.UTF_8));\n    }\n  }\n\n  @Test\n  public void getSize() {\n    Assertions.assertEquals(content.length(), part.getSize());\n  }\n\n  @Test\n  public void write() throws IOException {\n    File destFile = new File(\"testFilePartCopy.txt\");\n\n    part.write(destFile.getPath());\n    Assertions.assertEquals(content, FileUtils.readFileToString(destFile, StandardCharsets.UTF_8));\n\n    FilePart destPart = new FilePart(null, destFile);\n    destPart.delete();\n    Assertions.assertFalse(destFile.exists());\n  }\n\n  @Test\n  public void deleteAfterFinished() {\n    Assertions.assertFalse(part.isDeleteAfterFinished());\n\n    Assertions.assertTrue(part.setDeleteAfterFinished(true).isDeleteAfterFinished());\n  }\n\n  @Test\n  public void getAbsolutePath() {\n    Assertions.assertEquals(file.getAbsolutePath(), part.getAbsolutePath());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestInputStreamPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport org.apache.commons.io.IOUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestInputStreamPart {\n  String name = \"paramName\";\n\n  byte[] bytes = new byte[] {1, 2, 3};\n\n  InputStream is = new ByteArrayInputStream(bytes);\n\n  InputStreamPart part = new InputStreamPart(name, is);\n\n  @Test\n  public void getName() {\n    Assertions.assertEquals(name, part.getName());\n  }\n\n  @Test\n  public void test() throws IOException {\n    try (InputStream is = part.getInputStream()) {\n      byte[] content = IOUtils.toByteArray(is);\n      Assertions.assertArrayEquals(bytes, content);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/part/TestResourcePart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.part;\n\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport org.apache.commons.io.IOUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.core.io.ByteArrayResource;\nimport org.springframework.core.io.Resource;\n\npublic class TestResourcePart {\n  String name = \"paramName\";\n\n  byte[] bytes = new byte[] {1, 2, 3};\n\n  Resource resource = new ByteArrayResource(bytes);\n\n  ResourcePart part = new ResourcePart(name, resource);\n\n  @Test\n  public void getName() {\n    Assertions.assertEquals(name, part.getName());\n  }\n\n  @Test\n  public void getInputStream() throws IOException {\n    try (InputStream is = part.getInputStream()) {\n      byte[] content = IOUtils.toByteArray(is);\n      Assertions.assertArrayEquals(bytes, content);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/spring/TestPaasNamespaceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.spring;\n\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPaasNamespaceHandler {\n\n  PaasNamespaceHandler paasNamespaceHandler = null;\n\n  @BeforeEach\n  public void setUp() throws Exception {\n    paasNamespaceHandler = new PaasNamespaceHandler();\n  }\n\n  @AfterEach\n  public void tearDown() throws Exception {\n    paasNamespaceHandler = null;\n  }\n\n  @Test\n  public void testInit() {\n    boolean status = false;\n    try {\n      paasNamespaceHandler.init();\n    } catch (Exception e) {\n      status = true;\n    }\n    Assertions.assertFalse(status);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/AsyncUtilsTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.junit.jupiter.api.Test;\n\nclass AsyncUtilsTest {\n  @Test\n  void should_convert_success_async_to_sync() {\n    CompletableFuture<String> future = CompletableFuture.completedFuture(\"value\");\n\n    assertThat(AsyncUtils.toSync(future)).isEqualTo(\"value\");\n  }\n\n  @Test\n  void should_convert_fail_async_to_sync() {\n    RuntimeExceptionWithoutStackTrace throwable = new RuntimeExceptionWithoutStackTrace();\n    CompletableFuture<String> future = AsyncUtils.completeExceptionally(throwable);\n\n    Throwable catchThrowable = catchThrowable(() -> AsyncUtils.toSync(future));\n    assertThat(catchThrowable).isSameAs(throwable);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/JsonUtilsTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport org.apache.commons.lang3.StringUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class JsonUtilsTest {\n\n    @Test\n    void testWriteUnicodeValueAsString() throws JsonProcessingException {\n        String unicodeStr = \"测试\";\n        Map<String, String> inMap = new HashMap<>();\n        inMap.put(\"key\", unicodeStr);\n\n        Assertions.assertFalse(StringUtils.isAsciiPrintable(JsonUtils.writeValueAsString(inMap)));\n        String jsonStr = JsonUtils.writeUnicodeValueAsString(inMap);\n        Assertions.assertTrue(StringUtils.isAsciiPrintable(jsonStr));\n\n        Map<String, String> outMap = JsonUtils.OBJ_MAPPER.readValue(jsonStr, new TypeReference<Map<String, String>>() {\n        });\n        Assertions.assertEquals(unicodeStr, outMap.get(\"key\"));\n    }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/ResourceUtilTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.util.List;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class ResourceUtilTest {\n\n  @Test\n  public void loadResources_in_disk() throws IOException, URISyntaxException {\n    List<URI> uris = ResourceUtil.findResourcesBySuffix(\"META-INF/spring\", \".xml\");\n    Assertions.assertEquals(1, uris.size());\n    URI uri = uris.get(0);\n    Assertions.assertTrue(uri.toString().startsWith(\"file:\"), \"unexpected uri: \" + uri);\n    Assertions.assertTrue(uri.toString().endsWith(\"META-INF/spring/config.bean.xml\"), \"unexpected uri: \" + uri);\n  }\n\n  @Test\n  public void loadResources_exact_file_in_disk() throws IOException, URISyntaxException {\n    List<URI> uris = ResourceUtil.findResources(\"META-INF/spring/config.bean.xml\");\n    Assertions.assertEquals(1, uris.size());\n    URI uri = uris.get(0);\n    Assertions.assertTrue(uri.toString().startsWith(\"file:\"), \"unexpected uri: \" + uri);\n    Assertions.assertTrue(uri.toString().endsWith(\"META-INF/spring/config.bean.xml\"), \"unexpected uri: \" + uri);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestExceptionUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.IOException;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestExceptionUtils {\n  @Test\n  public void testExceptionUtils() {\n    Exception e = new Exception(\"Hello\");\n    Assertions.assertEquals(\"cause:Exception,message:Hello\", ExceptionUtils.getExceptionMessageWithoutTrace(e));\n    Exception e2 = new Exception(\"FAIL\", new IOException(\"IO\"));\n    Assertions.assertEquals(\"cause:Exception,message:FAIL;cause:IOException,message:IO\",\n        ExceptionUtils.getExceptionMessageWithoutTrace(e2));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestFileNameTooLong.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.File;\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class TestFileNameTooLong {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestFileNameTooLong.class);\n\n  // ensure the maximum file path do not exceed. now set to 200(some old windows max 260)\n  // smaller is better, can refactor in future\n  // NOTICE: compiled classes or other generated files like surefire reports may exceed this size\n  private static final int MAN_FILE_SIZE = 200;\n\n  @Test\n  public void assertFileNotTooLong() {\n    File folder = new File(System.getProperty(\"user.dir\"));\n    LOGGER.error(folder.getAbsolutePath()); // $ROOT\\foundations\\foundation-common\n    File root = new File(folder.getParentFile().getParent());\n    LOGGER.error(root.getAbsolutePath()); // $ROOT\\foundations\\foundation-common\n    Assertions.assertTrue(root.exists());\n    Assertions.assertTrue(root.isDirectory());\n\n    List<String> names = new LinkedList<>();\n    findLongFileName(root, names, root.getAbsolutePath().length());\n    Collections.sort(names);\n    names.forEach(LOGGER::error);\n    if (!names.isEmpty()) {\n      // for debug\n      Assertions.assertEquals(\"\", names.toString());\n    }\n    Assertions.assertTrue(names.isEmpty());\n  }\n\n  private static void findLongFileName(File folder, List<String> holder, int baseLength) {\n    if (folder.isFile()) {\n      if (folder.getAbsolutePath().length() >= MAN_FILE_SIZE + baseLength) {\n        holder.add(folder.getAbsolutePath());\n      }\n    } else if (folder.isDirectory() && !\"target\".equals(folder.getName())) {\n      File[] children = folder.listFiles();\n      for (File child : children) {\n        findLongFileName(child, holder, baseLength);\n      }\n    } else {\n      return;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestFortifyUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.io.IOException;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestFortifyUtils {\n  @Test\n  public void testFortifyUtils() throws IOException {\n    Assertions.assertEquals(\"\", FortifyUtils.getErrorMsg(null));\n    Assertions.assertEquals(\"\", FortifyUtils.getErrorStack(null));\n  }\n\n  @Test\n  public void testFilePerm() {\n    Assertions.assertEquals(10, (FilePerm.getDefaultAclPerm().size()));\n    Assertions.assertEquals(3, (FilePerm.getDefaultPosixPerm().size()));\n    Assertions.assertEquals(4, (FilePerm.getPosixPerm(400).size()));\n  }\n\n  @Test\n  public void testGetErrorMsg() {\n\n    Throwable e = new Throwable();\n\n    FortifyUtils.getErrorMsg(e);\n\n    Assertions.assertNull(FortifyUtils.getErrorMsg(e));\n  }\n\n  @Test\n  public void testGetSecurityXmlDocumentFactory() {\n\n    try {\n      FortifyUtils.getSecurityXmlDocumentFactory();\n      Assertions.assertNotNull(FortifyUtils.getSecurityXmlDocumentFactory());\n    } catch (Exception e) {\n      /* Do not Worry */\n        Assertions.fail();\n    }\n  }\n\n  @Test\n  public void testGetErrorStack() {\n\n    Throwable e = new Throwable();\n    FortifyUtils.getErrorStack(e);\n    Assertions.assertNotEquals(true, FortifyUtils.getErrorStack(e));\n  }\n\n  @Test\n  public void testGetErrorInfo() {\n\n    Throwable e = new Throwable();\n    FortifyUtils.getErrorInfo(e, true);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestGenericsUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.core.ParameterizedTypeReference;\n\npublic class TestGenericsUtils {\n  @Test\n  public void testIsGenerics() {\n    Assertions.assertTrue(GenericsUtils.isGenericResponseType(List.class));\n    Assertions.assertTrue(GenericsUtils.isGenericResponseType(Map.class));\n    Assertions.assertTrue(GenericsUtils.isGenericResponseType(Person.class));\n\n    Assertions.assertFalse(GenericsUtils.isGenericResponseType(Man.class));\n    Assertions.assertFalse(GenericsUtils.isGenericResponseType(String.class));\n    Assertions.assertFalse(GenericsUtils.isGenericResponseType(GenericsUtils.class));\n\n    Assertions.assertFalse(GenericsUtils.isGenericResponseType(new ParameterizedTypeReference<List<Man>>() {\n    }.getType()));\n  }\n}\n\nclass Person<T> {\n  private T value;\n\n  public T getValue() {\n    return value;\n  }\n}\n\nclass Man extends Person<String> {\n\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestIOUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestIOUtils {\n\n  @Test\n  public void testAnonymousPath() {\n    Assertions.assertEquals(\":/:/r/2/y/b/y/0/s/microservice.yaml\",\n        IOUtils.anonymousPath(\"jar:file:/D:/User/.m2/repository/servicecomb\"\n            + \"/transport-highway/2.3.0/classes/microservice.yaml\"));\n\n    Assertions.assertEquals(\":/:/r/microservice.yaml\", IOUtils.anonymousPath(\"file:/D:/User/microservice.yaml\"));\n\n    Assertions.assertEquals(\":\\\\:\\\\r\\\\microservice.yaml\", IOUtils.anonymousPath(\"file:\\\\D:\\\\User\\\\microservice.yaml\"));\n\n    Assertions.assertEquals(\"r\\\\t\\\\a.txt\", IOUtils.anonymousPath(\"user\\\\test\\\\a.txt\"));\n\n    Assertions.assertEquals(\":\\\\:\\\\a.txt\", IOUtils.anonymousPath(\"file:\\\\D:\\\\a.txt\"));\n\n    Assertions.assertEquals(\":\\\\a.txt\", IOUtils.anonymousPath(\"D:\\\\a.txt\"));\n\n    Assertions.assertEquals(\"a.txt\", IOUtils.anonymousPath(\"a.txt\"));\n  }\n\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport mockit.Mock;\nimport mockit.MockUp;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Disabled;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.condition.EnabledOnJre;\nimport org.junit.jupiter.api.condition.JRE;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\nimport java.net.URL;\n\n\npublic class TestJvmUtils {\n\n  @Test\n  @Disabled\n  public void findMainClass_notExist() {\n    System.clearProperty(JvmUtils.SUN_JAVA_COMMAND);\n    Assertions.assertNull(JvmUtils.findMainClass());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClass_existButEmpty() {\n    System.setProperty(JvmUtils.SUN_JAVA_COMMAND, \"\");\n    Assertions.assertNull(JvmUtils.findMainClass());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClass_invalid() {\n    LogCollector logCollector = new LogCollector();\n\n    System.setProperty(JvmUtils.SUN_JAVA_COMMAND, \"invalidCls\");\n\n    Assertions.assertNull(JvmUtils.findMainClass());\n    Assertions.assertEquals(\"\\\"invalidCls\\\" is not a valid class.\", logCollector.getEvents().get(0).getMessage());\n    logCollector.tearDown();\n  }\n\n  @Test\n  @Disabled\n  public void findMainClass_class_normal() {\n    System.setProperty(JvmUtils.SUN_JAVA_COMMAND, TestJvmUtils.class.getName() + \" arg\");\n\n    Assertions.assertEquals(TestJvmUtils.class, JvmUtils.findMainClass());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClass_jar_normal() throws Exception {\n    String command = \"a.jar\";\n\n    String content = String.format(\"Manifest-Version: 1.0\\nMain-Class: %s\\n\", TestJvmUtils.class.getName());\n    InputStream inputStream = new ByteArrayInputStream(content.getBytes());\n    new MockUp<URL>() {\n      @Mock\n      InputStream openStream() throws Exception {\n        return inputStream;\n      }\n    };\n\n    System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + \" arg\");\n\n    Assertions.assertEquals(TestJvmUtils.class, JvmUtils.findMainClass());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClass_jar_null() throws Exception {\n    String content = \"Manifest-Version: 1.0\\n\";\n    InputStream inputStream = new ByteArrayInputStream(content.getBytes());\n\n    String command = \"a.jar\";\n\n    new MockUp<URL>() {\n      @Mock\n      InputStream openStream() throws Exception {\n        return inputStream;\n      }\n    };\n\n    System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + \" arg\");\n\n    Assertions.assertNull(JvmUtils.findMainClass());\n  }\n\n  @Test\n  @Disabled\n  @EnabledOnJre(JRE.JAVA_17)\n  public void findMainClass_jar_readFailed() throws Exception {\n    String command = \"a.jar\";\n\n    new MockUp<URL>() {\n      @Mock\n      InputStream openStream() throws Exception {\n        throw new RuntimeExceptionWithoutStackTrace();\n      }\n    };\n\n    System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + \" arg\");\n\n    Assertions.assertNull(JvmUtils.findMainClass());\n  }\n\n\n  @Test\n  @Disabled\n  public void findMainClassByStackTrace_normal() throws Exception{\n    StackTraceElement[] stackTraceElements = {\n            new StackTraceElement(\"declaring.class.fileName\", \"methodName\", \"fileName\", 100),\n            new StackTraceElement(\"java.lang.String\", \"main\", \"fileName\", 120)\n    };\n    new MockUp<RuntimeException>() {\n      @Mock\n      public StackTraceElement[] getStackTrace() {\n        return stackTraceElements;\n      }\n    };\n\n    Assertions.assertEquals(String.class, JvmUtils.findMainClassByStackTrace());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClassByStackTrace_invalidClass() throws Exception{\n    StackTraceElement[] stackTraceElements = {\n            new StackTraceElement(\"declaring.class.fileName\", \"methodName\", \"fileName\", 100),\n            new StackTraceElement(\"InvalidClass\", \"main\", \"fileName\", 120)\n    };\n    new MockUp<RuntimeException>() {\n      @Mock\n      public StackTraceElement[] getStackTrace() {\n        return stackTraceElements;\n      }\n    };\n\n    Assertions.assertNull(JvmUtils.findMainClassByStackTrace());\n  }\n\n\n  @Test\n  @Disabled\n  public void findMainClassByStackTrace_withoutMainMethod() throws Exception{\n    StackTraceElement[] stackTraceElements = {\n            new StackTraceElement(\"declaring.class.fileName\", \"methodName\", \"fileName\", 100),\n            new StackTraceElement(\"InvalidClass\", \"methodName\", \"fileName\", 120)\n    };\n    new MockUp<RuntimeException>() {\n      @Mock\n      public StackTraceElement[] getStackTrace() {\n        return stackTraceElements;\n      }\n    };\n\n    Assertions.assertNull(JvmUtils.findMainClassByStackTrace());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClassByStackTrace_emptyStackTrace() throws Exception{\n    new MockUp<RuntimeException>() {\n      @Mock\n      public StackTraceElement[] getStackTrace() {\n        return new StackTraceElement[]{};\n      }\n    };\n\n    Assertions.assertNull(JvmUtils.findMainClassByStackTrace());\n  }\n\n  @Test\n  @Disabled\n  public void findMainClassByStackTrace_nullStackTrace() throws Exception{\n    new MockUp<RuntimeException>() {\n      @Mock\n      public StackTraceElement[] getStackTrace() {\n        return null;\n      }\n    };\n\n    Assertions.assertNull(JvmUtils.findMainClassByStackTrace());\n  }\n\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestLambdaMetafactoryUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport static org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils.createObjectGetter;\nimport static org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils.createObjectSetter;\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport java.lang.reflect.Field;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.function.BiFunction;\nimport java.util.function.Consumer;\nimport java.util.function.Function;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport com.fasterxml.jackson.databind.BeanDescription;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.condition.EnabledOnJre;\nimport org.junit.jupiter.api.condition.JRE;\n\n@EnabledOnJre(JRE.JAVA_8)\npublic class TestLambdaMetafactoryUtils {\n  public static class Model {\n    public int f1;\n\n    private int f2;\n\n    public int getF1() {\n      return f1;\n    }\n\n    public void setF1(int f1) {\n      this.f1 = f1;\n    }\n\n    public Model fluentSetF1(int f1) {\n      this.f1 = f1;\n      return this;\n    }\n\n    public List<Integer> echo(List<Integer> value) {\n      return value;\n    }\n  }\n\n  Model model = new Model();\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void createLambda_withInstance() throws Throwable {\n    Supplier<Object> getter = LambdaMetafactoryUtils\n        .createLambda(model, Model.class.getMethod(\"getF1\"), Supplier.class);\n    Consumer<Object> setter = LambdaMetafactoryUtils\n        .createLambda(model, Model.class.getMethod(\"setF1\", int.class), Consumer.class);\n    Function<Object, Object> echo = LambdaMetafactoryUtils\n        .createLambda(model, Model.class.getMethod(\"echo\", List.class), Function.class);\n\n    setter.accept(1);\n    int f1 = (int) getter.get();\n    Assertions.assertEquals(1, f1);\n    MatcherAssert.assertThat((List<Integer>) echo.apply(Arrays.asList(2)), Matchers.contains(2));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void createGetterSetterByMethod() throws Throwable {\n    IntGetter<Model> getter = LambdaMetafactoryUtils.createGetter(Model.class.getMethod(\"getF1\"));\n    IntSetter<Model> setter = LambdaMetafactoryUtils.createSetter(Model.class.getMethod(\"setF1\", int.class));\n    IntSetter<Model> fluentSetter = LambdaMetafactoryUtils\n        .createSetter(Model.class.getMethod(\"fluentSetF1\", int.class));\n    BiFunction<Object, Object, Object> echo = LambdaMetafactoryUtils\n        .createLambda(Model.class.getMethod(\"echo\", List.class), BiFunction.class);\n\n    setter.set(model, 1);\n    int f1 = getter.get(model);\n    Assertions.assertEquals(1, f1);\n    MatcherAssert.assertThat((List<Integer>) echo.apply(model, Arrays.asList(2)), Matchers.contains(2));\n\n    fluentSetter.set(model, 2);\n    int ff1 = getter.get(model);\n    Assertions.assertEquals(2, ff1);\n  }\n\n  @Test\n  public void should_failed_when_createGetterSetterByField_and_field_is_not_public() throws Throwable {\n    Field field = Model.class.getDeclaredField(\"f2\");\n    assertThat(catchThrowable(() -> LambdaMetafactoryUtils.createGetter(field)))\n        .isInstanceOf(IllegalStateException.class)\n        .hasMessage(\n            \"Can not access field, a public field or accessor is required.Declaring class is org.apache.servicecomb.foundation.common.utils.TestLambdaMetafactoryUtils$Model, field is f2\");\n    assertThat(catchThrowable(() -> LambdaMetafactoryUtils.createSetter(field)))\n        .isInstanceOf(IllegalStateException.class)\n        .hasMessage(\n            \"Can not access field, a public field or accessor is required.Declaring class is org.apache.servicecomb.foundation.common.utils.TestLambdaMetafactoryUtils$Model, field is f2\");\n  }\n\n  public static class Base<T> {\n    private T base;\n\n    public T getBase() {\n      return base;\n    }\n\n    public Base<T> setBase(T base) {\n      this.base = base;\n      return this;\n    }\n  }\n\n  public static class Child extends Base<Integer> {\n    private int child;\n\n    public int getChild() {\n      return child;\n    }\n\n    public Child setChild(int child) {\n      this.child = child;\n      return this;\n    }\n  }\n\n  @Test\n  public void should_support_primitive_type() {\n    Child child = new Child();\n\n    ObjectMapper mapper = JsonUtils.OBJ_MAPPER;\n    BeanDescription beanDescription = mapper.getSerializationConfig().introspect(mapper.constructType(Child.class));\n    List<BeanPropertyDefinition> properties = beanDescription.findProperties();\n    assertThat(properties).hasSize(2);\n\n    for (int idx = 0; idx < properties.size(); idx++) {\n      BeanPropertyDefinition property = properties.get(idx);\n\n      Setter<Object, Object> setter = createObjectSetter(property.getSetter().getAnnotated());\n      setter.set(child, idx);\n\n      Getter<Object, Object> getter = createObjectGetter(property.getGetter().getAnnotated());\n      Object value = getter.get(child);\n\n      assertThat(value).isEqualTo(idx);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestLambdaPerformance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.lang.invoke.MethodHandle;\nimport java.lang.invoke.MethodHandles;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\nimport org.apache.servicecomb.foundation.common.utils.TestLambdaMetafactoryUtils.Model;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\n\npublic class TestLambdaPerformance {\n  static Model model = new Model();\n\n  // 20 field/msg, 10_0000tps\n  static int count = 20 * 100_0000;\n\n  static int sum = 0;\n\n  static Method f1_getter;\n\n  static MethodHandle mh_f1_getter;\n\n  static IntGetter<Model> lambda_f1_method_getter;\n\n  static Field f1_field;\n\n  static Getter<Model, Integer> lambda_f1_field_getter;\n\n  static {\n    model.setF1(123456);\n    try {\n      f1_field = Model.class.getDeclaredField(\"f1\");\n      f1_field.setAccessible(true);\n\n      f1_getter = Model.class.getMethod(\"getF1\");\n      mh_f1_getter = MethodHandles.lookup().unreflect(f1_getter);\n      lambda_f1_method_getter = LambdaMetafactoryUtils.createGetter(f1_getter);\n      lambda_f1_field_getter = LambdaMetafactoryUtils.createGetter(f1_field);\n    } catch (Throwable throwable) {\n      throwable.printStackTrace();\n    }\n  }\n\n  public static long directGetter() {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += model.getF1();\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long reflectfieldF1() throws IllegalAccessException {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += (int) f1_field.get(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long reflectIntFieldF1() throws IllegalAccessException {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += f1_field.getInt(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long lambdaMethodGetter() throws Throwable {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += lambda_f1_method_getter.get(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long lambdaFieldGetter() throws Throwable {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += lambda_f1_field_getter.get(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long mhGetterInvoke() throws Throwable {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += (int) mh_f1_getter.invoke(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long mhGetterExact() throws Throwable {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += (int) mh_f1_getter.invokeExact(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static long reflectGetter() throws InvocationTargetException, IllegalAccessException {\n    long start = System.nanoTime();\n    sum = 0;\n    for (int idx = 0; idx < count; idx++) {\n      sum += (int) f1_getter.invoke(model);\n    }\n    return System.nanoTime() - start;\n  }\n\n  public static void main(String[] args) throws Throwable {\n    lambdaMethodGetter();\n    directGetter();\n    mhGetterInvoke();\n    reflectGetter();\n    mhGetterExact();\n    reflectfieldF1();\n    reflectIntFieldF1();\n\n    System.out.println(\"mhGetterInvoke       : \" + mhGetterInvoke());\n    System.out.println(\"mhGetterExact        : \" + mhGetterExact());\n    System.out.println(\"reflectGetter        : \" + reflectGetter());\n\n    System.out.println(\"\");\n\n    System.out.println(\"reflectfieldF1       : \" + reflectfieldF1());\n    System.out.println(\"lambdaFieldGetter    : \" + lambdaFieldGetter());\n\n    System.out.println(\"\");\n\n    System.out.println(\"lambdaMethodGetter   : \" + lambdaMethodGetter());\n    System.out.println(\"directGetter         : \" + directGetter());\n    System.out.println(\"reflectIntFieldF1    : \" + reflectIntFieldF1());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestMimeTypesUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMimeTypesUtils {\n  @Test\n  public void testSortedAcceptableMimeTypes1() {\n    String accept = \"text/html\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(1, types.size());\n    Assertions.assertEquals(\"text/html\", types.get(0));\n  }\n\n  @Test\n  public void testSortedAcceptableMimeTypes2() {\n    String accept = \"text/html, application/json\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(2, types.size());\n    Assertions.assertEquals(\"text/html\", types.get(0));\n    Assertions.assertEquals(\"application/json\", types.get(1));\n  }\n\n  @Test\n  public void testSortedAcceptableMimeTypes3() {\n    String accept = \"text/html,application/json\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(2, types.size());\n    Assertions.assertEquals(\"text/html\", types.get(0));\n    Assertions.assertEquals(\"application/json\", types.get(1));\n  }\n\n  @Test\n  public void testSortedAcceptableMimeTypes4() {\n    String accept = \"text/html; q=0.8,application/json; q=0.9\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(2, types.size());\n    Assertions.assertEquals(\"application/json\", types.get(0));\n    Assertions.assertEquals(\"text/html\", types.get(1));\n  }\n\n  @Test\n  public void testSortedAcceptableMimeTypes5() {\n    String accept = \"text/html;q=0.8,application/json;q=0.9\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(2, types.size());\n    Assertions.assertEquals(\"application/json\", types.get(0));\n    Assertions.assertEquals(\"text/html\", types.get(1));\n  }\n\n  @Test\n  public void testSortedAcceptableMimeTypes6() {\n    String accept = \"text/html; q=0.8,application/json; q=0.9, text/plain\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(3, types.size());\n    Assertions.assertEquals(\"text/plain\", types.get(0));\n    Assertions.assertEquals(\"application/json\", types.get(1));\n    Assertions.assertEquals(\"text/html\", types.get(2));\n  }\n\n  @Test\n  public void testSortedAcceptableMimeTypes7() {\n    String accept = \"text/html;q=0.8,application/json;q=0.9,text/plain\";\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(accept);\n    Assertions.assertEquals(3, types.size());\n    Assertions.assertEquals(\"text/plain\", types.get(0));\n    Assertions.assertEquals(\"application/json\", types.get(1));\n    Assertions.assertEquals(\"text/html\", types.get(2));\n  }\n\n  @Test\n  public void getSortedAcceptableMimeTypesNull() {\n    List<String> types = MimeTypesUtils.getSortedAcceptableMimeTypes(null);\n    Assertions.assertSame(Collections.emptyList(), types);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestRSAUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.security.InvalidKeyException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.SignatureException;\nimport java.security.spec.InvalidKeySpecException;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestRSAUtil {\n  @BeforeAll\n  public static void setUpClass() {\n    Environment environment = Mockito.mock(Environment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keyGeneratorAlgorithm\", \"RSA\"))\n        .thenReturn(\"RSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.signAlgorithm\", \"SHA256withRSA\"))\n        .thenReturn(\"SHA256withRSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keySize\", int.class, 2048))\n        .thenReturn(2048);\n  }\n\n  @Test\n  public void testSignVerify()\n      throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException {\n    KeyPairEntry keyPairEntry = KeyPairUtils.generateALGKeyPair();\n\n    Assertions.assertNotNull(keyPairEntry.getPublicKeyEncoded());\n    Assertions.assertNotNull(keyPairEntry.getPrivateKey());\n    Assertions.assertNotNull(keyPairEntry.getPublicKey());\n    String testContent = \"instance-id@201711201930@randomstr\";\n    String signstr = KeyPairUtils.sign(testContent, keyPairEntry.getPrivateKey());\n    Assertions.assertTrue(KeyPairUtils.verify(keyPairEntry.getPublicKeyEncoded(), signstr, testContent));\n  }\n\n  @Test\n  public void testSignVerify2()\n      throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException {\n    String sign =\n        \"WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\";\n    String content =\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ\";\n    String pubKey =\n        \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxKl5TNUTec7fL2degQcCk6vKf3c0wsfNK5V6elKzjWxm0MwbRj/UeR20VSnicBmVIOWrBS9LiERPPvjmmWUOSS2vxwr5XfhBhZ07gCAUNxBOTzgMo5nE45DhhZu5Jzt5qSV6o10Kq7+fCCBlDZ1UoWxZceHkUt5AxcrhEDulFjQIDAQAB\";\n    Assertions.assertTrue(KeyPairUtils.verify(pubKey, sign, content));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestTypesUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestTypesUtil {\n  @Test\n  public void testTypesUtil() {\n    Assertions.assertEquals(double.class, TypesUtil.wrapperTypeToPrimitive(Double.class));\n    Assertions.assertEquals(Float.class, TypesUtil.primitiveTypeToWrapper(float.class));\n    Assertions\n        .assertEquals(TypesUtil.PRIMITIVE_CHAR, TypesUtil.wrapperJavaTypeToPrimitive(TypesUtil.PRIMITIVE_WRAPPER_CHAR));\n    Assertions\n        .assertEquals(TypesUtil.PRIMITIVE_WRAPPER_BYTE, TypesUtil.primitiveJavaTypeToWrapper(TypesUtil.PRIMITIVE_BYTE));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-common/src/test/resources/META-INF/spring/config.bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\">\n\n  <bean id=\"beanProp\" class=\"org.apache.servicecomb.foundation.common.config.BeanProp\">\n    <property name=\"test\">\n      <value>${1.2}</value>\n    </property>\n  </bean>\n</beans>\n"
  },
  {
    "path": "foundations/foundation-common/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "foundations/foundation-config/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>foundations</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <properties>\n  </properties>\n\n  <artifactId>foundation-config</artifactId>\n  <name>Java Chassis::Foundations::Config</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-beans</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-autoconfigure</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.yaml</groupId>\n      <artifactId>snakeyaml</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>jakarta.annotation</groupId>\n      <artifactId>jakarta.annotation-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>slf4j-api</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.httpcomponents</groupId>\n      <artifactId>httpclient</artifactId>\n      <exclusions>\n        <exclusion>\n          <artifactId>commons-logging</artifactId>\n          <groupId>commons-logging</groupId>\n        </exclusion>\n      </exclusions>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-codec</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-codec-http</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-codec-http2</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-handler</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-buffer</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-codec-socks</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-handler-proxy</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-resolver</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-transport</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/BootStrapProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.springframework.core.env.Environment;\n\n\n/**\n * This class holds configurations that need to be configured\n * through property files or environment variables.\n *\n * These properties are core model for java chassis, e.g.\n * <pre>\n *   servicecomb:\n *     service:\n *       application:\n *       name:\n *       version:\n *       environment:\n *       properties:\n * </pre>\n *\n */\npublic class BootStrapProperties {\n  // start of : service definition keys\n  // service definition keys of old version\n  public static final String OLD_CONFIG_SERVICE_APPLICATION = \"APPLICATION_ID\";\n\n  public static final String OLD_CONFIG_SERVICE_NAME = \"service_description.name\";\n\n  public static final String OLD_CONFIG_SERVICE_VERSION = \"service_description.version\";\n\n  public static final String OLD_CONFIG_SERVICE_ROLE = \"service_description.role\";\n\n  public static final String OLD_CONFIG_SERVICE_ALIAS = \"service_description.alias\";\n\n  public static final String OLD_CONFIG_SERVICE_DESCRIPTION = \"service_description.description\";\n\n  public static final String OLD_CONFIG_SERVICE_ENVIRONMENT = \"service_description.environment\";\n\n  public static final String OLD_CONFIG_SERVICE_EXTENDED_CLASS = \"service_description.propertyExtendedClass\";\n\n  public static final String OLD_CONFIG_SERVICE_PROPERTIES = \"service_description.properties\";\n\n  // service instance definition keys of old version\n  public static final String OLD_CONFIG_SERVICE_INSTANCE_PROPERTIES = \"instance_description.properties\";\n\n  public static final String OLD_CONFIG_SERVICE_INSTANCE_EXTENDED_CLASS = \"instance_description.propertyExtendedClass\";\n\n  public static final String OLD_CONFIG_SERVICE_INSTANCE_INITIAL_STATUS = \"instance_description.initialStatus\";\n\n  // service definition keys of new version\n  public static final String CONFIG_SERVICE_APPLICATION = \"servicecomb.service.application\";\n\n  public static final String CONFIG_SERVICE_NAME = \"servicecomb.service.name\";\n\n  public static final String CONFIG_SERVICE_VERSION = \"servicecomb.service.version\";\n\n  public static final String CONFIG_SERVICE_ROLE = \"servicecomb.service.role\";\n\n  public static final String CONFIG_SERVICE_ALIAS = \"servicecomb.service.alias\";\n\n  public static final String CONFIG_SERVICE_DESCRIPTION = \"servicecomb.service.description\";\n\n  public static final String CONFIG_SERVICE_ENVIRONMENT = \"servicecomb.service.environment\";\n\n  public static final String CONFIG_SERVICE_EXTENDED_CLASS = \"servicecomb.service.propertyExtendedClass\";\n\n  public static final String CONFIG_SERVICE_PROPERTIES = \"servicecomb.service.properties\";\n\n  // service instance definition keys of new version\n  public static final String CONFIG_SERVICE_INSTANCE_PROPERTIES = \"servicecomb.instance.properties\";\n\n  public static final String CONFIG_SERVICE_INSTANCE_EXTENDED_CLASS = \"servicecomb.instance.propertyExtendedClass\";\n\n  public static final String CONFIG_SERVICE_INSTANCE_INITIAL_STATUS = \"servicecomb.instance.initialStatus\";\n\n  // configuration default values\n  public static final String DEFAULT_APPLICATION = \"default\";\n\n  public static final String DEFAULT_MICROSERVICE_NAME = \"defaultMicroservice\";\n\n  public static final String DEFAULT_MICROSERVICE_VERSION = \"1.0.0.0\";\n\n  public static final String DEFAULT_MICROSERVICE_ROLE = \"FRONT\";\n\n  public static final String DEFAULT_MICROSERVICE_ENVIRONMENT = \"\";\n\n  public static final String DEFAULT_MICROSERVICE_INSTANCE_INITIAL_STATUS = \"UP\";\n\n  public static String readApplication(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_APPLICATION,\n        OLD_CONFIG_SERVICE_APPLICATION, DEFAULT_APPLICATION);\n  }\n\n  public static String readServiceName(Environment environment) {\n    String result = readStringValue(environment, CONFIG_SERVICE_NAME, OLD_CONFIG_SERVICE_NAME,\n        DEFAULT_MICROSERVICE_NAME);\n    checkMicroserviceName(result);\n    return result;\n  }\n\n  public static String readServiceVersion(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_VERSION, OLD_CONFIG_SERVICE_VERSION,\n        DEFAULT_MICROSERVICE_VERSION);\n  }\n\n  public static String readServiceRole(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_ROLE, OLD_CONFIG_SERVICE_ROLE, DEFAULT_MICROSERVICE_ROLE);\n  }\n\n  public static String readServiceAlias(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_ALIAS, OLD_CONFIG_SERVICE_ALIAS, null);\n  }\n\n  public static String readServiceDescription(Environment environment) {\n    String[] descriptionArray = environment.getProperty(CONFIG_SERVICE_DESCRIPTION, String[].class);\n    if (null == descriptionArray || descriptionArray.length < 1) {\n      descriptionArray = environment.getProperty(OLD_CONFIG_SERVICE_DESCRIPTION, String[].class);\n    }\n\n    if (null == descriptionArray || descriptionArray.length < 1) {\n      return null;\n    }\n\n    StringBuilder rawDescriptionBuilder = new StringBuilder();\n    for (String desc : descriptionArray) {\n      rawDescriptionBuilder.append(desc).append(\",\");\n    }\n\n    return rawDescriptionBuilder.substring(0, rawDescriptionBuilder.length() - 1);\n  }\n\n  public static String readServiceEnvironment(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_ENVIRONMENT, OLD_CONFIG_SERVICE_ENVIRONMENT,\n        DEFAULT_MICROSERVICE_ENVIRONMENT);\n  }\n\n  public static String readServiceExtendedClass(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_EXTENDED_CLASS, OLD_CONFIG_SERVICE_EXTENDED_CLASS,\n        null);\n  }\n\n  public static Map<String, String> readServiceProperties(Environment environment) {\n    return readProperties(environment, CONFIG_SERVICE_PROPERTIES, OLD_CONFIG_SERVICE_PROPERTIES);\n  }\n\n  public static Map<String, String> readServiceInstanceProperties(Environment environment) {\n    return readProperties(environment, CONFIG_SERVICE_INSTANCE_PROPERTIES, OLD_CONFIG_SERVICE_INSTANCE_PROPERTIES);\n  }\n\n  public static String readServiceInstanceExtendedClass(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_INSTANCE_EXTENDED_CLASS,\n        OLD_CONFIG_SERVICE_INSTANCE_EXTENDED_CLASS,\n        null);\n  }\n\n  public static String readServiceInstanceInitialStatus(Environment environment) {\n    return readStringValue(environment, CONFIG_SERVICE_INSTANCE_INITIAL_STATUS,\n        OLD_CONFIG_SERVICE_INSTANCE_INITIAL_STATUS,\n        DEFAULT_MICROSERVICE_INSTANCE_INITIAL_STATUS);\n  }\n\n  private static String readStringValue(Environment environment, String newKey, String oldKey,\n      String defaultValue) {\n    String result = environment.getProperty(newKey);\n    if (result == null) {\n      return environment.getProperty(oldKey, defaultValue);\n    }\n    return result;\n  }\n\n  private static Map<String, String> readProperties(Environment environment, String newKey, String oldKey) {\n    String prefix = newKey;\n    Set<String> keys = ConfigUtil.propertiesWithPrefix(environment, prefix);\n    if (keys.isEmpty()) {\n      prefix = oldKey;\n      keys = ConfigUtil.propertiesWithPrefix(environment, oldKey);\n    }\n    Map<String, String> result = new HashMap<>(keys.size());\n    for (String key : keys) {\n      result.put(key.substring(prefix.length() + 1), environment.getProperty(key));\n    }\n    return result;\n  }\n\n  private static void checkMicroserviceName(String name) {\n    // the configuration we used\n    // when resolve placeholder failed\n    // the result will remains ${var}\n    if (StringUtils.isEmpty(name) || name.contains(\"${\")) {\n      throw new IllegalArgumentException(String.format(\n          \"MicroserviceName '%s' is invalid. you must configure '%s' or set the placeholder value.\",\n          name,\n          CONFIG_SERVICE_NAME));\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigEnvironmentPostProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.config.file.MicroserviceConfigLoader;\nimport org.apache.servicecomb.foundation.bootstrap.BootStrapService;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.env.EnvironmentPostProcessor;\nimport org.springframework.context.annotation.Conditional;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.MutablePropertySources;\n\n/**\n * Initialize configuration.\n */\npublic class ConfigEnvironmentPostProcessor implements EnvironmentPostProcessor {\n  public static final String MICROSERVICE_PROPERTY_SOURCE_NAME = \"microservice.yaml\";\n\n  public static final String MAPPING_PROPERTY_SOURCE_NAME = \"mapping.yaml\";\n\n  @Override\n  public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {\n    LegacyPropertyFactory.setEnvironment(environment);\n    addMicroserviceDefinitions(environment);\n    startupBootStrapService(environment);\n    addDynamicConfigurationToSpring(environment);\n  }\n\n  public static void addMicroserviceDefinitions(Environment environment) {\n    addMicroserviceYAMLToSpring(environment);\n    addMappingToSpring(environment);\n  }\n\n  private void startupBootStrapService(Environment environment) {\n    for (BootStrapService bootStrapService : SPIServiceUtils.getSortedService(BootStrapService.class)) {\n      bootStrapService.startup(environment);\n    }\n  }\n\n  /**\n   * make springboot have a change to add microservice.yaml source earlier<br>\n   * to affect {@link Conditional}\n   * @param environment environment\n   */\n  private static void addMicroserviceYAMLToSpring(Environment environment) {\n    if (!(environment instanceof ConfigurableEnvironment)) {\n      return;\n    }\n\n    MutablePropertySources propertySources = ((ConfigurableEnvironment) environment).getPropertySources();\n    if (propertySources.contains(MICROSERVICE_PROPERTY_SOURCE_NAME)) {\n      return;\n    }\n\n    propertySources.addLast(new EnumerablePropertySource<MicroserviceConfigLoader>(MICROSERVICE_PROPERTY_SOURCE_NAME) {\n      private final Map<String, Object> values = new HashMap<>();\n\n      private final String[] propertyNames;\n\n      {\n        MicroserviceConfigLoader loader = new MicroserviceConfigLoader();\n        loader.loadAndSort();\n\n        loader.getConfigModels()\n            .forEach(configModel -> values.putAll(YAMLUtil.retrieveItems(\"\", configModel.getConfig())));\n\n        propertyNames = values.keySet().toArray(new String[0]);\n      }\n\n      @Override\n      public String[] getPropertyNames() {\n        return propertyNames;\n      }\n\n      @SuppressWarnings(\"unchecked\")\n      @Override\n      public Object getProperty(String name) {\n        Object value = this.values.get(name);\n\n        // spring will not resolve nested placeholder of list, so try to fix the problem\n        if (value instanceof List) {\n          value = ((List<Object>) value).stream()\n              .filter(item -> item instanceof String)\n              .map(item -> environment.resolvePlaceholders((String) item))\n              .collect(Collectors.toList());\n        }\n        return value;\n      }\n    });\n  }\n\n  private static void addMappingToSpring(Environment environment) {\n    if (!(environment instanceof ConfigurableEnvironment)) {\n      return;\n    }\n\n    MutablePropertySources propertySources = ((ConfigurableEnvironment) environment).getPropertySources();\n    if (propertySources.contains(MAPPING_PROPERTY_SOURCE_NAME)) {\n      return;\n    }\n\n    Map<String, Object> mappings = ConfigMapping.getConvertedMap(environment);\n    propertySources.addFirst(new MapPropertySource(MAPPING_PROPERTY_SOURCE_NAME, mappings));\n  }\n\n  private void addDynamicConfigurationToSpring(Environment environment) {\n    if (!(environment instanceof ConfigurableEnvironment)) {\n      return;\n    }\n\n    for (DynamicPropertiesSource dynamicPropertiesSource :\n        SPIServiceUtils.getOrLoadSortedService(DynamicPropertiesSource.class)) {\n      ((ConfigurableEnvironment) environment).getPropertySources()\n          .addFirst(dynamicPropertiesSource.create(environment));\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigMapping.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.file.AbstractConfigLoader;\nimport org.apache.servicecomb.foundation.common.utils.JvmUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n * Created by   on 2017/1/5.\n */\npublic final class ConfigMapping {\n  private static final Map<String, Object> configMap;\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConfigMapping.class);\n\n  static {\n    ClassLoader loader = JvmUtils.findClassLoader();\n    List<Map<String, Object>> mappingList = new ArrayList<>();\n    configMap = new HashMap<>();\n    Enumeration<URL> urls;\n    try {\n      urls = loader.getResources(\"mapping.yaml\");\n      while (urls.hasMoreElements()) {\n        try (InputStream in = urls.nextElement().openStream()) {\n          mappingList.add(YAMLUtil.yaml2Properties(in));\n        }\n      }\n\n      mappingList.sort((a, b) -> {\n        int orderA = a.get(AbstractConfigLoader.ORDER_KEY) == null ? 0 : (int) a.get(AbstractConfigLoader.ORDER_KEY);\n        int orderB = b.get(AbstractConfigLoader.ORDER_KEY) == null ? 0 : (int) b.get(AbstractConfigLoader.ORDER_KEY);\n        return orderA - orderB;\n      });\n\n      mappingList.forEach(item -> {\n        item.remove(AbstractConfigLoader.ORDER_KEY);\n        configMap.putAll(item);\n      });\n    } catch (IOException e) {\n      LOGGER.error(\"get config mapping file error!\", e);\n    }\n  }\n\n  private ConfigMapping() {\n  }\n\n  @VisibleForTesting\n  @SuppressWarnings(\"unchecked\")\n  static <T> T map(String key) {\n    return (T) configMap.get(key);\n  }\n\n  public static Map<String, Object> getMapping() {\n    return configMap;\n  }\n\n  public static Map<String, Object> getConvertedMap(Map<String, Object> oldMap) {\n    if (configMap == null) {\n      return new LinkedHashMap<>();\n    }\n    Map<String, Object> retMap = new LinkedHashMap<>();\n    retMap.putAll(oldMap);\n    configMap.entrySet().forEach(entry -> putConfigsToRetMap(retMap, entry, oldMap.get(entry.getKey())));\n    return retMap;\n  }\n\n  public static Map<String, Object> getConvertedMap(Environment environment) {\n    if (configMap == null) {\n      return new LinkedHashMap<>();\n    }\n    Map<String, Object> retMap = new LinkedHashMap<>();\n    configMap.entrySet().forEach(entry -> putConfigsToRetMap(retMap, entry, environment.getProperty(entry.getKey())));\n    return retMap;\n  }\n\n  private static void putConfigsToRetMap(Map<String, Object> retMap, Map.Entry<String, Object> entry,\n      Object configValue) {\n    if (configValue != null) {\n      if (entry.getValue() instanceof List) {\n        @SuppressWarnings(\"unchecked\")\n        List<String> newKeys = (List<String>) entry.getValue();\n        newKeys.forEach(newKey -> retMap.put(newKey, configValue));\n        return;\n      }\n      String newKey = (String) entry.getValue();\n      retMap.put(newKey, configValue);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.PropertySource;\n\npublic final class ConfigUtil {\n  private ConfigUtil() {\n  }\n\n  public static List<String> parseArrayValue(String value) {\n    if (value == null) {\n      return new ArrayList<>(0);\n    }\n    String[] tokens = value.split(\",\");\n    List<String> result = new ArrayList<>(tokens.length);\n    for (String t : tokens) {\n      result.add(t.trim());\n    }\n    return result;\n  }\n\n  public static Set<String> propertiesWithPrefix(Environment environment, String prefix) {\n    Set<String> result = new HashSet<>();\n    for (PropertySource<?> propertySource : ((ConfigurableEnvironment) environment).getPropertySources()) {\n      if (propertySource instanceof EnumerablePropertySource) {\n        for (String key : ((EnumerablePropertySource<?>) propertySource).getPropertyNames()) {\n          if (key.startsWith(prefix)) {\n            result.add(key);\n          }\n        }\n      }\n    }\n    return result;\n  }\n\n  public static Map<String, String> stringPropertiesWithPrefix(Environment environment, String prefix) {\n    Map<String, String> result = new HashMap<>();\n    for (PropertySource<?> propertySource : ((ConfigurableEnvironment) environment).getPropertySources()) {\n      if (propertySource instanceof EnumerablePropertySource) {\n        for (String key : ((EnumerablePropertySource<?>) propertySource).getPropertyNames()) {\n          if (key.startsWith(prefix)) {\n            result.put(key, environment.getProperty(key));\n          }\n        }\n      }\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/ConfigurationChangedEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Set;\n\n/**\n * This event is fired when configuration changed. And the change is already applied to Environment.\n *\n * Listeners can use Environment to get the latest value.\n */\npublic class ConfigurationChangedEvent {\n  private final Map<String, Object> added;\n\n  private final Map<String, Object> deleted;\n\n  private final Map<String, Object> updated;\n\n  private Set<String> changed;\n\n  private ConfigurationChangedEvent(Map<String, Object> added, Map<String, Object> updated,\n      Map<String, Object> deleted) {\n    this.added = added;\n    this.deleted = deleted;\n    this.updated = updated;\n    this.changed = new HashSet<>();\n    this.changed.addAll(added.keySet());\n    this.changed.addAll(updated.keySet());\n    this.changed.addAll(deleted.keySet());\n  }\n\n  public static ConfigurationChangedEvent createIncremental(Map<String, Object> latest, Map<String, Object> last) {\n    Map<String, Object> itemsCreated = new HashMap<>();\n    Map<String, Object> itemsDeleted = new HashMap<>();\n    Map<String, Object> itemsModified = new HashMap<>();\n\n    for (Map.Entry<String, Object> entry : latest.entrySet()) {\n      String itemKey = entry.getKey();\n      if (!last.containsKey(itemKey)) {\n        itemsCreated.put(itemKey, entry.getValue());\n      } else if (!Objects.equals(last.get(itemKey), latest.get(itemKey))) {\n        itemsModified.put(itemKey, entry.getValue());\n      }\n    }\n    for (String itemKey : last.keySet()) {\n      if (!latest.containsKey(itemKey)) {\n        itemsDeleted.put(itemKey, null);\n      }\n    }\n    ConfigurationChangedEvent event = ConfigurationChangedEvent\n        .createIncremental(itemsCreated, itemsModified, itemsDeleted);\n    return event;\n  }\n\n  public static ConfigurationChangedEvent createIncremental(Map<String, Object> added, Map<String, Object> updated,\n      Map<String, Object> deleted) {\n    return new ConfigurationChangedEvent(added, updated, deleted);\n  }\n\n  public static ConfigurationChangedEvent createIncremental(Map<String, Object> updated) {\n    return new ConfigurationChangedEvent(new HashMap<>(), updated, new HashMap<>());\n  }\n\n  public final Map<String, Object> getAdded() {\n    return added;\n  }\n\n\n  public final Map<String, Object> getUpdated() {\n    return updated;\n  }\n\n\n  public final Map<String, Object> getDeleted() {\n    return deleted;\n  }\n\n  public final Set<String> getChanged() {\n    return changed;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DataCenterProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config;\n\npublic class DataCenterProperties {\n  public static final String PREFIX = \"servicecomb.datacenter\";\n\n  private String name;\n\n  private String region;\n\n  private String availableZone;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getRegion() {\n    return region;\n  }\n\n  public void setRegion(String region) {\n    this.region = region;\n  }\n\n  public String getAvailableZone() {\n    return availableZone;\n  }\n\n  public void setAvailableZone(String availableZone) {\n    this.availableZone = availableZone;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.IntConsumer;\nimport java.util.function.LongConsumer;\n\npublic interface DynamicProperties {\n  default String getStringProperty(String propertyName, Consumer<String> consumer, String defaultValue) {\n    return defaultValue;\n  }\n\n  default String getStringProperty(String propertyName, String defaultValue) {\n    return defaultValue;\n  }\n\n  default int getIntProperty(String propertyName, IntConsumer consumer, int defaultValue) {\n    return defaultValue;\n  }\n\n  default int getIntProperty(String propertyName, int defaultValue) {\n    return defaultValue;\n  }\n\n  default long getLongProperty(String propertyName, LongConsumer consumer, long defaultValue) {\n    return defaultValue;\n  }\n\n  default long getLongProperty(String propertyName, long defaultValue) {\n    return defaultValue;\n  }\n\n  default float getFloatProperty(String propertyName, DoubleConsumer consumer, float defaultValue) {\n    return defaultValue;\n  }\n\n  default float getFloatProperty(String propertyName, float defaultValue) {\n    return defaultValue;\n  }\n\n  default double getDoubleProperty(String propertyName, DoubleConsumer consumer, double defaultValue) {\n    return defaultValue;\n  }\n\n  default double getDoubleProperty(String propertyName, double defaultValue) {\n    return defaultValue;\n  }\n\n  default boolean getBooleanProperty(String propertyName, Consumer<Boolean> consumer, boolean defaultValue) {\n    return defaultValue;\n  }\n\n  default boolean getBooleanProperty(String propertyName, boolean defaultValue) {\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicPropertiesImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.IntConsumer;\nimport java.util.function.LongConsumer;\n\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic class DynamicPropertiesImpl implements DynamicProperties {\n  private static class Holder<C, D> {\n    C callback;\n\n    D defaultValue;\n\n    Holder(C callback, D defaultValue) {\n      this.callback = callback;\n      this.defaultValue = defaultValue;\n    }\n  }\n\n  private final Map<String, Set<Holder<Consumer<String>, String>>> stringCallbacks = new ConcurrentHashMap<>();\n\n  private final Map<String, Set<Holder<IntConsumer, Integer>>> intCallbacks = new ConcurrentHashMap<>();\n\n  private final Map<String, Set<Holder<LongConsumer, Long>>> longCallbacks = new ConcurrentHashMap<>();\n\n  private final Map<String, Set<Holder<DoubleConsumer, Float>>> floatCallbacks = new ConcurrentHashMap<>();\n\n  private final Map<String, Set<Holder<DoubleConsumer, Double>>> doubleCallbacks = new ConcurrentHashMap<>();\n\n  private final Map<String, Set<Holder<Consumer<Boolean>, Boolean>>> booleanCallbacks = new ConcurrentHashMap<>();\n\n  private final Environment environment;\n\n  public DynamicPropertiesImpl(Environment environment) {\n    this.environment = environment;\n    EventManager.register(this);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (Entry<String, Object> entry : event.getAdded().entrySet()) {\n      updateValue(entry);\n    }\n\n    for (Entry<String, Object> entry : event.getUpdated().entrySet()) {\n      updateValue(entry);\n    }\n\n    for (Entry<String, Object> entry : event.getDeleted().entrySet()) {\n      updateValue(entry);\n    }\n  }\n\n  private void updateValue(Entry<String, Object> entry) {\n    if (stringCallbacks.containsKey(entry.getKey())) {\n      for (Holder<Consumer<String>, String> callbacks : stringCallbacks.get(entry.getKey())) {\n        callbacks.callback.accept(environment.getProperty(entry.getKey(), callbacks.defaultValue));\n      }\n    }\n    if (intCallbacks.containsKey(entry.getKey())) {\n      for (Holder<IntConsumer, Integer> callbacks : intCallbacks.get(entry.getKey())) {\n        callbacks.callback.accept(environment.getProperty(entry.getKey(), Integer.class, callbacks.defaultValue));\n      }\n    }\n    if (longCallbacks.containsKey(entry.getKey())) {\n      for (Holder<LongConsumer, Long> callbacks : longCallbacks.get(entry.getKey())) {\n        callbacks.callback.accept(environment.getProperty(entry.getKey(), Long.class, callbacks.defaultValue));\n      }\n    }\n    if (floatCallbacks.containsKey(entry.getKey())) {\n      for (Holder<DoubleConsumer, Float> callbacks : floatCallbacks.get(entry.getKey())) {\n        callbacks.callback.accept(environment.getProperty(entry.getKey(), Float.class, callbacks.defaultValue));\n      }\n    }\n    if (doubleCallbacks.containsKey(entry.getKey())) {\n      for (Holder<DoubleConsumer, Double> callbacks : doubleCallbacks.get(entry.getKey())) {\n        callbacks.callback.accept(environment.getProperty(entry.getKey(), Double.class, callbacks.defaultValue));\n      }\n    }\n    if (booleanCallbacks.containsKey(entry.getKey())) {\n      for (Holder<Consumer<Boolean>, Boolean> callbacks : booleanCallbacks.get(entry.getKey())) {\n        callbacks.callback.accept(environment.getProperty(entry.getKey(), Boolean.class, callbacks.defaultValue));\n      }\n    }\n  }\n\n  @Override\n  public String getStringProperty(String propertyName, Consumer<String> consumer, String defaultValue) {\n    stringCallbacks.computeIfAbsent(propertyName, key -> new HashSet<>()).add(new Holder<>(consumer, defaultValue));\n    return environment.getProperty(propertyName, defaultValue);\n  }\n\n  @Override\n  public String getStringProperty(String propertyName, String defaultValue) {\n    return environment.getProperty(propertyName, defaultValue);\n  }\n\n  @Override\n  public int getIntProperty(String propertyName, IntConsumer consumer, int defaultValue) {\n    intCallbacks.computeIfAbsent(propertyName, key -> new HashSet<>()).add(new Holder<>(consumer, defaultValue));\n    return environment.getProperty(propertyName, int.class, defaultValue);\n  }\n\n  @Override\n  public int getIntProperty(String propertyName, int defaultValue) {\n    return environment.getProperty(propertyName, int.class, defaultValue);\n  }\n\n  @Override\n  public long getLongProperty(String propertyName, LongConsumer consumer, long defaultValue) {\n    longCallbacks.computeIfAbsent(propertyName, key -> new HashSet<>()).add(new Holder<>(consumer, defaultValue));\n    return environment.getProperty(propertyName, long.class, defaultValue);\n  }\n\n  @Override\n  public long getLongProperty(String propertyName, long defaultValue) {\n    return environment.getProperty(propertyName, long.class, defaultValue);\n  }\n\n  @Override\n  public float getFloatProperty(String propertyName, DoubleConsumer consumer, float defaultValue) {\n    floatCallbacks.computeIfAbsent(propertyName, key -> new HashSet<>()).add(new Holder<>(consumer, defaultValue));\n    return environment.getProperty(propertyName, float.class, defaultValue);\n  }\n\n  @Override\n  public float getFloatProperty(String propertyName, float defaultValue) {\n    return environment.getProperty(propertyName, float.class, defaultValue);\n  }\n\n  @Override\n  public double getDoubleProperty(String propertyName, DoubleConsumer consumer, double defaultValue) {\n    doubleCallbacks.computeIfAbsent(propertyName, key -> new HashSet<>()).add(new Holder<>(consumer, defaultValue));\n    return environment.getProperty(propertyName, double.class, defaultValue);\n  }\n\n  @Override\n  public double getDoubleProperty(String propertyName, double defaultValue) {\n    return environment.getProperty(propertyName, double.class, defaultValue);\n  }\n\n  @Override\n  public boolean getBooleanProperty(String propertyName, Consumer<Boolean> consumer, boolean defaultValue) {\n    booleanCallbacks.computeIfAbsent(propertyName, key -> new HashSet<>()).add(new Holder<>(consumer, defaultValue));\n    return environment.getProperty(propertyName, boolean.class, defaultValue);\n  }\n\n  @Override\n  public boolean getBooleanProperty(String propertyName, boolean defaultValue) {\n    return environment.getProperty(propertyName, boolean.class, defaultValue);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config;\n\nimport org.springframework.core.Ordered;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.PropertySource;\n\n/**\n * SPI to add new DynamicPropertiesSource.\n */\npublic interface DynamicPropertiesSource extends Ordered {\n  PropertySource<?> create(Environment environment);\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/FoundationConfigConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config;\n\nimport org.apache.servicecomb.config.inject.InjectBeanPostProcessor;\nimport org.apache.servicecomb.config.priority.ConfigObjectFactory;\nimport org.apache.servicecomb.config.priority.PriorityPropertyFactory;\nimport org.apache.servicecomb.config.priority.PriorityPropertyManager;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.Lazy;\nimport org.springframework.core.env.Environment;\n\n@Configuration\n@SuppressWarnings(\"unused\")\npublic class FoundationConfigConfiguration {\n  @Bean\n  public static InjectBeanPostProcessor scbInjectBeanPostProcessor(\n      @Autowired @Lazy PriorityPropertyManager priorityPropertyManager) {\n    return new InjectBeanPostProcessor(priorityPropertyManager);\n  }\n\n  @Bean\n  public PriorityPropertyManager scbPriorityPropertyManager(ConfigObjectFactory configObjectFactory) {\n    return new PriorityPropertyManager(configObjectFactory);\n  }\n\n  @Bean\n  public PriorityPropertyFactory scbPriorityPropertyFactory(Environment environment) {\n    return new PriorityPropertyFactory(environment);\n  }\n\n  @Bean\n  public DynamicPropertiesImpl scbDynamicProperties(Environment environment) {\n    return new DynamicPropertiesImpl(environment);\n  }\n\n  @Bean\n  public ConfigObjectFactory scbConfigObjectFactory(PriorityPropertyFactory propertyFactory) {\n    return new ConfigObjectFactory(propertyFactory);\n  }\n\n  @Bean\n  @ConfigurationProperties(prefix = DataCenterProperties.PREFIX)\n  public DataCenterProperties scbDataCenterProperties() {\n    return new DataCenterProperties();\n  }\n\n  @Bean\n  public InMemoryDynamicPropertiesSource scbInMemoryDynamicPropertiesSource() {\n    return new InMemoryDynamicPropertiesSource();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/InMemoryDynamicPropertiesSource.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.PropertySource;\n\n/**\n * This DynamicPropertiesSource is created for easier system tests.\n */\npublic class InMemoryDynamicPropertiesSource implements DynamicPropertiesSource {\n  public static final String SOURCE_NAME = \"in-memory\";\n\n  private static final Map<String, Object> DYNAMIC = new HashMap<>();\n\n  @Override\n  public PropertySource<?> create(Environment environment) {\n    return new MapPropertySource(SOURCE_NAME, DYNAMIC);\n  }\n\n  @Override\n  public int getOrder() {\n    return -100;\n  }\n\n  public static void update(String key, Object value) {\n    DYNAMIC.put(key, value);\n\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(key, value);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n  }\n\n  public static void reset() {\n    DYNAMIC.clear();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/YAMLUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.io.InputStream;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport org.yaml.snakeyaml.LoaderOptions;\nimport org.yaml.snakeyaml.TypeDescription;\nimport org.yaml.snakeyaml.Yaml;\nimport org.yaml.snakeyaml.constructor.Constructor;\nimport org.yaml.snakeyaml.constructor.SafeConstructor;\n\npublic final class YAMLUtil {\n  private YAMLUtil() {\n  }\n\n  private static Yaml safeParser() {\n    // Yaml instance is not thread safe, create a new instance for each parser\n    return new Yaml(new SafeConstructor(new LoaderOptions()));\n  }\n\n  /**\n   * load a input {@link InputStream} to be a map {@link Map}, you have to close the inputStream by yourself, such as:<br>\n   * <p>try (InputStream in = url.openStream()) {<br>\n   *   &nbsp;&nbsp;&nbsp;&nbsp;    configMap.putAll(YAMLUtil.yaml2Properties(in));<br>\n   *     }<br>\n   * </p>\n   * @param input the stream to be loaded\n   * @return a config map\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static Map<String, Object> yaml2Properties(InputStream input) {\n    Map<String, Object> configurations = new LinkedHashMap<>();\n    safeParser().loadAll(input).forEach(data -> {\n      if (data instanceof Map && isValidMap((Map<Object, Object>) data)) {\n        configurations.putAll(retrieveItems(\"\", (Map<String, Object>) data));\n      } else {\n        throw new IllegalArgumentException(\"input cannot be convert to map\");\n      }\n    });\n    return configurations;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private static boolean isValidMap(Map<Object, Object> data) {\n    for (Map.Entry<Object, Object> entry : data.entrySet()) {\n      Object key = entry.getKey();\n      Object value = entry.getValue();\n      if (key instanceof String) {\n        if (value instanceof Map) {\n          return isValidMap((Map<Object, Object>) value);\n        }\n        continue;\n      }\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * load a input {@link String} to be a map {@link Map}\n   * @param input the String to be loaded\n   * @return a config map\n   */\n  @SuppressWarnings(\"unchecked\")\n  public static Map<String, Object> yaml2Properties(String input) {\n    Map<String, Object> configurations = new LinkedHashMap<>();\n    safeParser().loadAll(input).forEach(data -> {\n      if (data instanceof Map && isValidMap((Map<Object, Object>) data)) {\n        configurations.putAll(retrieveItems(\"\", (Map<String, Object>) data));\n      } else {\n        throw new IllegalArgumentException(\"input cannot be convert to map\");\n      }\n    });\n    return configurations;\n  }\n\n  public static <T> T parserObject(String yamlContent, Class<T> clazz) {\n    Yaml parser = new Yaml(new Constructor(new TypeDescription(clazz, clazz), new LoaderOptions()));\n    return parser.loadAs(yamlContent, clazz);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static Map<String, Object> retrieveItems(String prefix, Map<String, Object> propertiesMap) {\n    Map<String, Object> result = new LinkedHashMap<>();\n    if (!prefix.isEmpty()) {\n      prefix += \".\";\n    }\n\n    for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {\n      if (entry.getValue() instanceof Map) {\n        result.putAll(retrieveItems(prefix + entry.getKey(), (Map<String, Object>) entry.getValue()));\n      } else {\n        String key = prefix + entry.getKey();\n        result.put(key, entry.getValue());\n      }\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/file/AbstractConfigLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.file;\n\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Enumeration;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.JvmUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.ResourceUtils;\n\npublic abstract class AbstractConfigLoader {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractConfigLoader.class);\n\n  public static final String ORDER_KEY = \"servicecomb-config-order\";\n\n  protected final List<ConfigModel> configModels = new ArrayList<>();\n\n  public List<ConfigModel> getConfigModels() {\n    return configModels;\n  }\n\n  public void load(String resourceName) throws IOException {\n    loadFromClassPath(resourceName);\n  }\n\n  protected void loadFromClassPath(String resourceName) throws IOException {\n    List<URL> urlList = findURLFromClassPath(resourceName);\n    for (URL url : urlList) {\n      ConfigModel configModel = load(url);\n      configModels.add(configModel);\n    }\n  }\n\n  public ConfigModel load(URL url) throws IOException {\n    Map<String, Object> config = loadData(url);\n    // load a empty or all commented yaml, will get a null map\n    // this is not an error\n    if (config == null) {\n      config = new LinkedHashMap<>();\n    }\n\n    ConfigModel configModel = new ConfigModel();\n    configModel.setUrl(url);\n    configModel.setConfig(config);\n\n    Object objOrder = config.get(ORDER_KEY);\n    if (objOrder == null) {\n      // compatible check\n      objOrder = config.get(\"cse-config-order\");\n      if (objOrder != null) {\n        LOGGER.error(\"cse-config-order will not be supported in future, please change it to servicecomb-config-order\");\n      }\n    }\n\n    if (objOrder != null) {\n      if (Integer.class.isInstance(objOrder)) {\n        configModel.setOrder((int) objOrder);\n      } else {\n        configModel.setOrder(Integer.parseInt(String.valueOf(objOrder)));\n      }\n    }\n    return configModel;\n  }\n\n  protected abstract Map<String, Object> loadData(URL url) throws IOException;\n\n  protected List<URL> findURLFromClassPath(String resourceName) throws IOException {\n    List<URL> urlList = new ArrayList<>();\n\n    ClassLoader loader = JvmUtils.findClassLoader();\n    Enumeration<URL> urls = loader.getResources(resourceName);\n    while (urls.hasMoreElements()) {\n      urlList.add(urls.nextElement());\n    }\n\n    return urlList;\n  }\n\n  private static class ConfigModelWrapper {\n    ConfigModel model;\n\n    int addOrder;\n  }\n\n  // sort rule:\n  // 1.files in jar\n  // 2.smaller order\n  // 3.add to list earlier\n  protected void sort() {\n    List<ConfigModelWrapper> list = new ArrayList<>(configModels.size());\n    for (int idx = 0; idx < configModels.size(); idx++) {\n      ConfigModelWrapper wrapper = new ConfigModelWrapper();\n      wrapper.model = configModels.get(idx);\n      wrapper.addOrder = idx;\n      list.add(wrapper);\n    }\n\n    list.sort(this::doSort);\n\n    for (int idx = 0; idx < configModels.size(); idx++) {\n      configModels.set(idx, list.get(idx).model);\n    }\n  }\n\n  private int doSort(ConfigModelWrapper w1, ConfigModelWrapper w2) {\n    ConfigModel m1 = w1.model;\n    ConfigModel m2 = w2.model;\n    boolean isM1Jar = ResourceUtils.isJarURL(m1.getUrl());\n    boolean isM2Jar = ResourceUtils.isJarURL(m2.getUrl());\n    if (isM1Jar != isM2Jar) {\n      if (isM1Jar) {\n        return -1;\n      }\n\n      return 1;\n    }\n    // min order load first\n    int result = Integer.compare(m1.getOrder(), m2.getOrder());\n    if (result != 0) {\n      return result;\n    }\n\n    return doFinalSort(w1, w2);\n  }\n\n  private int doFinalSort(ConfigModelWrapper w1, ConfigModelWrapper w2) {\n    return Integer.compare(w1.addOrder, w2.addOrder);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/file/ConfigModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.file;\n\nimport java.net.URL;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.IOUtils;\n\npublic class ConfigModel {\n\n  private URL url;\n\n  private int order;\n\n  private Map<String, Object> config;\n\n  public URL getUrl() {\n    return url;\n  }\n\n  public void setUrl(URL url) {\n    this.url = url;\n  }\n\n  public int getOrder() {\n    return order;\n  }\n\n  public void setOrder(int order) {\n    this.order = order;\n  }\n\n  public Map<String, Object> getConfig() {\n    return config;\n  }\n\n  public void setConfig(Map<String, Object> config) {\n    this.config = config;\n  }\n\n  @Override\n  public String toString() {\n    return url == null ? \"\" : IOUtils.anonymousPath(url.toString());\n  }\n\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/file/MicroserviceConfigLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.file;\n\nimport java.io.IOException;\nimport java.net.URL;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n\npublic class MicroserviceConfigLoader extends YAMLConfigLoader {\n  private static final Logger LOGGER = LoggerFactory.getLogger(MicroserviceConfigLoader.class);\n\n  private static final String ADDITIONAL_CONFIG_URL = \"servicecomb.configurationSource.additionalUrls\";\n\n  private static final String DEFAULT_FILE_NAME = \"servicecomb.configurationSource.defaultFileName\";\n\n  /**\n   * Default configuration file name to be used by default constructor. This file should\n   * be on the classpath. The file name can be overridden by the value of system property\n   * <code>configurationSource.defaultFileName</code>\n   */\n  private static final String DEFAULT_CONFIG_FILE_NAME = \"microservice.yaml\";\n\n  public MicroserviceConfigLoader() {\n    // Help to resolve incompatible changes. Can be deleted in future.\n    if (!StringUtils.isEmpty(System.getProperty(\"cse.configurationSource.additionalUrls\"))) {\n      throw new IllegalArgumentException(\"-Dcse.configurationSource.additionalUrls\"\n          + \" has been replaced with -D\" + ADDITIONAL_CONFIG_URL + \", please change it and restart.\");\n    }\n    if (!StringUtils.isEmpty(System.getProperty(\"cse.configurationSource.defaultFileName\"))) {\n      throw new IllegalArgumentException(\"-Dcse.configurationSource.additionalUrls\"\n          + \" has been replaced with -D\" + DEFAULT_FILE_NAME + \", please change it and restart.\");\n    }\n  }\n\n  public void loadAndSort() {\n    String configFileFromClasspath = null;\n    try {\n      configFileFromClasspath =\n          System.getProperty(DEFAULT_FILE_NAME) == null ? DEFAULT_CONFIG_FILE_NAME\n              : System.getProperty(DEFAULT_FILE_NAME);\n      super.load(configFileFromClasspath);\n      loadAdditionalConfig();\n\n      if (configModels.isEmpty()) {\n        LOGGER.warn(\"No URLs will be polled as dynamic configuration sources.\");\n        LOGGER.warn(\n            \"To enable URLs as dynamic configuration sources, define System property {} or make {} available on classpath.\",\n            ADDITIONAL_CONFIG_URL,\n            configFileFromClasspath);\n      }\n\n      sort();\n    } catch (Exception e) {\n      throw new ServiceCombException(\"Failed to load microservice configFile \" + configFileFromClasspath, e);\n    }\n  }\n\n  private void loadAdditionalConfig() throws IOException {\n    String strUrls = System.getProperty(ADDITIONAL_CONFIG_URL);\n    if (StringUtils.isEmpty(strUrls)) {\n      return;\n    }\n\n    for (String strUrl : strUrls.split(\",\")) {\n      URL url = new URL(strUrl);\n      ConfigModel configModel = load(url);\n      configModels.add(configModel);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/file/YAMLConfigLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.file;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.YAMLUtil;\n\npublic class YAMLConfigLoader extends AbstractConfigLoader {\n  @Override\n  protected Map<String, Object> loadData(URL url) throws IOException {\n    try (InputStream inputStream = url.openStream()) {\n      return YAMLUtil.yaml2Properties(inputStream);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/inject/InjectBeanPostProcessor.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config.inject;\r\n\r\nimport java.util.Collections;\r\n\r\nimport org.apache.servicecomb.config.priority.PriorityPropertyManager;\r\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\r\nimport org.springframework.beans.BeansException;\r\nimport org.springframework.beans.factory.config.BeanPostProcessor;\r\n\r\npublic class InjectBeanPostProcessor implements BeanPostProcessor {\r\n  private final PriorityPropertyManager priorityPropertyManager;\r\n\r\n  public InjectBeanPostProcessor(PriorityPropertyManager priorityPropertyManager) {\r\n    this.priorityPropertyManager = priorityPropertyManager;\r\n  }\r\n\r\n  @Override\r\n  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {\r\n    Class<?> beanCls = BeanUtils.getImplClassFromBean(bean);\r\n    InjectProperties injectProperties = beanCls.getAnnotation(InjectProperties.class);\r\n    if (injectProperties == null) {\r\n      return bean;\r\n    }\r\n\r\n    priorityPropertyManager.createConfigObject(bean, Collections.emptyMap());\r\n\r\n    return bean;\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/inject/InjectProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.inject;\n\nimport static java.lang.annotation.ElementType.TYPE;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\n@Documented\n@Retention(RUNTIME)\n@Target(TYPE)\n@Inherited\npublic @interface InjectProperties {\n  /**\n   * The name prefix of the properties that are valid to bind to this object.\n   * @return the name prefix of the properties to bind\n   */\n  String prefix() default \"\";\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/inject/InjectProperty.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.inject;\n\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\n@Documented\n@Retention(RUNTIME)\n@Target(FIELD)\npublic @interface InjectProperty {\n  /**\n   * override prefix of {@link InjectProperties}\n   * @return prefix of keys\n   */\n  String prefix() default \"\";\n\n  /**\n   * <pre>\n   * The name of the property\n   * 1.support priority\n   *   high,middle,low\n   * 2.support placeholder\n   *   name is root.${placeholder-1}.name\n   *   placeholder-1 is k1\n   *   then final name is root.k1.name\n   * 3.placeholder can be a list\n   *   name is root.${placeholder-1}.name\n   *   placeholder-1 is a list, value is k1-1/k1-2\n   *   then final name is root.k1-1.name/root.k1-2.name\n   * </pre>\n   * @return the name of the property\n   */\n  String[] keys() default {};\n\n  String defaultValue() default \"\";\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/inject/PlaceholderResolver.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.inject;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\n\n/**\n * <pre>\n * not care for performance\n *\n * behavior of multiple list if defined:\n *   org.apache.servicecomb.config.inject.TestPlaceholderResolver#multi_list()\n * behavior of nested and multiple list variable is undefined\n *   org.apache.servicecomb.config.inject.TestPlaceholderResolver#mixed()\n * </pre>\n */\npublic class PlaceholderResolver {\n  private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(\"(?<escape>\\\\\\\\)?\\\\$\\\\{(?<name>[^{}]+)\\\\}\");\n\n  static class SplitPart {\n    boolean var;\n\n    String fullName;\n\n    Object value;\n\n    public SplitPart(boolean var, String fullName) {\n      this.var = var;\n      this.fullName = fullName;\n    }\n\n    @Override\n    public String toString() {\n      return \"SplitPart{\" +\n          \"var=\" + var +\n          \", fullName='\" + fullName + '\\'' +\n          \", value=\" + value +\n          '}';\n    }\n  }\n\n  static class Row {\n    List<SplitPart> parts = new ArrayList<>();\n\n    int cartesianProductCount = 1;\n\n    int varCount = 0;\n  }\n\n  public String replaceFirst(String str) {\n    return replace(str, Collections.emptyMap()).get(0);\n  }\n\n  public String replaceFirst(String str, Map<String, Object> parameters) {\n    return replace(str, parameters).get(0);\n  }\n\n  public List<String> replace(String str, Map<String, Object> parameters) {\n    List<Row> finalRows = replaceToRows(str, parameters);\n\n    List<String> replaced = new ArrayList<>();\n    for (Row row : finalRows) {\n      resolve(row, replaced);\n    }\n\n    replaced.replaceAll(s -> s.replace(\"\\\\$\", \"$\"));\n    return replaced;\n  }\n\n  private List<Row> replaceToRows(String str, Map<String, Object> parameters) {\n    List<Row> finalRows = new ArrayList<>();\n    List<String> remainRows = new ArrayList<>();\n    replaceToRows(str, parameters, remainRows, finalRows);\n\n    for (String row : remainRows) {\n      List<Row> nestedRows = replaceToRows(row, parameters);\n      finalRows.addAll(nestedRows);\n    }\n    return finalRows;\n  }\n\n  private void replaceToRows(String str, Map<String, Object> parameters, List<String> remainRows,\n      List<Row> finalRows) {\n    Row row = parseToRow(str, parameters);\n    if (row.varCount == 0 && row.cartesianProductCount == 1) {\n      finalRows.add(row);\n      return;\n    }\n\n    resolve(row, remainRows);\n  }\n\n  private Row parseToRow(String str, Map<String, Object> parameters) {\n    Matcher matcher = PLACEHOLDER_PATTERN.matcher(str);\n    Row row = new Row();\n\n    int last = 0;\n    while (matcher.find()) {\n      row.parts.add(new SplitPart(false, str.substring(last, matcher.start())));\n      last = matcher.end();\n\n      if (matcher.group(\"escape\") != null) {\n        row.parts.add(new SplitPart(false, matcher.group().substring(1)));\n        continue;\n      }\n\n      String name = matcher.group(\"name\");\n      Object value = findValue(parameters, name);\n      if (value instanceof Collection) {\n        row.cartesianProductCount *= ((Collection) value).size();\n      }\n      if (value != null) {\n        row.varCount++;\n      }\n\n      SplitPart splitPart = new SplitPart(value != null, matcher.group());\n      splitPart.value = value;\n      row.parts.add(splitPart);\n    }\n    row.parts.add(new SplitPart(false, str.substring(last)));\n\n    return row;\n  }\n\n  // resolve placeholder and execute cartesian product\n  @SuppressWarnings(\"unchecked\")\n  private void resolve(Row row, List<String> resolvedRows) {\n    List<StringBuilder> stringBuilders = new ArrayList<>();\n    for (int idx = 0; idx < row.cartesianProductCount; idx++) {\n      stringBuilders.add(new StringBuilder());\n    }\n\n    int collectionRepeatCount = 1;\n    for (SplitPart part : row.parts) {\n      if (!part.var) {\n        for (int idx = 0; idx < row.cartesianProductCount; idx++) {\n          StringBuilder sb = stringBuilders.get(idx);\n\n          if (part.fullName.startsWith(\"$\")) {\n            sb.append(\"\\\\\" + part.fullName);\n            continue;\n          }\n\n          sb.append(part.fullName);\n        }\n        continue;\n      }\n\n      if (part.value instanceof Collection) {\n        int size = ((Collection<String>) part.value).size();\n        int rowRepeatCount = row.cartesianProductCount / size / collectionRepeatCount;\n\n        int valueIdx = 0;\n        for (int collectionRepeatIdx = 0; collectionRepeatIdx < collectionRepeatCount; collectionRepeatIdx++) {\n          for (String value : (Collection<String>) part.value) {\n            for (int repeatIdx = 0; repeatIdx < rowRepeatCount; repeatIdx++) {\n              StringBuilder sb = stringBuilders.get(valueIdx);\n              valueIdx++;\n              sb.append(value);\n            }\n          }\n        }\n\n        collectionRepeatCount *= size;\n        continue;\n      }\n\n      // normal var\n      for (int idx = 0; idx < row.cartesianProductCount; idx++) {\n        StringBuilder sb = stringBuilders.get(idx);\n        sb.append(part.value);\n      }\n    }\n\n    for (StringBuilder sb : stringBuilders) {\n      resolvedRows.add(sb.toString());\n    }\n  }\n\n  private Object findValue(Map<String, Object> parameters, String key) {\n    Object value = parameters.get(key);\n    if (value == null) {\n      value = LegacyPropertyFactory.getStringProperty(key);\n    }\n    return value;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/Parser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.parser;\n\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic interface Parser {\n  String CONTENT_TYPE_YAML = \"yaml\";\n  String CONTENT_TYPE_PROPERTIES = \"properties\";\n  String CONTENT_TYPE_RAW = \"raw\";\n\n  YamlParser yamlParser = new YamlParser();\n  PropertiesParser propertiesParser = new PropertiesParser();\n  RawParser rawParser = new RawParser();\n\n  Map<String, Object> parse(String content, String prefix, boolean addPrefix);\n\n  static Parser findParser(String contentType) {\n    switch (contentType) {\n      case CONTENT_TYPE_YAML:\n        return yamlParser;\n      case CONTENT_TYPE_PROPERTIES:\n        return propertiesParser;\n      case CONTENT_TYPE_RAW:\n        return rawParser;\n      default:\n        throw new IllegalArgumentException(\"not supported contentType=\" + contentType);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  static Map<String, Object> propertiesToMap(Properties properties, String prefix, boolean addPrefix) {\n    Map<String, Object> result = new HashMap<>();\n    Enumeration<String> keys = (Enumeration<String>) properties.propertyNames();\n    while (keys.hasMoreElements()) {\n      String key = keys.nextElement();\n      String value = properties.getProperty(key);\n\n      if (addPrefix && !StringUtils.isEmpty(prefix)) {\n        key = prefix + \".\" + key;\n      }\n\n      if (value == null) {\n        result.put(key, null);\n      } else {\n        result.put(key, value.trim());\n      }\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/PropertiesParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.parser;\n\nimport java.io.IOException;\nimport java.io.StringReader;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class PropertiesParser implements Parser {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesParser.class);\n\n  @Override\n  public Map<String, Object> parse(String content, String prefix, boolean addPrefix) {\n    Properties properties = new Properties();\n    try {\n      properties.load(new StringReader(content));\n    } catch (IOException e) {\n      LOGGER.error(\"parse properties content failed, message={}\", e.getMessage());\n    }\n    return Parser.propertiesToMap(properties, prefix, addPrefix);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/RawParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.parser;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class RawParser implements Parser {\n  @Override\n  public Map<String, Object> parse(String content, String prefix, boolean addPrefix) {\n    Map<String, Object> result = new HashMap<>();\n    result.put(prefix, content);\n    return result;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/YamlParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.parser;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.Map;\nimport java.util.Properties;\n\nimport org.springframework.beans.factory.config.YamlPropertiesFactoryBean;\nimport org.springframework.core.io.ByteArrayResource;\n\npublic class YamlParser implements Parser {\n  @Override\n  public Map<String, Object> parse(String content, String prefix, boolean addPrefix) {\n    YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();\n    yamlFactory.setResources(new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8)));\n    Properties properties = yamlFactory.getObject();\n    return Parser.propertiesToMap(properties, prefix, addPrefix);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/ConfigObject.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config.priority;\r\n\r\nimport java.util.List;\r\n\r\npublic class ConfigObject<T> {\r\n  private final T instance;\r\n\r\n  private final List<ConfigObjectProperty> properties;\r\n\r\n  public ConfigObject(T instance, List<ConfigObjectProperty> properties) {\r\n    this.instance = instance;\r\n    this.properties = properties;\r\n  }\r\n\r\n  public T getInstance() {\r\n    return instance;\r\n  }\r\n\r\n  public List<ConfigObjectProperty> getProperties() {\r\n    return properties;\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/ConfigObjectFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.priority;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.inject.InjectProperties;\nimport org.apache.servicecomb.config.inject.InjectProperty;\nimport org.apache.servicecomb.config.inject.PlaceholderResolver;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\n\nimport com.fasterxml.jackson.databind.BeanDescription;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\n/**\n * must create by PriorityPropertyManager<br>\n *   or register to PriorityPropertyManager manually<br>\n * <br>\n * ${} or ${not-exist-key} is valid key in archaius<br>\n * so this wrapper mechanism will not throw exception even can not find value by placeholder\n */\npublic class ConfigObjectFactory {\n  private final PriorityPropertyFactory propertyFactory;\n\n  private final Map<Class<?>, JavaType> classCache = new ConcurrentHashMapEx<>();\n\n  private final Map<JavaType, BeanDescription> javaTypeCache = new ConcurrentHashMapEx<>();\n\n  private final Map<BeanPropertyDefinition, Setter<Object, Object>> beanDescriptionCache = new ConcurrentHashMapEx<>();\n\n  public ConfigObjectFactory(PriorityPropertyFactory propertyFactory) {\n    this.propertyFactory = propertyFactory;\n  }\n\n  public PriorityPropertyFactory getPropertyFactory() {\n    return propertyFactory;\n  }\n\n  public <T> ConfigObject<T> create(Class<T> cls, Map<String, Object> parameters) {\n    try {\n      return create(cls.getDeclaredConstructor().newInstance(), parameters);\n    } catch (Throwable e) {\n      throw new IllegalStateException(\"create config object failed, class=\" + cls.getName(), e);\n    }\n  }\n\n  public <T> ConfigObject<T> create(T instance, Map<String, Object> parameters) {\n    String prefix = initPrefix(instance.getClass());\n    List<ConfigObjectProperty> properties = createProperties(instance, prefix, parameters);\n\n    return new ConfigObject<>(instance, properties);\n  }\n\n  private String initPrefix(Class<?> cls) {\n    InjectProperties injectProperties = cls.getAnnotation(InjectProperties.class);\n    if (injectProperties == null) {\n      return \"\";\n    }\n\n    String prefix = injectProperties.prefix();\n    if (prefix.isEmpty()) {\n      return \"\";\n    }\n    return prefix + \".\";\n  }\n\n  public List<ConfigObjectProperty> createProperties(Object instance, String prefix, Map<String, Object> parameters) {\n    List<ConfigObjectProperty> properties = new ArrayList<>();\n    JavaType javaType = classCache.computeIfAbsent(instance.getClass(), TypeFactory.defaultInstance()::constructType);\n    BeanDescription beanDescription = javaTypeCache.computeIfAbsent(javaType,\n        JsonUtils.OBJ_MAPPER.getSerializationConfig()::introspect);\n    for (BeanPropertyDefinition propertyDefinition : beanDescription.findProperties()) {\n      if (propertyDefinition.getField() == null) {\n        continue;\n      }\n\n      if (propertyDefinition.getSetter() == null && !propertyDefinition.getField().isPublic()) {\n        continue;\n      }\n\n      PriorityProperty<?> priorityProperty = createPriorityProperty(propertyDefinition.getField().getAnnotated(),\n          prefix, parameters);\n      if (priorityProperty == null) {\n        continue;\n      }\n      Setter<Object, Object> setter = beanDescriptionCache.computeIfAbsent(propertyDefinition,\n          LambdaMetafactoryUtils::createObjectSetter);\n      setter.set(instance, priorityProperty.getValue());\n      properties.add(new ConfigObjectProperty(setter, priorityProperty));\n    }\n    return properties;\n  }\n\n  private PriorityProperty<?> createPriorityProperty(Field field, String prefix, Map<String, Object> parameters) {\n    String[] keys = collectPropertyKeys(field, prefix, parameters);\n\n    Class<?> fieldCls = field.getType();\n    switch (fieldCls.getName()) {\n      case \"int\":\n        return createIntProperty(field, keys, 0);\n      case \"java.lang.Integer\":\n        return createIntProperty(field, keys, null);\n      case \"long\":\n        return createLongProperty(field, keys, 0L);\n      case \"java.lang.Long\":\n        return createLongProperty(field, keys, null);\n      case \"java.lang.String\":\n        return createStringProperty(field, keys);\n      case \"float\":\n        return createFloatProperty(field, keys, 0f);\n      case \"java.lang.Float\":\n        return createFloatProperty(field, keys, null);\n      case \"double\":\n        return createDoubleProperty(field, keys, 0.0);\n      case \"java.lang.Double\":\n        return createDoubleProperty(field, keys, null);\n      case \"boolean\":\n        return createBooleanProperty(field, keys, false);\n      case \"java.lang.Boolean\":\n        return createBooleanProperty(field, keys, null);\n      default:\n        return null;\n    }\n  }\n\n  private PriorityProperty<?> createStringProperty(Field field, String[] keys) {\n    String defaultValue = null;\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.defaultValue().isEmpty()) {\n        defaultValue = injectProperty.defaultValue();\n      }\n    }\n\n    return propertyFactory.getOrCreate(String.class, null, defaultValue, keys);\n  }\n\n  private PriorityProperty<?> createDoubleProperty(Field field, String[] keys, Double defaultValue) {\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.defaultValue().isEmpty()) {\n        defaultValue = Double.parseDouble(injectProperty.defaultValue());\n      }\n    }\n\n    return propertyFactory.getOrCreate(Double.class, null, defaultValue, keys);\n  }\n\n  private PriorityProperty<?> createFloatProperty(Field field, String[] keys, Float defaultValue) {\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.defaultValue().isEmpty()) {\n        defaultValue = Float.parseFloat(injectProperty.defaultValue());\n      }\n    }\n\n    return propertyFactory.getOrCreate(Float.class, null, defaultValue, keys);\n  }\n\n  private PriorityProperty<?> createBooleanProperty(Field field, String[] keys, Boolean defaultValue) {\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.defaultValue().isEmpty()) {\n        defaultValue = Boolean.parseBoolean(injectProperty.defaultValue());\n      }\n    }\n\n    return propertyFactory.getOrCreate(Boolean.class, null, defaultValue, keys);\n  }\n\n  private PriorityProperty<?> createLongProperty(Field field, String[] keys, Long defaultValue) {\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.defaultValue().isEmpty()) {\n        defaultValue = Long.parseLong(injectProperty.defaultValue());\n      }\n    }\n\n    return propertyFactory.getOrCreate(Long.class, null, defaultValue, keys);\n  }\n\n  private PriorityProperty<?> createIntProperty(Field field, String[] keys, Integer defaultValue) {\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.defaultValue().isEmpty()) {\n        defaultValue = Integer.parseInt(injectProperty.defaultValue());\n      }\n    }\n\n    return propertyFactory.getOrCreate(Integer.class, null, defaultValue, keys);\n  }\n\n  private String[] collectPropertyKeys(Field field, String prefix, Map<String, Object> parameters) {\n    String propertyPrefix = prefix;\n    String[] keys = new String[] {field.getName()};\n\n    InjectProperty injectProperty = field.getAnnotation(InjectProperty.class);\n    if (injectProperty != null) {\n      if (!injectProperty.prefix().isEmpty()) {\n        propertyPrefix = injectProperty.prefix() + \".\";\n      }\n      if (injectProperty.keys().length != 0) {\n        keys = injectProperty.keys();\n      }\n    }\n\n    List<String> finalKeys = new ArrayList<>();\n    for (String key : keys) {\n      List<String> resolvedKeys = new PlaceholderResolver().replace(propertyPrefix + key, parameters);\n      finalKeys.addAll(resolvedKeys);\n    }\n\n    return finalKeys.toArray(new String[0]);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/ConfigObjectProperty.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config.priority;\r\n\r\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\r\n\r\n/**\r\n * do not reference config object instance, otherwise gc for weak hash map will failed\r\n */\r\npublic class ConfigObjectProperty {\r\n  private final Setter<Object, Object> setter;\r\n\r\n  private final PriorityProperty<?> property;\r\n\r\n  public ConfigObjectProperty(Setter<Object, Object> setter, PriorityProperty<?> property) {\r\n    this.setter = setter;\r\n    this.property = property;\r\n  }\r\n\r\n  public void updateValueWhenChanged(Object instance, String changedKey) {\r\n    if (property.isChangedKey(changedKey)) {\r\n      property.updateValue();\r\n      setter.set(instance, property.getValue());\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/DynamicProperty.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.priority;\n\nimport org.springframework.core.env.Environment;\n\npublic class DynamicProperty {\n  private final Environment environment;\n\n  private final String propName;\n\n  public DynamicProperty(Environment environment, String propName) {\n    this.environment = environment;\n    this.propName = propName;\n  }\n\n  public Integer getInteger() {\n    return environment.getProperty(propName, Integer.class);\n  }\n\n  public Long getLong() {\n    return environment.getProperty(propName, Long.class);\n  }\n\n  public String getString() {\n    return environment.getProperty(propName);\n  }\n\n  public Boolean getBoolean() {\n    return environment.getProperty(propName, Boolean.class);\n  }\n\n  public Double getDouble() {\n    return environment.getProperty(propName, Double.class);\n  }\n\n  public Float getFloat() {\n    return environment.getProperty(propName, Float.class);\n  }\n\n  public String getName() {\n    return propName;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/PriorityProperty.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.priority;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.Objects;\nimport java.util.function.Function;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\n/**\n * must create by PriorityPropertyManager<br>\n *   or register to PriorityPropertyManager manually\n * @param <T>\n */\npublic final class PriorityProperty<T> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PriorityProperty.class);\n\n  private final PriorityPropertyType<T> propertyType;\n\n  private final String joinedPriorityKeys;\n\n  private final Function<DynamicProperty, T> internalValueReader;\n\n  private final DynamicProperty[] properties;\n\n  private T finalValue;\n\n  public PriorityProperty(Environment environment, PriorityPropertyType<T> propertyType) {\n    this.propertyType = propertyType;\n    this.joinedPriorityKeys = Arrays.toString(propertyType.getPriorityKeys());\n    this.internalValueReader = collectReader(propertyType.getType());\n    this.properties = createProperties(environment, propertyType.getPriorityKeys());\n    initValue();\n  }\n\n  private DynamicProperty[] createProperties(Environment environment, String[] priorityKeys) {\n    DynamicProperty[] properties = new DynamicProperty[priorityKeys.length];\n    for (int idx = 0; idx < priorityKeys.length; idx++) {\n      String key = priorityKeys[idx].trim();\n      properties[idx] = new DynamicProperty(environment, key);\n    }\n    return properties;\n  }\n\n  private Function<DynamicProperty, T> collectReader(Type type) {\n    if (type == int.class || type == Integer.class) {\n      return this::readInt;\n    }\n\n    if (type == long.class || type == Long.class) {\n      return this::readLong;\n    }\n\n    if (type == String.class) {\n      return this::readString;\n    }\n\n    if (type == boolean.class || type == Boolean.class) {\n      return this::readBoolean;\n    }\n\n    if (type == double.class || type == Double.class) {\n      return this::readDouble;\n    }\n\n    if (type == float.class || type == Float.class) {\n      return this::readFloat;\n    }\n\n    throw new IllegalStateException(\"not support, type=\" + type.getTypeName());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private T readInt(DynamicProperty property) {\n    return (T) property.getInteger();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private T readLong(DynamicProperty property) {\n    return (T) property.getLong();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private T readString(DynamicProperty property) {\n    return (T) property.getString();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private T readBoolean(DynamicProperty property) {\n    return (T) property.getBoolean();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private T readDouble(DynamicProperty property) {\n    return (T) property.getDouble();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private T readFloat(DynamicProperty property) {\n    return (T) property.getFloat();\n  }\n\n  public String[] getPriorityKeys() {\n    return propertyType.getPriorityKeys();\n  }\n\n  public T getDefaultValue() {\n    return propertyType.getDefaultValue();\n  }\n\n  public DynamicProperty[] getProperties() {\n    return properties;\n  }\n\n  void initValue() {\n    String effectiveKey = doUpdateFinalValue();\n    LOGGER.debug(\"config inited, \\\"{}\\\" set to {}, effective key is \\\"{}\\\".\",\n        joinedPriorityKeys, finalValue, effectiveKey);\n  }\n\n  synchronized boolean updateValue() {\n    T lastValue = finalValue;\n    String effectiveKey = doUpdateFinalValue();\n    if (effectiveKey != null) {\n      LOGGER.debug(\"config changed, \\\"{}\\\" changed from {} to {}, effective key is \\\"{}\\\".\",\n          joinedPriorityKeys, lastValue, finalValue, effectiveKey);\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   *\n   * @return if value changed, return effectiveKey, otherwise null\n   */\n  private String doUpdateFinalValue() {\n    T lastValue = finalValue;\n\n    String effectiveKey = \"default value\";\n    T value = propertyType.getDefaultValue();\n    for (DynamicProperty property : properties) {\n      T propValue = internalValueReader.apply(property);\n      if (propValue == null || propValue.equals(propertyType.getInvalidValue())) {\n        continue;\n      }\n\n      effectiveKey = property.getName();\n      value = propValue;\n      break;\n    }\n\n    if (Objects.equals(lastValue, value)) {\n      return null;\n    }\n\n    finalValue = value;\n    return effectiveKey;\n  }\n\n  public T getValue() {\n    return finalValue;\n  }\n\n  public boolean isChangedKey(String changedKey) {\n    if (changedKey == null) {\n      // property source changed or clear, and so on\n      return true;\n    }\n\n    for (DynamicProperty property : properties) {\n      if (changedKey.equals(property.getName())) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/PriorityPropertyFactory.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config.priority;\r\n\r\nimport java.lang.reflect.Type;\r\nimport java.util.Map;\r\nimport java.util.stream.Stream;\r\n\r\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\r\nimport org.springframework.core.env.Environment;\r\n\r\nimport com.google.common.annotations.VisibleForTesting;\r\n\r\npublic class PriorityPropertyFactory {\r\n  private final Map<PriorityPropertyType<?>, PriorityProperty<?>> properties = new ConcurrentHashMapEx<>();\r\n\r\n  private final Environment environment;\r\n\r\n  public PriorityPropertyFactory(Environment environment) {\r\n    this.environment = environment;\r\n  }\r\n\r\n  @VisibleForTesting\r\n  public Stream<PriorityProperty<?>> getProperties() {\r\n    return properties.values().stream();\r\n  }\r\n\r\n  @SuppressWarnings(\"unchecked\")\r\n  public <T> PriorityProperty<T> getOrCreate(Type type, T invalidValue, T defaultValue, String... priorityKeys) {\r\n    PriorityPropertyType<T> propertyType = new PriorityPropertyType<>(type, invalidValue, defaultValue, priorityKeys);\r\n    return (PriorityProperty<T>) properties.computeIfAbsent(propertyType,\r\n        key -> new PriorityProperty<>(environment, key));\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/PriorityPropertyManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.priority;\n\nimport static java.util.Collections.synchronizedMap;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.WeakHashMap;\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.eventbus.Subscribe;\n\npublic class PriorityPropertyManager {\n  private final ConfigObjectFactory configObjectFactory;\n\n  // key is config object instance\n  // value is properties of the config object instance\n  private final Map<Object, List<ConfigObjectProperty>> configObjectMap = synchronizedMap(new WeakHashMap<>());\n\n  public PriorityPropertyManager(ConfigObjectFactory configObjectFactory) {\n    this.configObjectFactory = configObjectFactory;\n    EventManager.register(this);\n  }\n\n  public PriorityPropertyFactory getPropertyFactory() {\n    return configObjectFactory.getPropertyFactory();\n  }\n\n  public void close() {\n\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    // just loop all properties, it's very fast, no need to do any optimize\n    for (Entry<Object, List<ConfigObjectProperty>> entry : configObjectMap.entrySet()) {\n      Object instance = entry.getKey();\n      entry.getValue().forEach(\n          configObjectProperty -> {\n            for (String updatedKey : event.getChanged()) {\n              configObjectProperty.updateValueWhenChanged(instance, updatedKey);\n            }\n          });\n    }\n  }\n\n  @VisibleForTesting\n  public Map<Object, List<ConfigObjectProperty>> getConfigObjectMap() {\n    return configObjectMap;\n  }\n\n  public <T> T createConfigObject(Class<T> cls, Object... kvs) {\n    Map<String, Object> parameters = new HashMap<>();\n    for (int idx = 0; idx < kvs.length; idx += 2) {\n      parameters.put(kvs[idx].toString(), kvs[idx + 1]);\n    }\n\n    return createConfigObject(cls, parameters);\n  }\n\n  public <T> T createConfigObject(Class<T> cls, Map<String, Object> parameters) {\n    ConfigObject<T> configObject = configObjectFactory.create(cls, parameters);\n    return saveConfigObject(configObject);\n  }\n\n  public <T> T createConfigObject(T instance, Map<String, Object> parameters) {\n    ConfigObject<T> configObject = configObjectFactory.create(instance, parameters);\n    return saveConfigObject(configObject);\n  }\n\n  private <T> T saveConfigObject(ConfigObject<T> configObject) {\n    configObjectMap.put(configObject.getInstance(), configObject.getProperties());\n    return configObject.getInstance();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/main/java/org/apache/servicecomb/config/priority/PriorityPropertyType.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config.priority;\r\n\r\nimport java.lang.reflect.Type;\r\nimport java.util.Arrays;\r\nimport java.util.Objects;\r\n\r\npublic class PriorityPropertyType<T> {\r\n  private final Type type;\r\n\r\n  // when got invalid value will try next level\r\n  // null always be a invalid value\r\n  private final T invalidValue;\r\n\r\n  // when got invalid value by lowest level, will use defaultValue\r\n  private final T defaultValue;\r\n\r\n  // priorityKeys[0] has the highest priority\r\n  private final String[] priorityKeys;\r\n\r\n  public PriorityPropertyType(Type type, T invalidValue, T defaultValue, String... priorityKeys) {\r\n    this.type = type;\r\n    this.invalidValue = invalidValue;\r\n    this.defaultValue = defaultValue;\r\n    this.priorityKeys = priorityKeys;\r\n  }\r\n\r\n  public Type getType() {\r\n    return type;\r\n  }\r\n\r\n  public T getInvalidValue() {\r\n    return invalidValue;\r\n  }\r\n\r\n  public T getDefaultValue() {\r\n    return defaultValue;\r\n  }\r\n\r\n  public String[] getPriorityKeys() {\r\n    return priorityKeys;\r\n  }\r\n\r\n  @Override\r\n  public boolean equals(Object o) {\r\n    if (this == o) {\r\n      return true;\r\n    }\r\n    if (o == null || getClass() != o.getClass()) {\r\n      return false;\r\n    }\r\n    PriorityPropertyType<?> that = (PriorityPropertyType<?>) o;\r\n    return type.equals(that.type) && Objects.equals(invalidValue, that.invalidValue) && Objects\r\n        .equals(defaultValue, that.defaultValue) && Arrays.equals(priorityKeys, that.priorityKeys);\r\n  }\r\n\r\n  @Override\r\n  public int hashCode() {\r\n    int result = Objects.hash(type, invalidValue, defaultValue);\r\n    result = 31 * result + Arrays.hashCode(priorityKeys);\r\n    return result;\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.config.InMemoryDynamicPropertiesSource\n"
  },
  {
    "path": "foundations/foundation-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.config.FoundationConfigConfiguration\n"
  },
  {
    "path": "foundations/foundation-config/src/main/resources/META-INF/spring.factories",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\norg.springframework.boot.env.EnvironmentPostProcessor=\\\n  org.apache.servicecomb.config.ConfigEnvironmentPostProcessor\n"
  },
  {
    "path": "foundations/foundation-config/src/main/resources/mapping.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb-config-order: -100\n\nSERVICECOMB_ENV: service_description.environment\n\nservicecomb.loadbalance.stats.timerIntervalInMilis:\n  - servicecomb.loadbalance.stats.timerIntervalInMillis\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/BootStrapPropertiesTest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config;\r\n\r\nimport static org.apache.servicecomb.foundation.test.scaffolding.AssertUtils.assertPrettyJson;\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\n\r\nimport java.util.Map;\r\nimport java.util.Map.Entry;\r\n\r\nimport org.junit.jupiter.api.Test;\r\nimport org.mockito.Mockito;\r\nimport org.springframework.core.env.ConfigurableEnvironment;\r\nimport org.springframework.core.env.MapPropertySource;\r\nimport org.springframework.core.env.MutablePropertySources;\r\n\r\npublic class BootStrapPropertiesTest {\r\n  private Map<String, String> readInstanceProperties(String yaml) {\r\n    Map<String, Object> properties = YAMLUtil.yaml2Properties(yaml);\r\n    ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\r\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\r\n    MapPropertySource propertySource = new MapPropertySource(\"yaml\", properties);\r\n    mutablePropertySources.addLast(propertySource);\r\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\r\n\r\n    for (Entry<String, Object> entry : properties.entrySet()) {\r\n      Mockito.when(environment.getProperty(entry.getKey())).thenReturn(entry.getValue().toString());\r\n    }\r\n\r\n    return BootStrapProperties.readServiceInstanceProperties(environment);\r\n  }\r\n\r\n  @Test\r\n  void should_be_empty_when_old_and_new_key_not_exists() {\r\n    Map<String, String> properties = readInstanceProperties(\"k: v\");\r\n\r\n    assertThat(properties).isEmpty();\r\n  }\r\n\r\n  @Test\r\n  void should_read_boolean_to_string() {\r\n    Map<String, String> properties = readInstanceProperties(\"\"\"\r\n        servicecomb:\r\n          instance:\r\n            properties:\r\n              k: true\"\"\");\r\n\r\n    assertPrettyJson(properties).isEqualTo(\"\"\"\r\n        {\r\n          \"k\" : \"true\"\r\n        }\"\"\");\r\n  }\r\n\r\n  @Test\r\n  void should_read_number_to_string() {\r\n    Map<String, String> properties = readInstanceProperties(\"\"\"\r\n        servicecomb:\r\n          instance:\r\n            properties:\r\n              k: 1\"\"\");\r\n\r\n    assertPrettyJson(properties).isEqualTo(\"\"\"\r\n        {\r\n          \"k\" : \"1\"\r\n        }\"\"\");\r\n  }\r\n\r\n  @Test\r\n  void should_read_by_old_prefix_when_new_prefix_not_exists() {\r\n    Map<String, String> properties = readInstanceProperties(\"\"\"\r\n        instance_description:\r\n          properties:\r\n            k: v\r\n            k1: v1\"\"\");\r\n\r\n    assertPrettyJson(properties).isEqualTo(\"\"\"\r\n        {\r\n          \"k1\" : \"v1\",\r\n          \"k\" : \"v\"\r\n        }\"\"\");\r\n  }\r\n\r\n  @Test\r\n  void should_ignore_old_prefix_when_new_prefix_exists() {\r\n    Map<String, String> properties = readInstanceProperties(\"\"\"\r\n        instance_description:\r\n          properties:\r\n            k: v\r\n            k1: v1\r\n        servicecomb:\r\n          instance:\r\n            properties:\r\n              k: new\"\"\");\r\n\r\n    assertPrettyJson(properties).isEqualTo(\"\"\"\r\n        {\r\n          \"k\" : \"new\"\r\n        }\"\"\");\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/DynamicPropertiesTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport static com.seanyinx.github.unit.scaffolding.Randomness.nextBoolean;\nimport static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;\nimport static org.hamcrest.MatcherAssert.assertThat;\nimport static org.hamcrest.core.Is.is;\nimport static org.hamcrest.number.IsCloseTo.closeTo;\n\nimport java.util.HashMap;\nimport java.util.Objects;\n\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.seanyinx.github.unit.scaffolding.Poller;\nimport com.seanyinx.github.unit.scaffolding.Randomness;\n\npublic class DynamicPropertiesTest {\n  private static final String stringPropertyName = uniquify(\"stringPropertyName\");\n\n  private static final String intPropertyName = uniquify(\"intPropertyName\");\n\n  private static final String longPropertyName = uniquify(\"longPropertyName\");\n\n  private static final String floatPropertyName = uniquify(\"floatPropertyName\");\n\n  private static final String doublePropertyName = uniquify(\"doublePropertyName\");\n\n  private static final String booleanPropertyName = uniquify(\"booleanPropertyName\");\n\n  private static final String stringOldValue = uniquify(\"stringPropertyValue\");\n\n  private static final int intOldValue = Randomness.nextInt();\n\n  private static final long longOldValue = Randomness.nextLong();\n\n  private static final float floatOldValue = Double.valueOf(Randomness.nextDouble()).floatValue();\n\n  private static final double doubleOldValue = Randomness.nextDouble();\n\n  private static final boolean booleanOldValue = nextBoolean();\n\n  private static final double ERROR = 0.0000001;\n\n  private static Environment environment;\n\n  private static DynamicProperties dynamicProperties;\n\n  private final Poller poller = new Poller(2000, 100);\n\n  private volatile String stringPropertyValue;\n\n  private volatile int intPropertyValue;\n\n  private volatile long longPropertyValue;\n\n  private volatile double floatPropertyValue;\n\n  private volatile double doublePropertyValue;\n\n  private volatile boolean booleanPropertyValue;\n\n\n  @BeforeClass\n  public static void setUpClass() throws Exception {\n    environment = Mockito.mock(Environment.class);\n    writeInitialConfig();\n    dynamicProperties = new DynamicPropertiesImpl(environment);\n  }\n\n  @AfterClass\n  public static void tearDown() throws Exception {\n\n  }\n\n  private static void writeInitialConfig() throws Exception {\n    Mockito.when(environment.getProperty(stringPropertyName, (String) null)).thenReturn(stringOldValue);\n    Mockito.when(environment.getProperty(intPropertyName, int.class, 0)).thenReturn(intOldValue);\n    Mockito.when(environment.getProperty(longPropertyName, long.class, 0L)).thenReturn(longOldValue);\n    Mockito.when(environment.getProperty(floatPropertyName, float.class, 0F)).thenReturn(floatOldValue);\n    Mockito.when(environment.getProperty(doublePropertyName, double.class, 0D)).thenReturn(doubleOldValue);\n    Mockito.when(environment.getProperty(booleanPropertyName, boolean.class, false))\n        .thenReturn(booleanOldValue);\n  }\n\n  @Test\n  public void observesSpecifiedStringProperty() throws Exception {\n    String property = dynamicProperties.getStringProperty(stringPropertyName, null);\n    assertThat(property, is(stringOldValue));\n\n    property = dynamicProperties.getStringProperty(stringPropertyName, value -> stringPropertyValue = value, null);\n    assertThat(property, is(stringOldValue));\n\n    String newValue = uniquify(\"newValue\");\n\n    Mockito.when(environment.getProperty(stringPropertyName, (String) null)).thenReturn(newValue);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(stringPropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    poller.assertEventually(() -> Objects.equals(stringPropertyValue, newValue));\n  }\n\n  @Test\n  public void observesSpecifiedIntProperty() throws Exception {\n    int property = dynamicProperties.getIntProperty(intPropertyName, 0);\n    assertThat(property, is(intOldValue));\n\n    property = dynamicProperties.getIntProperty(intPropertyName, value -> intPropertyValue = value, 0);\n    assertThat(property, is(intOldValue));\n\n    int newValue = Randomness.nextInt();\n\n    Mockito.when(environment.getProperty(intPropertyName, Integer.class, 0)).thenReturn(newValue);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(intPropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    poller.assertEventually(() -> intPropertyValue == newValue);\n  }\n\n  @Test\n  public void observesSpecifiedLongProperty() throws Exception {\n    Mockito.when(environment.getProperty(longPropertyName, long.class, 3L)).thenReturn(longOldValue);\n\n    long property = dynamicProperties.getLongProperty(longPropertyName, 0);\n    assertThat(property, is(longOldValue));\n\n    property = dynamicProperties.getLongProperty(longPropertyName, value -> longPropertyValue = value, 3L);\n    assertThat(property, is(longOldValue));\n\n    long newValue = Randomness.nextLong();\n\n    Mockito.when(environment.getProperty(longPropertyName, Long.class, 3L)).thenReturn(newValue);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(longPropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    Mockito.when(environment.getProperty(longPropertyName, Long.class, 3L)).thenReturn(3L);\n    HashMap<String, Object> deleted = new HashMap<>();\n    deleted.put(longPropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(new HashMap<>(), new HashMap<>(), deleted));\n\n    poller.assertEventually(() -> longPropertyValue == 3L);\n  }\n\n  @Test\n  public void observesSpecifiedFloatProperty() throws Exception {\n    double property = dynamicProperties.getFloatProperty(floatPropertyName, 0);\n    assertThat(property, closeTo(floatOldValue, ERROR));\n\n    property = dynamicProperties.getFloatProperty(floatPropertyName, value -> floatPropertyValue = value, 0f);\n    assertThat(property, closeTo(floatOldValue, ERROR));\n\n    float newValue = Double.valueOf(Randomness.nextDouble()).floatValue();\n\n    Mockito.when(environment.getProperty(floatPropertyName, Float.class, 0f)).thenReturn(newValue);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(floatPropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    poller.assertEventually(() -> Math.abs(floatPropertyValue - newValue) < ERROR);\n  }\n\n  @Test\n  public void observesSpecifiedDoubleProperty() throws Exception {\n    double property = dynamicProperties.getDoubleProperty(doublePropertyName, 0);\n    assertThat(property, closeTo(doubleOldValue, ERROR));\n\n    property = dynamicProperties.getDoubleProperty(doublePropertyName, value -> doublePropertyValue = value, 0d);\n    assertThat(property, closeTo(doubleOldValue, ERROR));\n\n    double newValue = Randomness.nextDouble();\n\n    Mockito.when(environment.getProperty(doublePropertyName, Double.class, 0d)).thenReturn(newValue);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(doublePropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    poller.assertEventually(() -> Math.abs(doublePropertyValue - newValue) < ERROR);\n  }\n\n  @Test\n  public void observesSpecifiedBooleanProperty() throws Exception {\n    boolean property = dynamicProperties.getBooleanProperty(booleanPropertyName, false);\n    assertThat(property, is(booleanOldValue));\n\n    property = dynamicProperties.getBooleanProperty(\n        booleanPropertyName,\n        value -> booleanPropertyValue = value,\n        false);\n    assertThat(property, is(booleanOldValue));\n\n    boolean newValue = !booleanOldValue;\n\n    Mockito.when(environment.getProperty(booleanPropertyName, Boolean.class, booleanOldValue)).thenReturn(newValue);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(booleanPropertyName, newValue);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    poller.assertEventually(() -> booleanPropertyValue == newValue);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/TestConfigMapping.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestConfigMapping {\n  @Test\n  public void testMapping() {\n    List<String> value = ConfigMapping.map(\"SERVICECOMB_ENV\");\n    Assertions.assertEquals(2, value.size());\n    Assertions.assertEquals(\"service_description.environment\", value.get(0));\n    Assertions.assertEquals(\"service_description.environment.old\", value.get(1));\n\n    Map<String, Object> m = ConfigMapping.getMapping();\n    Assertions.assertNotNull(m);\n  }\n\n  @Test\n  public void testConvertedMap() {\n    String value = ConfigMapping.map(\"CSE_ENV_MAPPING\");\n    Map<String, Object> m = ConfigMapping.getMapping();\n    Map<String, Object> m1 = ConfigMapping.getConvertedMap(m);\n    Assertions.assertEquals(\"servicecomb.testmapping.key\", value);\n    Assertions.assertNotNull(m1);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/TestYAMLUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config;\n\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestYAMLUtil {\n  public static class Person {\n    String name;\n\n    public String getName() {\n      return name;\n    }\n\n    public void setName(String name) {\n      this.name = name;\n    }\n  }\n\n  public static class UnsafePerson {\n    String name;\n\n    public String getName() {\n      return name;\n    }\n\n    public void setName(String name) {\n      this.name = name;\n    }\n  }\n\n  @Test\n  public void testSafeParser() {\n    Person person = YAMLUtil.parserObject(\"name: hello\", Person.class);\n    Assertions.assertEquals(\"hello\", person.getName());\n  }\n\n  @Test\n  public void testYamlConfig() {\n    RuntimeException runtimeException = Assertions.assertThrows(RuntimeException.class, () -> YAMLUtil.yaml2Properties(\"servicecomb.service.registry.enabled: {{true}}\"));\n    Assertions.assertEquals(\"input cannot be convert to map\", runtimeException.getMessage());\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void testListValue() {\n    Map<String, Object> result = YAMLUtil.yaml2Properties(\"hello: a,b\");\n    Assertions.assertEquals(result.size(), 1);\n    String listValue = (String) result.get(\"hello\");\n    Assertions.assertEquals(listValue, \"a,b\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/file/TestMicroserviceConfigLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.file;\n\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.net.MalformedURLException;\nimport java.net.URI;\nimport java.net.URL;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMicroserviceConfigLoader {\n\n  private final MicroserviceConfigLoader loader = new MicroserviceConfigLoader();\n\n  private ConfigModel createConfigModel(String protocol, int order, String file) throws MalformedURLException {\n    ConfigModel configModel = new ConfigModel();\n    configModel.setUrl(new URL(protocol, null, file));\n    configModel.setOrder(order);\n    return configModel;\n  }\n\n  @Test\n  public void configsSortedByInsertionOrder() throws MalformedURLException {\n    loader.getConfigModels().add(createConfigModel(\"jar\", 0, \"c\"));\n    loader.getConfigModels().add(createConfigModel(\"jar\", 0, \"b\"));\n    loader.getConfigModels().add(createConfigModel(\"jar\", 0, \"a\"));\n\n    loader.sort();\n\n    Assertions.assertEquals(urls(\"jar:c\", \"jar:b\", \"jar:a\"), urlsOf(loader.getConfigModels()));\n  }\n\n  @Test\n  public void configsSortedBySpecifiedOrder() throws MalformedURLException {\n    loader.getConfigModels().add(createConfigModel(\"jar\", 1, \"b\"));\n    loader.getConfigModels().add(createConfigModel(\"jar\", -10, \"c\"));\n    loader.getConfigModels().add(createConfigModel(\"jar\", Integer.MAX_VALUE, \"a\"));\n\n    loader.sort();\n\n    Assertions.assertEquals(urls(\"jar:c\", \"jar:b\", \"jar:a\"), urlsOf(loader.getConfigModels()));\n  }\n\n  @Test\n  public void jarsAlwaysHaveHigherPriorityThanFiles() throws MalformedURLException {\n    loader.getConfigModels().add(createConfigModel(\"file\", 0, \"f2\"));\n    loader.getConfigModels().add(createConfigModel(\"jar\", 1, \"j1\"));\n    loader.getConfigModels().add(createConfigModel(\"file\", 0, \"f1\"));\n\n    loader.sort();\n\n    Assertions.assertEquals(urls(\"jar:j1\", \"file:f2\", \"file:f1\"), urlsOf(loader.getConfigModels()));\n  }\n\n  private String urlsOf(List<ConfigModel> configModels) {\n    return String.join(\",\",\n        configModels\n            .stream()\n            .map(configModel -> configModel.getUrl().toString())\n            .collect(Collectors.toList()));\n  }\n\n  private String urls(String... urls) {\n    return String.join(\",\", (CharSequence[]) urls);\n  }\n\n  @Test\n  public void testLoadEmptyYaml() throws IOException {\n    loader.load(\"empty.yaml\");\n    Assertions.assertTrue(loader.getConfigModels().get(0).getConfig().isEmpty());\n  }\n\n  @Test\n  public void testLoadNotExistYaml() throws IOException {\n    URL url = URI.create(\"file:/notExist.yaml\").toURL();\n    try {\n      loader.load(url);\n      Assertions.fail(\"must throw exception\");\n    } catch (FileNotFoundException e) {\n      Assertions.assertTrue(true);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/inject/TestConfigObjectFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.inject;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.priority.TestPriorityPropertyBase;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestConfigObjectFactory extends TestPriorityPropertyBase {\n  public static class ConfigNoAnnotation {\n    public String strValue;\n\n    private String strValue1;\n\n    public int intValue;\n\n    private int intValue1;\n\n    public Integer intValueObj;\n\n    private Integer intValueObj1;\n\n    public long longValue;\n\n    private long longValue1;\n\n    public Long longValueObj;\n\n    private Long longValueObj1;\n\n    public float floatValue;\n\n    private float floatValue1;\n\n    public Float floatValueObj;\n\n    private Float floatValueObj1;\n\n    public double doubleValue;\n\n    private double doubleValue1;\n\n    public Double doubleValueObj;\n\n    private Double doubleValueObj1;\n\n    public boolean booleanValue;\n\n    private boolean booleanValue1;\n\n    public Boolean booleanValueObj;\n\n    private Boolean booleanValueObj1;\n\n    public String getStrValue1() {\n      return strValue1;\n    }\n\n    public void setStrValue1(String strValue1) {\n      this.strValue1 = strValue1;\n    }\n\n    public int getIntValue1() {\n      return intValue1;\n    }\n\n    public void setIntValue1(int intValue1) {\n      this.intValue1 = intValue1;\n    }\n\n    public Integer getIntValueObj1() {\n      return intValueObj1;\n    }\n\n    public void setIntValueObj1(Integer intValueObj1) {\n      this.intValueObj1 = intValueObj1;\n    }\n\n    public long getLongValue1() {\n      return longValue1;\n    }\n\n    public void setLongValue1(long longValue1) {\n      this.longValue1 = longValue1;\n    }\n\n    public Long getLongValueObj1() {\n      return longValueObj1;\n    }\n\n    public void setLongValueObj1(Long longValueObj1) {\n      this.longValueObj1 = longValueObj1;\n    }\n\n    public float getFloatValue1() {\n      return floatValue1;\n    }\n\n    public void setFloatValue1(float floatValue1) {\n      this.floatValue1 = floatValue1;\n    }\n\n    public Float getFloatValueObj1() {\n      return floatValueObj1;\n    }\n\n    public void setFloatValueObj1(Float floatValueObj1) {\n      this.floatValueObj1 = floatValueObj1;\n    }\n\n    public double getDoubleValue1() {\n      return doubleValue1;\n    }\n\n    public void setDoubleValue1(double doubleValue1) {\n      this.doubleValue1 = doubleValue1;\n    }\n\n    public Double getDoubleValueObj1() {\n      return doubleValueObj1;\n    }\n\n    public void setDoubleValueObj1(Double doubleValueObj1) {\n      this.doubleValueObj1 = doubleValueObj1;\n    }\n\n    public boolean isBooleanValue1() {\n      return booleanValue1;\n    }\n\n    public void setBooleanValue1(boolean booleanValue1) {\n      this.booleanValue1 = booleanValue1;\n    }\n\n    public Boolean getBooleanValueObj1() {\n      return booleanValueObj1;\n    }\n\n    public void setBooleanValueObj1(Boolean booleanValueObj1) {\n      this.booleanValueObj1 = booleanValueObj1;\n    }\n  }\n\n  @Test\n  public void noAnnotation_defaultValue() {\n    ConfigNoAnnotation config = priorityPropertyManager.createConfigObject(ConfigNoAnnotation.class);\n\n    Assertions.assertNull(config.strValue);\n    Assertions.assertNull(config.getStrValue1());\n\n    Assertions.assertEquals(0, config.intValue);\n    Assertions.assertEquals(0, config.getIntValue1());\n    Assertions.assertNull(config.intValueObj);\n    Assertions.assertNull(config.getIntValueObj1());\n\n    Assertions.assertEquals(0, config.longValue);\n    Assertions.assertEquals(0, config.getLongValue1());\n    Assertions.assertNull(config.longValueObj);\n    Assertions.assertNull(config.getLongValueObj1());\n\n    Assertions.assertEquals(0, config.floatValue, 0);\n    Assertions.assertEquals(0, config.getFloatValue1(), 0);\n    Assertions.assertNull(config.floatValueObj);\n    Assertions.assertNull(config.getFloatValueObj1());\n\n    Assertions.assertEquals(0, config.doubleValue, 0);\n    Assertions.assertEquals(0, config.getDoubleValue1(), 0);\n    Assertions.assertNull(config.doubleValueObj);\n    Assertions.assertNull(config.getDoubleValueObj1());\n\n    Assertions.assertFalse(config.booleanValue);\n    Assertions.assertFalse(config.isBooleanValue1());\n    Assertions.assertNull(config.booleanValueObj);\n    Assertions.assertNull(config.getBooleanValueObj1());\n  }\n\n  @Test\n  public void noAnnotation_initValue() {\n    Mockito.when(environment.getProperty(\"strValue\")).thenReturn(\"strValue\");\n    Mockito.when(environment.getProperty(\"strValue1\")).thenReturn(\"strValue1\");\n\n    Mockito.when(environment.getProperty(\"intValue\", Integer.class)).thenReturn(1);\n    Mockito.when(environment.getProperty(\"intValue1\", Integer.class)).thenReturn(2);\n    Mockito.when(environment.getProperty(\"intValueObj\", Integer.class)).thenReturn(3);\n    Mockito.when(environment.getProperty(\"intValueObj1\", Integer.class)).thenReturn(4);\n\n    Mockito.when(environment.getProperty(\"longValue\", Long.class)).thenReturn(5L);\n    Mockito.when(environment.getProperty(\"longValue1\", Long.class)).thenReturn(6L);\n    Mockito.when(environment.getProperty(\"longValueObj\", Long.class)).thenReturn(7L);\n    Mockito.when(environment.getProperty(\"longValueObj1\", Long.class)).thenReturn(8L);\n\n    Mockito.when(environment.getProperty(\"floatValue\", Float.class)).thenReturn(9.0F);\n    Mockito.when(environment.getProperty(\"floatValue1\", Float.class)).thenReturn(10.0F);\n    Mockito.when(environment.getProperty(\"floatValueObj\", Float.class)).thenReturn(11.0F);\n    Mockito.when(environment.getProperty(\"floatValueObj1\", Float.class)).thenReturn(12.0F);\n\n    Mockito.when(environment.getProperty(\"doubleValue\", Double.class)).thenReturn(13.0D);\n    Mockito.when(environment.getProperty(\"doubleValue1\", Double.class)).thenReturn(14.0D);\n    Mockito.when(environment.getProperty(\"doubleValueObj\", Double.class)).thenReturn(15.0D);\n    Mockito.when(environment.getProperty(\"doubleValueObj1\", Double.class)).thenReturn(16.0D);\n\n    Mockito.when(environment.getProperty(\"booleanValue\", Boolean.class)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"booleanValue1\", Boolean.class)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"booleanValueObj\", Boolean.class)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"booleanValueObj1\", Boolean.class)).thenReturn(true);\n\n    ConfigNoAnnotation config = priorityPropertyManager.createConfigObject(ConfigNoAnnotation.class);\n\n    Assertions.assertEquals(\"strValue\", config.strValue);\n    Assertions.assertEquals(\"strValue1\", config.getStrValue1());\n\n    Assertions.assertEquals(1, config.intValue);\n    Assertions.assertEquals(2, config.getIntValue1());\n    Assertions.assertEquals(3, (int) config.intValueObj);\n    Assertions.assertEquals(4, (int) config.getIntValueObj1());\n\n    Assertions.assertEquals(5, config.longValue);\n    Assertions.assertEquals(6, config.getLongValue1());\n    Assertions.assertEquals(7, (long) config.longValueObj);\n    Assertions.assertEquals(8, (long) config.getLongValueObj1());\n\n    Assertions.assertEquals(9, config.floatValue, 0);\n    Assertions.assertEquals(10, config.getFloatValue1(), 0);\n    Assertions.assertEquals(11, config.floatValueObj, 0);\n    Assertions.assertEquals(12, config.getFloatValueObj1(), 0);\n\n    Assertions.assertEquals(13, config.doubleValue, 0);\n    Assertions.assertEquals(14, config.getDoubleValue1(), 0);\n    Assertions.assertEquals(15, config.doubleValueObj, 0);\n    Assertions.assertEquals(16, config.getDoubleValueObj1(), 0);\n\n    Assertions.assertTrue(config.booleanValue);\n    Assertions.assertTrue(config.isBooleanValue1());\n    Assertions.assertTrue(config.booleanValueObj);\n    Assertions.assertTrue(config.getBooleanValueObj1());\n  }\n\n  @Test\n  public void noAnnotation_updateValue() {\n    ConfigNoAnnotation config = priorityPropertyManager.createConfigObject(ConfigNoAnnotation.class);\n\n    Mockito.when(environment.getProperty(\"strValue\")).thenReturn(\"strValue\");\n    Mockito.when(environment.getProperty(\"strValue1\")).thenReturn(\"strValue1\");\n\n    Mockito.when(environment.getProperty(\"intValue\", Integer.class)).thenReturn(1);\n    Mockito.when(environment.getProperty(\"intValue1\", Integer.class)).thenReturn(2);\n    Mockito.when(environment.getProperty(\"intValueObj\", Integer.class)).thenReturn(3);\n    Mockito.when(environment.getProperty(\"intValueObj1\", Integer.class)).thenReturn(4);\n\n    Mockito.when(environment.getProperty(\"longValue\", Long.class)).thenReturn(5L);\n    Mockito.when(environment.getProperty(\"longValue1\", Long.class)).thenReturn(6L);\n    Mockito.when(environment.getProperty(\"longValueObj\", Long.class)).thenReturn(7L);\n    Mockito.when(environment.getProperty(\"longValueObj1\", Long.class)).thenReturn(8L);\n\n    Mockito.when(environment.getProperty(\"floatValue\", Float.class)).thenReturn(9.0F);\n    Mockito.when(environment.getProperty(\"floatValue1\", Float.class)).thenReturn(10.0F);\n    Mockito.when(environment.getProperty(\"floatValueObj\", Float.class)).thenReturn(11.0F);\n    Mockito.when(environment.getProperty(\"floatValueObj1\", Float.class)).thenReturn(12.0F);\n\n    Mockito.when(environment.getProperty(\"doubleValue\", Double.class)).thenReturn(13.0D);\n    Mockito.when(environment.getProperty(\"doubleValue1\", Double.class)).thenReturn(14.0D);\n    Mockito.when(environment.getProperty(\"doubleValueObj\", Double.class)).thenReturn(15.0D);\n    Mockito.when(environment.getProperty(\"doubleValueObj1\", Double.class)).thenReturn(16.0D);\n\n    Mockito.when(environment.getProperty(\"booleanValue\", Boolean.class)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"booleanValue1\", Boolean.class)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"booleanValueObj\", Boolean.class)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"booleanValueObj1\", Boolean.class)).thenReturn(true);\n\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(\"strValue\", \"strValue\");\n    updated.put(\"strValue1\", \"strValue1\");\n\n    updated.put(\"intValue\", 0);\n    updated.put(\"intValue1\", 1);\n    updated.put(\"intValueObj\", 2);\n    updated.put(\"intValueObj1\", 3);\n\n    updated.put(\"longValue\", 5L);\n    updated.put(\"longValue1\", 6L);\n    updated.put(\"longValueObj\", 7L);\n    updated.put(\"longValueObj1\", 8L);\n\n    updated.put(\"floatValue\", 9.0F);\n    updated.put(\"floatValue1\", 10.0F);\n    updated.put(\"floatValueObj\", 11.0F);\n    updated.put(\"floatValueObj1\", 12.0F);\n\n    updated.put(\"doubleValue\", 13.0D);\n    updated.put(\"doubleValue1\", 14.0D);\n    updated.put(\"doubleValueObj\", 15.0D);\n    updated.put(\"doubleValueObj1\", 16.0D);\n\n    updated.put(\"booleanValue\", true);\n    updated.put(\"booleanValue1\", true);\n    updated.put(\"booleanValueObj\", true);\n    updated.put(\"booleanValueObj1\", true);\n\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    Assertions.assertEquals(\"strValue\", config.strValue);\n    Assertions.assertEquals(\"strValue1\", config.getStrValue1());\n\n    Assertions.assertEquals(1, config.intValue);\n    Assertions.assertEquals(2, config.getIntValue1());\n    Assertions.assertEquals(3, (int) config.intValueObj);\n    Assertions.assertEquals(4, (int) config.getIntValueObj1());\n\n    Assertions.assertEquals(5, config.longValue);\n    Assertions.assertEquals(6, config.getLongValue1());\n    Assertions.assertEquals(7, (long) config.longValueObj);\n    Assertions.assertEquals(8, (long) config.getLongValueObj1());\n\n    Assertions.assertEquals(9, config.floatValue, 0);\n    Assertions.assertEquals(10, config.getFloatValue1(), 0);\n    Assertions.assertEquals(11, config.floatValueObj, 0);\n    Assertions.assertEquals(12, config.getFloatValueObj1(), 0);\n\n    Assertions.assertEquals(13, config.doubleValue, 0);\n    Assertions.assertEquals(14, config.getDoubleValue1(), 0);\n    Assertions.assertEquals(15, config.doubleValueObj, 0);\n    Assertions.assertEquals(16, config.getDoubleValueObj1(), 0);\n\n    Assertions.assertTrue(config.booleanValue);\n    Assertions.assertTrue(config.isBooleanValue1());\n    Assertions.assertTrue(config.booleanValueObj);\n    Assertions.assertTrue(config.getBooleanValueObj1());\n  }\n\n  @InjectProperties(prefix = \"root\")\n  public static class ConfigWithAnnotation {\n    @InjectProperty(prefix = \"override\", keys = {\"high\", \"low\"})\n    public String strValue;\n\n    @InjectProperty(keys = \"${key}.value\")\n    public int intValue;\n\n    @InjectProperty(keys = \"${low-list}.a.${high-list}.b\")\n    public long longValue;\n\n    @InjectProperty(keys = \"${full-list}\")\n    public float floatValue;\n\n    @InjectProperty(defaultValue = \"abc\")\n    public String strDef;\n\n    @InjectProperty(defaultValue = \"1\")\n    public int intDef;\n\n    @InjectProperty(defaultValue = \"2\")\n    public long longDef;\n\n    @InjectProperty(defaultValue = \"3\")\n    public float floatDef;\n\n    @InjectProperty(defaultValue = \"4\")\n    public double doubleDef;\n\n    @InjectProperty(defaultValue = \"true\")\n    public boolean booleanDef;\n  }\n\n  @Test\n  public void annotationDefault() {\n    ConfigWithAnnotation config = priorityPropertyManager.createConfigObject(ConfigWithAnnotation.class);\n\n    Assertions.assertEquals(\"abc\", config.strDef);\n    Assertions.assertEquals(1, config.intDef);\n    Assertions.assertEquals(2, config.longDef);\n    Assertions.assertEquals(3, config.floatDef, 0);\n    Assertions.assertEquals(4, config.doubleDef, 0);\n    Assertions.assertTrue(config.booleanDef);\n  }\n\n  @Test\n  public void placeholder_multi_list() {\n    ConfigWithAnnotation config = priorityPropertyManager.createConfigObject(ConfigWithAnnotation.class,\n        \"low-list\", Arrays.asList(\"low-1\", \"low-2\"),\n        \"high-list\", Arrays.asList(\"high-1\", \"high-2\"));\n    // low-1.a.high-1.b\n    // low-1.a.high-2.b\n    // low-2.a.high-1.b\n    // low-2.a.high-2.b\n\n    Assertions.assertEquals(0, config.longValue);\n\n    Mockito.when(environment.getProperty(\"root.low-2.a.high-2.b\", Long.class)).thenReturn(Long.MAX_VALUE);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(\"root.low-2.a.high-2.b\", Long.MAX_VALUE);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertEquals(Long.MAX_VALUE, config.longValue);\n\n    Mockito.when(environment.getProperty(\"root.low-2.a.high-1.b\", Long.class)).thenReturn(Long.MAX_VALUE - 1);\n    updated = new HashMap<>();\n    updated.put(\"root.low-2.a.high-1.b\", Long.MAX_VALUE - 1);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    Assertions.assertEquals(Long.MAX_VALUE - 1, config.longValue);\n\n    Mockito.when(environment.getProperty(\"root.low-1.a.high-2.b\", Long.class)).thenReturn(Long.MAX_VALUE - 2);\n    updated = new HashMap<>();\n    updated.put(\"root.low-1.a.high-2.b\", Long.MAX_VALUE - 2);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertEquals(Long.MAX_VALUE - 2, config.longValue);\n\n    Mockito.when(environment.getProperty(\"root.low-1.a.high-1.b\", Long.class)).thenReturn(Long.MAX_VALUE - 3);\n    updated = new HashMap<>();\n    updated.put(\"root.low-1.a.high-1.b\", Long.MAX_VALUE - 3);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertEquals(Long.MAX_VALUE - 3, config.longValue);\n  }\n\n  @Test\n  public void placeholder_full_list() {\n    ConfigWithAnnotation config = priorityPropertyManager.createConfigObject(ConfigWithAnnotation.class,\n        \"full-list\", Arrays.asList(\"l1-1\", \"l1-2\"));\n\n    Assertions.assertEquals(0, config.floatValue, 0);\n\n    Mockito.when(environment.getProperty(\"root.l1-2\", Float.class)).thenReturn(1F);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(\"root.l1-2\", 1F);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    Assertions.assertEquals(1F, config.floatValue, 0);\n\n    Mockito.when(environment.getProperty(\"root.l1-1\", Float.class)).thenReturn(2F);\n    updated = new HashMap<>();\n    updated.put(\"root.l1-1\", 2F);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    Assertions.assertEquals(2F, config.floatValue, 0);\n  }\n\n  @Test\n  public void placeholder_normal() {\n    ConfigWithAnnotation config = priorityPropertyManager.createConfigObject(ConfigWithAnnotation.class, \"key\", \"k\");\n\n    Assertions.assertEquals(0, config.intValue);\n\n    Mockito.when(environment.getProperty(\"root.k.value\", Integer.class)).thenReturn(1);\n    Map<String, Object> updated = new HashMap<>();\n    updated.put(\"root.k.value\", 1);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertEquals(1, config.intValue);\n  }\n\n  @Test\n  public void overridePrefix() {\n    ConfigWithAnnotation config = priorityPropertyManager.createConfigObject(ConfigWithAnnotation.class);\n\n    Mockito.when(environment.getProperty(\"override.high\")).thenReturn(\"high\");\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(\"override.high\", \"high\");\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertEquals(\"high\", config.strValue);\n\n    Mockito.when(environment.getProperty(\"override.high\")).thenReturn(null);\n    updated = new HashMap<>();\n    updated.put(\"override.high\", null);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertNull(config.strValue);\n\n    Mockito.when(environment.getProperty(\"override.low\")).thenReturn(\"low\");\n    updated = new HashMap<>();\n    updated.put(\"override.low\", \"low\");\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertEquals(\"low\", config.strValue);\n\n    Mockito.when(environment.getProperty(\"override.low\")).thenReturn(null);\n    updated = new HashMap<>();\n    updated.put(\"override.low\", null);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n    Assertions.assertNull(config.strValue);\n  }\n\n  @InjectProperties(prefix = \"root\")\n  public static class ConfigWithPojo {\n\n    @InjectProperties(prefix = \"root.model\")\n    public static class Model {\n      @InjectProperty(defaultValue = \"h\")\n      public String name;\n    }\n\n    @InjectProperty(defaultValue = \"4\")\n    public int index;\n\n    public Model model;\n  }\n\n  @Test\n  public void configWithPojoWork() {\n    ConfigWithPojo config = priorityPropertyManager.createConfigObject(ConfigWithPojo.class);\n    ConfigWithPojo.Model model = priorityPropertyManager.createConfigObject(ConfigWithPojo.Model.class);\n    config.model = model;\n\n    Assertions.assertEquals(4, config.index);\n    Assertions.assertEquals(\"h\", config.model.name);\n\n    Mockito.when(environment.getProperty(\"root.index\", Integer.class)).thenReturn(5);\n    Mockito.when(environment.getProperty(\"root.model.name\")).thenReturn(\"w\");\n    Map<String, Object> updated = new HashMap<>();\n    updated.put(\"root.index\", 5);\n    updated.put(\"root.model.name\", \"w\");\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    Assertions.assertEquals(5, config.index);\n    Assertions.assertEquals(\"w\", config.model.name);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/inject/TestPlaceholderResolver.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.inject;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestPlaceholderResolver {\n  static Map<String, Object> parameters = new HashMap<>();\n\n  static PlaceholderResolver resolver = new PlaceholderResolver();\n\n  @BeforeAll\n  public static void setupClass() {\n    parameters.put(\"key\", \"value\");\n    parameters.put(\"varOfVar\", Arrays.asList(\"${key}\"));\n\n    parameters.put(\"priority\", \"low\");\n\n    parameters.put(\"low-list\", Arrays.asList(\"low-1\", \"low-2\"));\n    parameters.put(\"middle-list\", Arrays.asList(\"middle-1\", \"middle-2\"));\n    parameters.put(\"high-list\", Arrays.asList(\"high-1\", \"high-2\"));\n  }\n\n  protected Environment environment;\n\n  @BeforeEach\n  public void setup() {\n    environment = Mockito.mock(Environment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void unknown() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix${xxx}suffix\", parameters),\n        Matchers.contains(\"prefix${xxx}suffix\"));\n  }\n\n  @Test\n  public void empty() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix${}suffix\", parameters),\n        Matchers.contains(\"prefix${}suffix\"));\n  }\n\n  @Test\n  public void notComplete() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix${suffix\", parameters),\n        Matchers.contains(\"prefix${suffix\"));\n  }\n\n  @Test\n  public void normal() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix.${key}.suffix\", parameters),\n        Matchers.contains(\"prefix.value.suffix\"));\n  }\n\n  @Test\n  public void disable() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix.\\\\${key}.suffix\", parameters),\n        Matchers.contains(\"prefix.${key}.suffix\"));\n  }\n\n  @Test\n  public void varOfVar() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix.${varOfVar}.suffix\", parameters),\n        Matchers.contains(\"prefix.value.suffix\"));\n  }\n\n  @Test\n  public void list() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix.${low-list}.suffix\", parameters),\n        Matchers.contains(\"prefix.low-1.suffix\", \"prefix.low-2.suffix\"));\n  }\n\n  @Test\n  public void multi_list() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix.${low-list}.${middle-list}.${high-list}.suffix\", parameters),\n        Matchers.contains(\n            \"prefix.low-1.middle-1.high-1.suffix\",\n            \"prefix.low-1.middle-1.high-2.suffix\",\n            \"prefix.low-1.middle-2.high-1.suffix\",\n            \"prefix.low-1.middle-2.high-2.suffix\",\n            \"prefix.low-2.middle-1.high-1.suffix\",\n            \"prefix.low-2.middle-1.high-2.suffix\",\n            \"prefix.low-2.middle-2.high-1.suffix\",\n            \"prefix.low-2.middle-2.high-2.suffix\"));\n  }\n\n  @Test\n  public void nested() {\n    MatcherAssert.assertThat(resolver.replace(\"prefix.${${priority}-list}.suffix\", parameters),\n        Matchers.contains(\"prefix.low-1.suffix\", \"prefix.low-2.suffix\"));\n  }\n\n  @Test\n  public void mixed() {\n    MatcherAssert.assertThat(\n        resolver.replace(\"prefix.${${priority}-list}.${key}.${high-list}.suffix ${xxx}\", parameters),\n        Matchers.contains(\n            \"prefix.low-1.value.high-1.suffix ${xxx}\",\n            \"prefix.low-2.value.high-1.suffix ${xxx}\",\n            \"prefix.low-1.value.high-2.suffix ${xxx}\",\n            \"prefix.low-2.value.high-2.suffix ${xxx}\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/parser/TestParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.parser;\n\nimport static org.assertj.core.api.Assertions.assertThat;\nimport static org.assertj.core.api.Assertions.catchThrowable;\n\nimport org.junit.Test;\n\npublic class TestParser {\n  @Test\n  public void testRawParser() {\n    Parser parser = Parser.findParser(Parser.CONTENT_TYPE_RAW);\n    assertThat(parser.parse(\"world\", \"hello\", true)).containsKey(\"hello\").containsValue(\"world\");\n    assertThat(parser.parse(\"world\", \"hello\", false)).containsKey(\"hello\").containsValue(\"world\");\n  }\n\n  @Test\n  public void testPropertiesParser() {\n    Parser parser = Parser.findParser(Parser.CONTENT_TYPE_PROPERTIES);\n    assertThat(parser.parse(\"l1-1=3.0\\n\"\n        + \"l1-2=2.0\", \"hello\", true)).containsKeys(\"hello.l1-1\", \"hello.l1-2\")\n        .containsValues(\"2.0\", \"3.0\");\n    assertThat(parser.parse(\"l1-1=3.0\\n\"\n        + \"l1-2=2.0\", \"hello\", false)).containsKeys(\"l1-1\", \"l1-2\")\n        .containsValues(\"2.0\", \"3.0\");\n  }\n\n  @Test\n  public void testYamlParser() {\n    Parser parser = Parser.findParser(Parser.CONTENT_TYPE_YAML);\n    assertThat(parser.parse(\"l1-1: 3.0\\n\"\n        + \"l1-2: 2.0\", \"hello\", true)).containsKeys(\"hello.l1-1\", \"hello.l1-2\")\n        .containsValues(\"2.0\", \"3.0\");\n    assertThat(parser.parse(\"l1-1: 3.0\\n\"\n        + \"l1-2: 2.0\", \"false\", false)).containsKeys(\"l1-1\", \"l1-2\")\n        .containsValues(\"2.0\", \"3.0\");\n  }\n\n  @Test\n  public void testInvalidParser() {\n    Throwable exception = catchThrowable(() -> Parser.findParser(\"unknown\"));\n    assertThat(exception).isInstanceOf(IllegalArgumentException.class);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/priority/TestPriorityProperty.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.priority;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestPriorityProperty extends TestPriorityPropertyBase {\n  String high = \"ms.schema.op\";\n\n  String middle = \"ms.schema\";\n\n  String low = \"ms\";\n\n  String[] keys = {high, middle, low};\n\n  @Test\n  public void testLong() {\n    PriorityProperty<Long> config = propertyFactory.getOrCreate(Long.class, -1L, -2L, keys);\n    Assertions.assertEquals(-2L, (long) config.getValue());\n\n    updateLong(low, 1L, config);\n    Assertions.assertEquals(1L, (long) config.getValue());\n\n    updateLong(middle, 2L, config);\n    Assertions.assertEquals(2L, (long) config.getValue());\n\n    updateLong(high, 3L, config);\n    Assertions.assertEquals(3L, (long) config.getValue());\n\n    updateLong(middle, null, config);\n    Assertions.assertEquals(3L, (long) config.getValue());\n\n    updateLong(middle, 2L, config);\n    updateLong(high, null, config);\n    Assertions.assertEquals(2L, (long) config.getValue());\n\n    updateLong(middle, null, config);\n    Assertions.assertEquals(1L, (long) config.getValue());\n\n    updateLong(low, null, config);\n    Assertions.assertEquals(-2L, (long) config.getValue());\n  }\n\n  @Test\n  public void testInt() {\n    PriorityProperty<Integer> config = propertyFactory.getOrCreate(Integer.class, -1, -2, keys);\n    Assertions.assertEquals(-2L, (int) config.getValue());\n\n    updateInt(low, 1, config);\n    Assertions.assertEquals(1, (int) config.getValue());\n\n    updateInt(middle, 2, config);\n    Assertions.assertEquals(2, (int) config.getValue());\n\n    updateInt(high, 3, config);\n    Assertions.assertEquals(3, (int) config.getValue());\n\n    updateInt(middle, null, config);\n    Assertions.assertEquals(3, (int) config.getValue());\n    updateInt(middle, 2, config);\n\n    updateInt(high, null, config);\n    Assertions.assertEquals(2, (int) config.getValue());\n\n    updateInt(middle, null, config);\n    Assertions.assertEquals(1, (int) config.getValue());\n\n    updateInt(low, null, config);\n    Assertions.assertEquals(-2, (int) config.getValue());\n  }\n\n  private void updateFloat(String key, Float value, PriorityProperty<Float> config) {\n    Mockito.when(environment.getProperty(key, Float.class)).thenReturn(value);\n    config.updateValue();\n  }\n\n  private void updateStr(String key, String value, PriorityProperty<String> config) {\n    Mockito.when(environment.getProperty(key)).thenReturn(value);\n    config.updateValue();\n  }\n\n  private void updateInt(String key, Integer value, PriorityProperty<Integer> config) {\n    Mockito.when(environment.getProperty(key, Integer.class)).thenReturn(value);\n    config.updateValue();\n  }\n\n  private void updateLong(String key, Long value, PriorityProperty<Long> config) {\n    Mockito.when(environment.getProperty(key, Long.class)).thenReturn(value);\n    config.updateValue();\n  }\n\n  private void updateBoolean(String key, Boolean value, PriorityProperty<Boolean> config) {\n    Mockito.when(environment.getProperty(key, Boolean.class)).thenReturn(value);\n    config.updateValue();\n  }\n\n  private void updateDouble(String key, Double value, PriorityProperty<Double> config) {\n    Mockito.when(environment.getProperty(key, Double.class)).thenReturn(value);\n    config.updateValue();\n  }\n\n  @Test\n  public void testString() {\n    PriorityProperty<String> config = propertyFactory.getOrCreate(String.class, null, \"def\", keys);\n    Assertions.assertEquals(\"def\", config.getValue());\n\n    updateStr(low, \"1\", config);\n    Assertions.assertEquals(\"1\", config.getValue());\n\n    updateStr(middle, \"2\", config);\n    Assertions.assertEquals(\"2\", config.getValue());\n\n    updateStr(high, \"3\", config);\n    Assertions.assertEquals(\"3\", config.getValue());\n\n    updateStr(middle, null, config);\n    Assertions.assertEquals(\"3\", config.getValue());\n\n    updateStr(middle, \"2\", config);\n    updateStr(high, null, config);\n    Assertions.assertEquals(\"2\", config.getValue());\n\n    updateStr(middle, null, config);\n    Assertions.assertEquals(\"1\", config.getValue());\n\n    updateStr(low, null, config);\n    Assertions.assertEquals(\"def\", config.getValue());\n  }\n\n  @Test\n  public void testBoolean() {\n    PriorityProperty<Boolean> config = propertyFactory.getOrCreate(Boolean.class, null, false, keys);\n    Assertions.assertFalse(config.getValue());\n\n    updateBoolean(low, true, config);\n    Assertions.assertTrue(config.getValue());\n\n    updateBoolean(middle, false, config);\n    Assertions.assertFalse(config.getValue());\n\n    updateBoolean(high, true, config);\n    Assertions.assertTrue(config.getValue());\n\n    updateBoolean(middle, false, config);\n    Assertions.assertTrue(config.getValue());\n\n    updateBoolean(middle, false, config);\n    updateBoolean(high, null, config);\n    Assertions.assertFalse(config.getValue());\n\n    updateBoolean(middle, null, config);\n    Assertions.assertTrue(config.getValue());\n\n    updateBoolean(low, null, config);\n    Assertions.assertFalse(config.getValue());\n  }\n\n  @Test\n  public void testDouble() {\n    PriorityProperty<Double> config = propertyFactory.getOrCreate(Double.class, null, -2.0, keys);\n    Assertions.assertEquals(-2, config.getValue(), 0);\n\n    updateDouble(low, 1D, config);\n    Assertions.assertEquals(1, config.getValue(), 0);\n\n    updateDouble(middle, 2D, config);\n    Assertions.assertEquals(2, config.getValue(), 0);\n\n    updateDouble(high, 3D, config);\n    Assertions.assertEquals(3, config.getValue(), 0);\n\n    updateDouble(middle, null, config);\n    Assertions.assertEquals(3, config.getValue(), 0);\n\n    updateDouble(middle, 2D, config);\n    updateDouble(high, null, config);\n    Assertions.assertEquals(2, config.getValue(), 0);\n\n    updateDouble(middle, null, config);\n    Assertions.assertEquals(1, config.getValue(), 0);\n\n    updateDouble(low, null, config);\n    Assertions.assertEquals(-2, config.getValue(), 0);\n  }\n\n  @Test\n  public void testFloat() {\n    PriorityProperty<Float> config = propertyFactory.getOrCreate(Float.class, null, -2.0f, keys);\n    Assertions.assertEquals(-2, config.getValue(), 0);\n\n    updateFloat(low, 1F, config);\n    Assertions.assertEquals(1, config.getValue(), 0);\n\n    updateFloat(middle, 2F, config);\n    Assertions.assertEquals(2, config.getValue(), 0);\n\n    updateFloat(high, 3F, config);\n    Assertions.assertEquals(3, config.getValue(), 0);\n\n    updateFloat(middle, null, config);\n    Assertions.assertEquals(3, config.getValue(), 0);\n\n    updateFloat(middle, 2F, config);\n    updateFloat(high, null, config);\n    Assertions.assertEquals(2, config.getValue(), 0);\n\n    updateFloat(middle, null, config);\n    Assertions.assertEquals(1, config.getValue(), 0);\n\n    updateFloat(low, null, config);\n    Assertions.assertEquals(-2, config.getValue(), 0);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/priority/TestPriorityPropertyBase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.config.priority;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestPriorityPropertyBase {\n  protected PriorityPropertyManager priorityPropertyManager;\n\n  protected PriorityPropertyFactory propertyFactory;\n\n  protected Environment environment;\n\n  @BeforeEach\n  public void setup() {\n    environment = Mockito.mock(Environment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n\n    propertyFactory = new PriorityPropertyFactory(environment);\n    priorityPropertyManager = new PriorityPropertyManager(new ConfigObjectFactory(propertyFactory));\n  }\n\n  @AfterEach\n  public void teardown() {\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/priority/TestPriorityPropertyFactory.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.config.priority;\r\n\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\n\r\nimport org.junit.jupiter.api.Test;\r\n\r\nclass TestPriorityPropertyFactory extends TestPriorityPropertyBase {\r\n  @Test\r\n  void should_not_create_multiple_instances_for_same_parameter() {\r\n    PriorityProperty<Integer> p1 = propertyFactory.getOrCreate(int.class, null, 0, \"high\", \"low\");\r\n    PriorityProperty<Integer> p2 = propertyFactory.getOrCreate(int.class, null, 0, \"high\", \"low\");\r\n\r\n    assertThat(p1).isSameAs(p2);\r\n    assertThat(propertyFactory.getProperties().count()).isEqualTo(1);\r\n  }\r\n\r\n  @Test\r\n  void should_create_different_instances_for_different_parameter() {\r\n    PriorityProperty<Integer> p1 = propertyFactory.getOrCreate(int.class, null, 0, \"high\", \"low\");\r\n    PriorityProperty<Long> p2 = propertyFactory.getOrCreate(long.class, null, 0L, \"high\", \"low\");\r\n\r\n    assertThat(p1).isNotSameAs(p2);\r\n    assertThat(propertyFactory.getProperties().count()).isEqualTo(2);\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-config/src/test/java/org/apache/servicecomb/config/priority/TestPriorityPropertyManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.config.priority;\n\nimport org.apache.servicecomb.config.inject.InjectProperties;\nimport org.apache.servicecomb.config.inject.InjectProperty;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPriorityPropertyManager extends TestPriorityPropertyBase {\n  String high = \"ms.schema.op\";\n\n  String middle = \"ms.schema\";\n\n  String low = \"ms\";\n\n  String[] keys = {high, middle, low};\n\n  @InjectProperties(prefix = \"root\")\n  public static class ConfigWithAnnotation {\n    @InjectProperty(prefix = \"override\", keys = {\"high\", \"low\"}, defaultValue = \"abc\")\n    public String strValue;\n  }\n\n  private void waitKeyForGC(PriorityPropertyManager priorityPropertyManager) {\n    long maxTime = 10000;\n    long currentTime = System.currentTimeMillis();\n    while (System.currentTimeMillis() - currentTime < maxTime) {\n      if (priorityPropertyManager.getConfigObjectMap().isEmpty()) {\n        break;\n      }\n      System.runFinalization();\n      System.gc();\n      try {\n        Thread.yield();\n        Thread.sleep(10);\n      } catch (InterruptedException e) {\n        e.printStackTrace();\n      }\n    }\n  }\n\n  @Test\n  public void testConfigurationsAreGCCollected() {\n    long timeBegin = System.currentTimeMillis();\n\n    for (int i = 0; i < 100; i++) {\n      for (int j = 0; j < 100; j++) {\n        ConfigWithAnnotation configConfigObject = priorityPropertyManager.createConfigObject(\n            ConfigWithAnnotation.class);\n        Assertions.assertEquals(\"abc\", configConfigObject.strValue);\n        PriorityProperty<Long> configPriorityProperty = propertyFactory.getOrCreate(Long.class, -1L, -2L, keys);\n        Assertions.assertEquals(-2L, (long) configPriorityProperty.getValue());\n      }\n    }\n\n    waitKeyForGC(priorityPropertyManager);\n\n    Assertions.assertTrue(priorityPropertyManager.getConfigObjectMap().isEmpty());\n    System.out.println(\"Token : \" + (System.currentTimeMillis() - timeBegin));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-config/src/test/resources/empty.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n"
  },
  {
    "path": "foundations/foundation-config/src/test/resources/m1.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nzq:\n  test: okok\n"
  },
  {
    "path": "foundations/foundation-config/src/test/resources/mapping.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\nservicecomb-config-order: 0\n\nCSE_ENV_MAPPING: servicecomb.testmapping.key\nMY_SERVICES_ENDPOINT:\n  - servicecomb.service.mapping.address\n  - servicecomb.service1.mapping.address\nSERVICECOMB_ENV:\n  - service_description.environment\n  - service_description.environment.old\n"
  },
  {
    "path": "foundations/foundation-config/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\ntrace:\n  handler:\n    enabled: false\n    sampler:\n      percent: 0.5\n  metric:\n    service:\n      enable: false\nzq:\n  - tlist: a\n  - tlist: b\n  - tlist: 1\nvalidate:\n  parameter:\n    enabled: true\n  returnValue:\n    enabled: true\n  apiInvoke:\n    enabled: true\n\nshutDownHandler:\n  enabled: true\n  timeLimit: 30000\n\neureka:\n  instance:\n    preferIpAddress: true\n    leaseRenewalIntervalInSeconds: 3\n    leaseExpirationDurationInSeconds: 5\n  client:\n    serviceUrl:\n      defaultZone: http://10.120.169.202:9980/\n\ncse:\n  config:\n    client:\n      serviceName: testDemo\n      serverUri: https://10.22.87.59:30103\n      tenantName: csetest\n      refreshMode: 1\n      refresh_interval: 10000\n\nservice_description:\n  name: testDemo\n\nholder: b,c,d\ntest:\n  commonSeparatedString: a,b,c\n  commonSeparatedStringHolder: ${holder}\n  stringArray:\n    - m\n    - n\n"
  },
  {
    "path": "foundations/foundation-config/src/test/resources/test1.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: \"1\"\n\ntrace:\n  handler:\n    enabled: false\n    sampler:\n      percent: 0.5\n  metric:\n    service:\n      enable: false\n\nvalidate:\n  parameter:\n    enabled: true\n  returnValue:\n    enabled: true\n  apiInvoke:\n    enabled: true\n\nshutDownHandler:\n  enabled: true\n  timeLimit: 30000\n\nhas:\n  manager:\n    url:  127.0.0.1\n  serializer:\n    default: protostuff\n  provider:\n    service:\n      name: ${spring.application.name}\n      version: 1.2\n      group: prod\n      protocols:\n        rpc:\n          serviceLevel: interface\n          dsf:\n#            ip: \"10.57.65.225\"\n            port: 7450\n\neureka:\n  instance:\n    preferIpAddress: true\n    leaseRenewalIntervalInSeconds: 3\n    leaseExpirationDurationInSeconds: 5\n  client:\n    serviceUrl:\n      defaultZone: http://10.120.169.202:9980/\n"
  },
  {
    "path": "foundations/foundation-config/src/test/resources/test2.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: 0\n\ndsf:\n  serializer:\n    kryo:\n      enabled: true\n      referencesRequired: false\n      registrationRequired: false\n"
  },
  {
    "path": "foundations/foundation-metrics/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>foundations</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>foundation-metrics</artifactId>\n  <name>Java Chassis::Foundations::Metrics</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.micrometer</groupId>\n      <artifactId>micrometer-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.util.concurrent.ThreadFactoryBuilder;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class MetricsBootstrap {\n  private static final Logger LOGGER = LoggerFactory.getLogger(MetricsBootstrap.class);\n\n  private final MetricsBootstrapConfig config;\n\n  private MeterRegistry meterRegistry;\n\n  private EventBus eventBus;\n\n  private ScheduledExecutorService executorService;\n\n  private List<MetricsInitializer> metricsInitializers;\n\n  @Autowired\n  public MetricsBootstrap(MetricsBootstrapConfig config) {\n    this.config = config;\n  }\n\n  @Autowired\n  public void setMetricsInitializers(List<MetricsInitializer> metricsInitializers) {\n    this.metricsInitializers = metricsInitializers;\n  }\n\n  @Autowired\n  public void setMeterRegistry(MeterRegistry meterRegistry) {\n    this.meterRegistry = meterRegistry;\n  }\n\n  public void start(EventBus eventBus) {\n    this.eventBus = eventBus;\n    this.executorService = Executors.newScheduledThreadPool(1,\n        new ThreadFactoryBuilder()\n            .setNameFormat(\"metrics-poller-%d\")\n            .build());\n\n    metricsInitializers.forEach(initializer -> initializer.init(this.meterRegistry, eventBus, config));\n    startPoll();\n  }\n\n  public void shutdown() {\n    if (executorService != null) {\n      executorService.shutdown();\n    }\n\n    Collections.reverse(metricsInitializers);\n    metricsInitializers.forEach(MetricsInitializer::destroy);\n  }\n\n  protected void startPoll() {\n    executorService.scheduleAtFixedRate(this::pollMeters,\n        config.getMsPollInterval(),\n        config.getMsPollInterval(),\n        TimeUnit.MILLISECONDS);\n  }\n\n  public synchronized void pollMeters() {\n    metricsInitializers.forEach(initializer -> {\n      if (initializer instanceof PeriodMeter) {\n        ((PeriodMeter) initializer).poll(System.currentTimeMillis(), config.getMsPollInterval());\n      }\n    });\n    try {\n      PolledEvent polledEvent = new PolledEvent(meterRegistry.getMeters());\n      eventBus.post(polledEvent);\n    } catch (Throwable e) {\n      LOGGER.error(\"poll meters error. \", e);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsBootstrapConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics;\n\nimport org.springframework.core.env.Environment;\n\npublic class MetricsBootstrapConfig {\n  public static final String METRICS_WINDOW_TIME = \"servicecomb.metrics.window_time\";\n\n  public static final String CONFIG_LATENCY_DISTRIBUTION = \"servicecomb.metrics.invocation.latencyDistribution\";\n\n  public static final String CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN =\n      \"servicecomb.metrics.publisher.defaultLog.invocation.latencyDistribution.minScopeLength\";\n\n  public static final int DEFAULT_METRICS_WINDOW_TIME = 300_000;\n\n  private long msPollInterval;\n\n  private String latencyDistribution;\n\n  private int minScopeLength;\n\n  private Environment environment;\n\n  public MetricsBootstrapConfig(Environment environment) {\n    this.environment = environment;\n    msPollInterval =\n        environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME);\n    if (msPollInterval < 1000) {\n      msPollInterval = 1000;\n    }\n\n    latencyDistribution = environment.getProperty(CONFIG_LATENCY_DISTRIBUTION, String.class);\n    minScopeLength = environment.getProperty(\n        CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7);\n  }\n\n  public Environment getEnvironment() {\n    return environment;\n  }\n\n  public long getMsPollInterval() {\n    return msPollInterval;\n  }\n\n  public String getLatencyDistribution() {\n    return latencyDistribution;\n  }\n\n  public int getMinScopeLength() {\n    return minScopeLength;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/MetricsInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic interface MetricsInitializer {\n  default int getOrder() {\n    return 0;\n  }\n\n  void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config);\n\n  default void destroy() {\n\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/PolledEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics;\n\nimport java.util.List;\n\nimport io.micrometer.core.instrument.Meter;\n\n\npublic class PolledEvent {\n  private List<Meter> meters;\n\n  public PolledEvent(List<Meter> meters) {\n    this.meters = meters;\n  }\n\n  public List<Meter> getMeters() {\n    return meters;\n  }\n\n  public void setMeters(List<Meter> meters) {\n    this.meters = meters;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckResult.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.metrics.health;\n\npublic class HealthCheckResult {\n  private boolean healthy;\n\n  private String information;\n\n  private String extraData;\n\n  private long timestamp;\n\n  public boolean isHealthy() {\n    return healthy;\n  }\n\n  public String getInformation() {\n    return information;\n  }\n\n  public String getExtraData() {\n    return extraData;\n  }\n\n  public long getTimestamp() {\n    return timestamp;\n  }\n\n  public HealthCheckResult() {\n  }\n\n  public HealthCheckResult(boolean healthy, String information, String extraData) {\n    this();\n    this.healthy = healthy;\n    this.information = information;\n    this.extraData = extraData;\n    this.timestamp = System.currentTimeMillis();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthChecker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.metrics.health;\n\npublic interface HealthChecker {\n  String getName();\n\n  HealthCheckResult check();\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/health/HealthCheckerManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.metrics.health;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\npublic class HealthCheckerManager {\n  private final Map<String, HealthChecker> healthCheckers;\n\n  private static final HealthCheckerManager INSTANCE = new HealthCheckerManager();\n\n  public static HealthCheckerManager getInstance() {\n    return INSTANCE;\n  }\n\n  private HealthCheckerManager() {\n    this.healthCheckers = new ConcurrentHashMap<>();\n    List<HealthChecker> checkers = SPIServiceUtils.getAllService(HealthChecker.class);\n    for (HealthChecker checker : checkers) {\n      register(checker);\n    }\n  }\n\n  public void register(HealthChecker checker) {\n    healthCheckers.put(checker.getName(), checker);\n  }\n\n  public void unregister(String name) {\n    healthCheckers.remove(name);\n  }\n\n  public Map<String, HealthCheckResult> check() {\n    return healthCheckers.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> e.getValue().check()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/meter/LatencyDistributionConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.meter;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class LatencyDistributionConfig {\n  public static final Long MAX_LATENCY = 60 * 60 * 1000L;\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(LatencyDistributionConfig.class);\n\n  private final List<LatencyScopeConfig> scopeConfigs = new ArrayList<>();\n\n  /**\n   *\n   * @param config scope definition, time unit is milliseconds, eg:0,1,10\n   */\n  public LatencyDistributionConfig(String config) {\n    if (StringUtils.isEmpty(config)) {\n      return;\n    }\n    config = config.trim() + \",\" + MAX_LATENCY;\n    String[] array = config.split(\"\\\\s*,+\\\\s*\");\n    try {\n      for (int idx = 0; idx < array.length - 1; idx++) {\n        long msMin = Long.parseLong(array[idx]);\n        long msMax = Long.parseLong(array[idx + 1]);\n        if (msMin >= msMax) {\n          String msg = String.format(\"invalid latency scope, min=%s, max=%s.\", array[idx], array[idx + 1]);\n          throw new IllegalStateException(msg);\n        }\n\n        LatencyScopeConfig latencyScopeConfig = new LatencyScopeConfig(msMin, msMax);\n        scopeConfigs.add(latencyScopeConfig);\n      }\n    } catch (Throwable e) {\n      LOGGER.error(\"Failed to parse latencyDistributionConfig, value={}\", config, e);\n      throw e;\n    }\n  }\n\n  public List<LatencyScopeConfig> getScopeConfigs() {\n    return scopeConfigs;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/meter/LatencyScopeConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.meter;\n\npublic class LatencyScopeConfig {\n  // [min, max)\n  // even max equals Long.MAX_VALUE, still not include it\n  // because it will never happened in real cases\n  private final long msMin;\n\n  private final long msMax;\n\n  public LatencyScopeConfig(long msMin, long msMax) {\n    this.msMin = msMin;\n    this.msMax = msMax;\n  }\n\n  public long getMsMin() {\n    return msMin;\n  }\n\n  public long getMsMax() {\n    return msMax;\n  }\n\n  @Override\n  public String toString() {\n    return \"LatencyScopeConfig[\" + msMin + \", \" + msMax + ')';\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/meter/PeriodMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.meter;\n\npublic interface PeriodMeter {\n  void poll(long msNow, long secondInterval);\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/DefaultTagFinder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish;\n\n\nimport io.micrometer.core.instrument.Tag;\n\npublic class DefaultTagFinder implements TagFinder {\n  private final String tagKey;\n\n  private boolean skipOnNull;\n\n  public DefaultTagFinder(String tagKey) {\n    this.tagKey = tagKey;\n  }\n\n  public DefaultTagFinder(String tagKey, boolean skipOnNull) {\n    this.tagKey = tagKey;\n    this.skipOnNull = skipOnNull;\n  }\n\n  @Override\n  public boolean skipOnNull() {\n    return skipOnNull;\n  }\n\n  @Override\n  public String getTagKey() {\n    return tagKey;\n  }\n\n  @Override\n  public Tag find(Iterable<Tag> tags) {\n    for (Tag tag : tags) {\n      if (tag.getKey().equals(tagKey)) {\n        return tag;\n      }\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MeasurementGroupConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\npublic class MeasurementGroupConfig {\n  // key is measurement id name\n  private final Map<String, List<TagFinder>> groups = new HashMap<>();\n\n  public MeasurementGroupConfig() {\n  }\n\n  public MeasurementGroupConfig(String idName, Object... tagNameOrFinders) {\n    addGroup(idName, tagNameOrFinders);\n  }\n\n  public void addGroup(String idName, Object... tagNameOrFinders) {\n    groups.put(idName,\n        Arrays\n            .asList(tagNameOrFinders)\n            .stream()\n            .map(TagFinder::build)\n            .collect(Collectors.toList()));\n  }\n\n  public List<TagFinder> findTagFinders(String idName) {\n    return groups.get(idName);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MeasurementNode.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish;\n\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter.Id;\n\npublic class MeasurementNode implements Comparable<MeasurementNode> {\n  private final String name;\n\n  private final Id id;\n\n  private final List<Measurement> measurements = new ArrayList<>();\n\n  private Map<String, MeasurementNode> children;\n\n  public MeasurementNode(String name, Id id, Map<String, MeasurementNode> children) {\n    this.name = name;\n    this.id = id;\n    this.children = children;\n  }\n\n  public String getName() {\n    return this.name;\n  }\n\n  public Id getId() {\n    return id;\n  }\n\n  public Map<String, MeasurementNode> getChildren() {\n    return children;\n  }\n\n  public MeasurementNode findChild(String childName) {\n    if (children == null) {\n      return null;\n    }\n    return children.get(childName);\n  }\n\n  public MeasurementNode findChild(String... childNames) {\n    MeasurementNode node = this;\n    for (String childName : childNames) {\n      if (node == null) {\n        return null;\n      }\n\n      node = node.findChild(childName);\n    }\n    return node;\n  }\n\n  public MeasurementNode addChild(String childName, Id id, Measurement measurement) {\n    if (children == null) {\n      children = new LinkedHashMap<>();\n    }\n\n    MeasurementNode node = children.computeIfAbsent(childName, name -> new MeasurementNode(name, id, null));\n\n    if (measurement != null) {\n      node.addMeasurement(measurement);\n    }\n\n    return node;\n  }\n\n  public List<Measurement> getMeasurements() {\n    return measurements;\n  }\n\n  public void addMeasurement(Measurement measurement) {\n    measurements.add(measurement);\n  }\n\n  public double summary() {\n    double result = 0;\n    for (Measurement measurement : measurements) {\n      result += measurement.getValue();\n    }\n\n    return result;\n  }\n\n  @Override\n  public int compareTo(MeasurementNode o) {\n    return this.name.compareTo(o.name);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/MeasurementTree.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport io.micrometer.core.instrument.DistributionSummary;\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter;\nimport io.micrometer.core.instrument.Meter.Id;\nimport io.micrometer.core.instrument.Statistic;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.distribution.CountAtBucket;\nimport io.micrometer.core.instrument.distribution.HistogramSnapshot;\n\n// like select * from meters group by ......\n// but output a tree not a table\npublic class MeasurementTree extends MeasurementNode {\n  public MeasurementTree() {\n    super(null, null, null);\n  }\n\n  // groupConfig:\n  //   key: id name\n  //   value: id tag keys\n  // only id name exists in groupConfig will accept, others will be ignored\n  public void from(Iterator<Meter> meters, MeasurementGroupConfig groupConfig) {\n    meters.forEachRemaining(meter -> {\n      // This code snip is not very good design. But DistributionSummary is quite special.\n      if (meter instanceof DistributionSummary distributionSummary) {\n        HistogramSnapshot snapshot = distributionSummary.takeSnapshot();\n        CountAtBucket[] countAtBuckets = snapshot.histogramCounts();\n        List<Measurement> distributions = new ArrayList<>(countAtBuckets.length);\n        for (CountAtBucket countAtBucket : countAtBuckets) {\n          final double value = countAtBucket.count();\n          distributions.add(new Measurement(() -> value,\n              Statistic.COUNT));\n        }\n\n        from(meter.getId(), distributions, groupConfig);\n        return;\n      }\n\n      Iterable<Measurement> measurements = meter.measure();\n      from(meter.getId(), measurements, groupConfig);\n    });\n  }\n\n  public void from(Id id, Iterable<Measurement> measurements, MeasurementGroupConfig groupConfig) {\n    for (Measurement measurement : measurements) {\n      MeasurementNode node = addChild(id.getName(), id, measurement);\n\n      List<TagFinder> tagFinders = groupConfig.findTagFinders(id.getName());\n      if (tagFinders == null) {\n        continue;\n      }\n\n      for (TagFinder tagFinder : tagFinders) {\n        Tag tag = tagFinder.find(id.getTags());\n        if (tag == null) {\n          if (tagFinder.skipOnNull()) {\n            break;\n          }\n          throw new IllegalStateException(\n              String.format(\"tag key \\\"%s\\\" not exist in %s\",\n                  tagFinder.getTagKey(),\n                  id));\n        }\n\n        node = node.addChild(tag.getValue(), id, measurement);\n      }\n\n      node.addChild(measurement.getStatistic().name(), id, measurement);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/main/java/org/apache/servicecomb/foundation/metrics/publish/TagFinder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish;\n\nimport io.micrometer.core.instrument.Tag;\n\npublic interface TagFinder {\n  static TagFinder build(Object obj) {\n    if (String.class.isInstance(obj)) {\n      return new DefaultTagFinder((String) obj);\n    }\n\n    if (TagFinder.class.isInstance(obj)) {\n      return (TagFinder) obj;\n    }\n\n    throw new IllegalArgumentException(\n        \"only support String or TagFinder, but got \" +\n            (obj == null ? \"null\" : obj.getClass().getName()));\n  }\n\n  default boolean skipOnNull() {\n    return false;\n  }\n\n  String getTagKey();\n\n  // read target tag from tags\n  // return directly or do some change and then return\n  Tag find(Iterable<Tag> tags);\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/TestMetricsBootstrap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.concurrent.ScheduledExecutorService;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport mockit.Deencapsulation;\n\npublic class TestMetricsBootstrap {\n  MetricsBootstrap bootstrap;\n\n  EventBus eventBus = new EventBus();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n\n    MetricsBootstrapConfig config = new MetricsBootstrapConfig(environment);\n    bootstrap = new MetricsBootstrap(config);\n    bootstrap.setMetricsInitializers(List.of());\n  }\n\n  @Test\n  public void loadMetricsInitializers() {\n    List<MetricsInitializer> initList = new ArrayList<>();\n    MetricsInitializer metricsInitializer = new MetricsInitializer() {\n      @Override\n      public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n        initList.add(this);\n      }\n    };\n\n    bootstrap.setMetricsInitializers(Arrays.asList(metricsInitializer, metricsInitializer));\n\n    bootstrap.start(eventBus);\n    bootstrap.shutdown();\n\n    MatcherAssert.assertThat(initList, Matchers.contains(metricsInitializer, metricsInitializer));\n  }\n\n  @Test\n  public void shutdown() {\n    ScheduledExecutorService scheduledExecutorService = Mockito.mock(ScheduledExecutorService.class);\n    List<MetricsInitializer> destroyList = new ArrayList<>();\n    MetricsInitializer initializer1 = new MetricsInitializer() {\n      @Override\n      public int getOrder() {\n        return 1;\n      }\n\n      @Override\n      public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n      }\n\n      @Override\n      public void destroy() {\n        destroyList.add(this);\n      }\n    };\n\n    MetricsInitializer initializer2 = new MetricsInitializer() {\n      @Override\n      public int getOrder() {\n        return 2;\n      }\n\n      @Override\n      public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n      }\n\n      @Override\n      public void destroy() {\n        destroyList.add(this);\n      }\n    };\n    bootstrap.setMetricsInitializers(Arrays.asList(initializer1, initializer2));\n    Deencapsulation.setField(bootstrap, \"executorService\", scheduledExecutorService);\n\n    bootstrap.shutdown();\n\n    MatcherAssert.assertThat(destroyList, Matchers.contains(initializer2, initializer1));\n  }\n\n  @Test\n  public void shutdown_notStart() {\n    Assertions.assertNull(Deencapsulation.getField(bootstrap, \"executorService\"));\n\n    // should not throw exception\n    bootstrap.shutdown();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/health/TestHealthCheckerManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.metrics.health;\n\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class TestHealthCheckerManager {\n\n  private final HealthChecker good = new HealthChecker() {\n    @Override\n    public String getName() {\n      return \"testBad\";\n    }\n\n    @Override\n    public HealthCheckResult check() {\n      return new HealthCheckResult(false, \"bad\", \"bad component\");\n    }\n  };\n\n  private final HealthChecker bad = new HealthChecker() {\n    @Override\n    public String getName() {\n      return \"testGood\";\n    }\n\n    @Override\n    public HealthCheckResult check() {\n      return new HealthCheckResult(true, \"good\", \"good component\");\n    }\n  };\n\n  @BeforeEach\n  public void reset() {\n    HealthCheckerManager.getInstance().unregister(good.getName());\n    HealthCheckerManager.getInstance().unregister(bad.getName());\n  }\n\n  @Test\n  public void checkResultCount_None() {\n    Map<String, HealthCheckResult> results = HealthCheckerManager.getInstance().check();\n    Assertions.assertEquals(0, results.size());\n  }\n\n  @Test\n  public void checkResultCount_One() {\n    HealthCheckerManager.getInstance().register(good);\n    Map<String, HealthCheckResult> results = HealthCheckerManager.getInstance().check();\n    Assertions.assertEquals(1, results.size());\n  }\n\n  @Test\n  public void checkResultCount_Both() {\n    HealthCheckerManager.getInstance().register(good);\n    HealthCheckerManager.getInstance().register(bad);\n    Map<String, HealthCheckResult> results = HealthCheckerManager.getInstance().check();\n    Assertions.assertEquals(2, results.size());\n  }\n\n  @Test\n  public void checkGoodResult() {\n    HealthCheckerManager.getInstance().register(good);\n    HealthCheckerManager.getInstance().register(bad);\n    HealthCheckResult result = HealthCheckerManager.getInstance().check().get(\"testGood\");\n    Assertions.assertTrue(result.isHealthy());\n    Assertions.assertEquals(\"good\", result.getInformation());\n    Assertions.assertEquals(\"good component\", result.getExtraData());\n  }\n\n  @Test\n  public void checkBadResult() {\n    HealthCheckerManager.getInstance().register(good);\n    HealthCheckerManager.getInstance().register(bad);\n    HealthCheckResult result = HealthCheckerManager.getInstance().check().get(\"testBad\");\n    Assertions.assertFalse(result.isHealthy());\n    Assertions.assertEquals(\"bad\", result.getInformation());\n    Assertions.assertEquals(\"bad component\", result.getExtraData());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/meter/TestLatencyDistributionConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.meter;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestLatencyDistributionConfig {\n\n  @Test\n  public void testValidProperty() {\n    String validProperty1 = \"0,1,2,10\";\n    String validProperty2 = \"0,1,  2  , 10 \";\n    String validProperty3 = \"0,1,2,10,\";\n\n    LatencyDistributionConfig config1 = new LatencyDistributionConfig(validProperty1);\n    LatencyDistributionConfig config2 = new LatencyDistributionConfig(validProperty2);\n    LatencyDistributionConfig config3 = new LatencyDistributionConfig(validProperty3);\n\n    Assertions.assertEquals(4, config1.getScopeConfigs().size());\n    Assertions.assertEquals(4, config2.getScopeConfigs().size());\n    Assertions.assertEquals(4, config3.getScopeConfigs().size());\n  }\n\n  @Test\n  public void testInValidProperty1() {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      LatencyDistributionConfig latencyDistributionConfig = new LatencyDistributionConfig(\"2,1,10\");\n      Assertions.assertEquals(0, latencyDistributionConfig.getScopeConfigs().size());\n    });\n    Assertions.assertEquals(\"invalid latency scope, min=2, max=1.\", exception.getMessage());\n  }\n\n  @Test\n  public void testInValidProperty2() {\n    NumberFormatException exception = Assertions.assertThrows(NumberFormatException.class, () -> {\n      LatencyDistributionConfig latencyDistributionConfig = new LatencyDistributionConfig(\"a,1,10\");\n      Assertions.assertEquals(0, latencyDistributionConfig.getScopeConfigs().size());\n    });\n    Assertions.assertEquals(\"For input string: \\\"a\\\"\", exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestDefaultTagFinder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish.spectator;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.metrics.publish.DefaultTagFinder;\nimport org.apache.servicecomb.foundation.metrics.publish.TagFinder;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.micrometer.core.instrument.Tag;\n\npublic class TestDefaultTagFinder {\n  TagFinder finder = new DefaultTagFinder(\"key\");\n\n  @Test\n  public void getTagKey() {\n    Assertions.assertEquals(\"key\", finder.getTagKey());\n  }\n\n  @Test\n  public void readSucc() {\n    Tag tag = Tag.of(\"key\", \"value\");\n    List<Tag> tags = Arrays.asList(Tag.of(\"t1\", \"t1v\"),\n        tag);\n\n    Assertions.assertSame(tag, finder.find(tags));\n  }\n\n  @Test\n  public void readFail() {\n    List<Tag> tags = Arrays.asList(Tag.of(\"t1\", \"t1v\"));\n\n    Assertions.assertNull(finder.find(tags));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementGroupConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish.spectator;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.TagFinder;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport mockit.Deencapsulation;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMeasurementGroupConfig {\n  MeasurementGroupConfig config = new MeasurementGroupConfig();\n\n  Map<String, List<TagFinder>> groups = Deencapsulation.getField(config, \"groups\");\n\n  @Test\n  public void defaultConstruct() {\n    Assertions.assertTrue(groups.isEmpty());\n  }\n\n  @Test\n  public void constructAddGroup() {\n    config = new MeasurementGroupConfig(\"id\", \"tag1\");\n    groups = Deencapsulation.getField(config, \"groups\");\n\n    MatcherAssert.assertThat(groups.keySet(), Matchers.contains(\"id\"));\n    MatcherAssert.assertThat(groups.get(\"id\").stream().map(TagFinder::getTagKey).toArray(),\n            Matchers.arrayContaining(\"tag1\"));\n  }\n\n  @Test\n  public void addGroup() {\n    config.addGroup(\"id1\", \"tag1.1\", \"tag1.2\");\n    config.addGroup(\"id2\", \"tag2.1\", \"tag2.2\");\n\n    MatcherAssert.assertThat(groups.keySet(), Matchers.containsInAnyOrder(\"id2\", \"id1\"));\n    MatcherAssert.assertThat(groups.get(\"id1\").stream().map(TagFinder::getTagKey).toArray(), Matchers.arrayContaining(\"tag1.1\", \"tag1.2\"));\n    MatcherAssert.assertThat(groups.get(\"id2\").stream().map(TagFinder::getTagKey).toArray(), Matchers.arrayContaining(\"tag2.1\", \"tag2.2\"));\n  }\n\n  @Test\n  public void findTagReaders() {\n    config.addGroup(\"id1\", \"tag1.1\", \"tag1.2\");\n    config.addGroup(\"id2\", \"tag2.1\", \"tag2.2\");\n\n    MatcherAssert.assertThat(config.findTagFinders(\"id2\").stream().map(TagFinder::getTagKey).toArray(),\n            Matchers.arrayContaining(\"tag2.1\", \"tag2.2\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementNode.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish.spectator;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter.Id;\nimport io.micrometer.core.instrument.Meter.Type;\nimport io.micrometer.core.instrument.Tags;\nimport mockit.Expectations;\nimport mockit.Mocked;\n\npublic class TestMeasurementNode {\n  Id id = new Id(\"name\", Tags.empty(), null, null, Type.OTHER);\n\n  MeasurementNode node = new MeasurementNode(\"name\", id, null);\n\n  @Test\n  public void getName() {\n    Assertions.assertEquals(\"name\", node.getName());\n  }\n\n  @Test\n  public void getChildren() {\n    Map<String, MeasurementNode> children = new HashMap<>();\n    node = new MeasurementNode(\"name\", id, children);\n\n    Assertions.assertSame(children, node.getChildren());\n  }\n\n  @Test\n  public void findChild_noChildren() {\n    Assertions.assertNull(node.findChild(\"child\"));\n  }\n\n  @Test\n  public void findChild_multiLevel_noMiddleChildren(@Mocked Measurement measurement) {\n    MeasurementNode c1 = node.addChild(\"c1\", id, measurement);\n    c1.addChild(\"c2\", id, measurement);\n\n    Assertions.assertNull(node.findChild(\"c1_notExist\", \"c2\"));\n  }\n\n  @Test\n  public void findChild_multiLevel_ok(@Mocked Measurement measurement) {\n    MeasurementNode c1 = node.addChild(\"c1\", id, measurement);\n    MeasurementNode c2 = c1.addChild(\"c2\", id, measurement);\n\n    Assertions.assertSame(c2, node.findChild(\"c1\", \"c2\"));\n  }\n\n  @Test\n  public void addChild(@Mocked Measurement measurement) {\n    MeasurementNode c1 = node.addChild(\"c1\", id, measurement);\n    MeasurementNode c2 = node.addChild(\"c2\", id, measurement);\n\n    Assertions.assertSame(c1, node.findChild(\"c1\"));\n    Assertions.assertSame(c2, node.findChild(\"c2\"));\n  }\n\n  @Test\n  public void getMeasurements(@Mocked Measurement measurement) {\n    node.addMeasurement(measurement);\n\n    MatcherAssert.assertThat(node.getMeasurements(), Matchers.contains(measurement));\n  }\n\n  @Test\n  public void summary(@Mocked Measurement measurement) {\n    new Expectations() {\n      {\n        measurement.getValue();\n        result = 10;\n      }\n    };\n    node.addMeasurement(measurement);\n    node.addMeasurement(measurement);\n\n    Assertions.assertEquals(20, node.summary(), 0);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementTree.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish.spectator;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.foundation.metrics.publish.DefaultTagFinder;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Statistic;\nimport io.micrometer.core.instrument.Timer;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\n\npublic class TestMeasurementTree {\n  MeasurementTree tree = new MeasurementTree();\n\n  MeterRegistry registry = new SimpleMeterRegistry();\n\n  Timer timer;\n\n  @Before\n  public void setup() {\n    timer = registry.timer(\"id\",\n        \"g1\",\n        \"g1v\",\n        \"g2\",\n        \"g2v\",\n        \"t3\",\n        \"t3v\",\n        \"t4\",\n        \"t4v\");\n    registry.counter(\"id_notCare\");\n  }\n\n  @Test\n  public void from() {\n    timer.record(10, TimeUnit.SECONDS);\n    timer.record(2, TimeUnit.SECONDS);\n\n    MeasurementGroupConfig config = new MeasurementGroupConfig(\"id\", \"g1\", \"g2\");\n    tree.from(registry.getMeters().iterator(), config);\n\n    Assertions.assertEquals(2, tree.getChildren().size());\n\n    MeasurementNode node = tree.findChild(\"id\", \"g1v\", \"g2v\");\n    Assertions.assertEquals(2d,\n        node.findChild(Statistic.COUNT.name()).getMeasurements().get(0).getValue(), 0);\n    Assertions.assertEquals(12d,\n        node.findChild(Statistic.TOTAL_TIME.name()).getMeasurements().get(0).getValue(), 0);\n    Assertions.assertEquals(0d, tree.findChild(\"id_notCare\").summary(), 0);\n  }\n\n  @Test\n  public void from_withSkipOnNull() {\n    try {\n      MeasurementGroupConfig config = new MeasurementGroupConfig(\"id\", new DefaultTagFinder(\"notExist\", true));\n      tree.from(registry.getMeters().iterator(), config);\n    } catch (Exception e) {\n      Assertions.fail(\"should not throw exception\");\n    }\n  }\n\n  @Test\n  public void from_failed() {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      MeasurementGroupConfig config = new MeasurementGroupConfig(\"id\", \"notExist\");\n      tree.from(registry.getMeters().iterator(), config);\n    });\n    Assertions.assertEquals(\n        \"tag key \\\"notExist\\\" not exist in MeterId{name='id', tags=[tag(g1=g1v),tag(g2=g2v),tag(t3=t3v),tag(t4=t4v)]}\",\n        exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestTagFinder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.metrics.publish.spectator;\n\nimport org.apache.servicecomb.foundation.metrics.publish.DefaultTagFinder;\nimport org.apache.servicecomb.foundation.metrics.publish.TagFinder;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestTagFinder {\n\n  @Test\n  public void buildFromString() {\n    String name = \"key\";\n    TagFinder finder = TagFinder.build(name);\n\n    Assertions.assertEquals(name, finder.getTagKey());\n    Assertions.assertEquals(DefaultTagFinder.class, finder.getClass());\n  }\n\n  @Test\n  public void buildFromTagFinder() {\n    TagFinder finder = new DefaultTagFinder(\"key\");\n    Assertions.assertSame(finder, TagFinder.build(finder));\n    DefaultTagFinder tagFinder = new DefaultTagFinder(\"key\", true);\n    Assertions.assertSame(tagFinder, TagFinder.build(tagFinder));\n  }\n\n  @Test\n  public void buildFromInvalidType() {\n    IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> TagFinder.build(1));\n    Assertions.assertEquals(\"only support String or TagFinder, but got \" + Integer.class.getName(), exception.getMessage());\n  }\n\n  @Test\n  public void buildFromNull() {\n    IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> TagFinder.build(null));\n    Assertions.assertEquals(\"only support String or TagFinder, but got null\", exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/README.md",
    "content": "# Overview\nThere are many existing protobuf codecs, but all of them are not suit for us.\nServiceComb data model is just POJO, not bind to any codec mechanism, so we had to create new one:\n\n|                                                          | ServiceComb   | protobuf | protostuff     | jackson |\n| -------------------------------------------------------- | :-----------: | :------: | :------------: | :-----: |\n| generate code | no need<br>just POJO | must<br>100+ lines IDL, generate 10000+ java code     | no need<br>POJO with Annotation(eg:@Tag) | no need |\n| support null element in repeated field                   | no            | no       | not compatible | no      |\n| support \"oneOf\"                                          | no            | yes      | no             | no      |\n| support \"packed\"                                         | yes           | yes      | no             | no      |\n| support \"map\"                                            | yes           | yes      | not compatible | no      |\n| support \"any\"                                            | yes           | yes      | not compatible | no      |\n| support \"any\" not defined in IDL                         | yes<br>extend based on \"any\" mechanism           | no       | not compatible | no      |\n| support field: `List<List<X>>`                           | yes           | no       | not compatible | no      |\n| support field: `List<Map<X, Y>>`                         | yes           | no       | not compatible | no      |\n| support field: `Map<X, List<Y>>`                         | yes           | no       | not compatible | no      |\n| support field: `Map<X, Map<Y, Z>>`                       | yes           | no       | not compatible | no      |\n| support field: array                                     | yes           | no       | not compatible | no      |\n| support generic POJO type, eg:`CustomGeneric<User>`      | yes           | no       | no             | no      |\n| serialize/deserialize based on IDL                       | yes           | no       | no             | yes     |\n| serialize not repeated number field ignore default value | yes           | yes      | no             | no      |\n| serialize from map model                                 | yes           | no       | no             | no      |\n| deserialize to map model                                 | yes           | no       | no             | no      |\n\n# Usage\n## Create factory\n  one factory instance globally is enough\n```java\nProtoMapperFactory factory = new ProtoMapperFactory();\n```\n## Load proto definition\n  create mapper instance for each proto definition\n- load from classpath\n```java\nProtoMapper protoMapper = factory.createFromName(\"protobuf.proto\");\n```\n- load from proto content\n```java\nProtoMapper protoMapper = factory.createFromContent(protoContent);\n```\n## Serialize\nserializer is reusable and thread safe\nAssuming you have a proto definition\n```proto\nmessage User {\n  string name = 1;\n}\n```\nand a POJO class\n```java\npublic class User {\n  private String name;\n  // getter and setter\n}\n```\nRootSerializer serializer = protoMapper.createRootSerializer(\"User\", User.class);\n\nUser user = new User();\nuser.setName(\"userName\");\nbyte[] pojoBytes= serializer.serialize(user);\n\nMap<String, Object> map = new HashMap<>();\nmap.put(\"name\", \"userName\");\nbyte[] mapBytes = serializer.serialize(map);\n```java\n\n\n// pojoBytes equals mapBytes\n```\n## Deserialize\ndeserializer is reusable and thread safe\n```java\nRootDeserializer<User> pojoDeserializer = protoMapper.createRootDeserializer(\"User\", User.class);\nRootDeserializer<Map<String, Object>> mapDeserializer = protoMapper.createRootDeserializer(\"User\", Map.class);\n\nUser user = pojoDeserializer.deserialize(bytes);\nMap<String, Object> map = mapDeserializer.deserialize(bytes);\n```\n\n# Performance\n```\n1.protobuf\n  in our real scenes\n  business model never bind to transport, and can switch between different transports dynamically\n  that means if we choose standard protobuf, must build protobuf models from business models each time\n  so should be much slower than the test results\n2.protoStuff\n  some scenes, there is no field but have getter or setter, so we can not use unsafe to access field\n  so we disable protoStuff unsafe feature\n\n  for repeated fields, protoStuff have better performance, but not compatible to protobuf\n\n3.jackson\n  not support map/any/recursive, ignore related fields\n4.serialize result size\n  ScbStrong/ScbWeak/Protobuf have the same and smaller size, because skip all default/null value\n\nEmpty:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 519        515        240        288        1242\nserialize len       : 36         0          0          0          56\ndeserialize time(ms): 161        69         10         516        486\ndeserialize->serialize len: 36         0          0          0          56\nserialize+deserialize(ms) : 680        584        250        804        1728\n\nScalars:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 557        529        328        262        1357\nserialize len       : 56         24         24         24         76\ndeserialize time(ms): 181        141        115        527        504\ndeserialize->serialize len: 56         24         24         24         76\nserialize+deserialize(ms) : 738        670        443        789        1861\n\nPojo:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 571        574        276        309        1304\nserialize len       : 46         10         10         10         66\ndeserialize time(ms): 230        69         112        668        537\ndeserialize->serialize len: 46         10         10         10         66\nserialize+deserialize(ms) : 801        643        388        977        1841\n\nSimpleList:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 590        609        296        637        1320\nserialize len       : 68         32         32         32         88\ndeserialize time(ms): 233        105        122        2226       541\ndeserialize->serialize len: 68         32         32         32         88\nserialize+deserialize(ms) : 823        714        418        2863       1861\n\nPojoList:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 609        632        319        2777       1407\nserialize len       : 56         20         20         20         76\ndeserialize time(ms): 244        134        173        2287       679\ndeserialize->serialize len: 56         20         20         20         76\nserialize+deserialize(ms) : 853        766        492        5064       2086\n\nMap:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 746        772        491        1079       1298\nserialize len       : 92         54         54         54         56\ndeserialize time(ms): 522        427        468        1031       422\ndeserialize->serialize len: 92         54         54         54         56\nserialize+deserialize(ms) : 1268       1199       959        2110       1720\n\nMixed:\n                Protostuff ScbStrong  ScbWeak    Protobuf   Jackson\nserialize time(ms)  : 1686       1999       2034       2112       2537\nserialize len       : 479        505        505        505        489\ndeserialize time(ms): 1969       2154       2923       2984       3316\ndeserialize->serialize len: 479        505        505        505        489\nserialize+deserialize(ms) : 3655       4153       4957       5096       5853\n```\n"
  },
  {
    "path": "foundations/foundation-protobuf/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>foundations</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>foundation-protobuf</artifactId>\n  <name>Java Chassis::Foundations::Protobuf</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.protostuff</groupId>\n      <artifactId>protostuff-parser</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.protostuff</groupId>\n      <artifactId>protostuff-runtime</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.protostuff</groupId>\n      <artifactId>protostuff-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.findbugs</groupId>\n      <artifactId>jsr305</artifactId>\n    </dependency>\n\n    <!-- will not update anymore, only for testing -->\n    <dependency>\n      <groupId>com.google.protobuf</groupId>\n      <artifactId>protobuf-java</artifactId>\n      <scope>test</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>com.fasterxml.jackson.dataformat</groupId>\n      <artifactId>jackson-dataformat-protobuf</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n\n  </dependencies>\n\n  <build>\n    <plugins>\n      <plugin>\n        <groupId>org.xolstice.maven.plugins</groupId>\n        <artifactId>protobuf-maven-plugin</artifactId>\n        <version>${protobuf-maven-plugin.version}</version>\n        <configuration>\n          <protocArtifact>com.google.protobuf:protoc:${protoc3-maven-plugin.version}:exe:${os.detected.classifier}</protocArtifact>\n          <checkStaleness>true</checkStaleness>\n          <pluginId>grpc-java</pluginId>\n          <pluginArtifact>io.grpc:protoc-gen-grpc-java:${protoc-gen-grpc-java-plugin.version}:exe:${os.detected.classifier}</pluginArtifact>\n          <protoTestSourceRoot>src/test/resources</protoTestSourceRoot>\n          <excludes>\n            <exclude>**/jacksonRoot.proto</exclude>\n            <exclude>**/method.proto</exclude>\n            <exclude>**/model.proto</exclude>\n          </excludes>\n        </configuration>\n        <executions>\n          <execution>\n            <phase>generate-test-sources</phase>\n            <goals>\n              <goal>test-compile</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n  </build>\n\n</project>\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/ByteArrayInputEx.java",
    "content": "//========================================================================\n//Copyright 2007-2010 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\nimport static io.protostuff.WireFormat.TAG_TYPE_BITS;\nimport static io.protostuff.WireFormat.WIRETYPE_END_GROUP;\nimport static io.protostuff.WireFormat.WIRETYPE_FIXED32;\nimport static io.protostuff.WireFormat.WIRETYPE_FIXED64;\nimport static io.protostuff.WireFormat.WIRETYPE_LENGTH_DELIMITED;\nimport static io.protostuff.WireFormat.WIRETYPE_START_GROUP;\nimport static io.protostuff.WireFormat.WIRETYPE_VARINT;\nimport static io.protostuff.WireFormat.getTagFieldNumber;\nimport static io.protostuff.WireFormat.getTagWireType;\nimport static io.protostuff.WireFormat.makeTag;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\nimport com.fasterxml.jackson.databind.util.ArrayBuilders;\n\nimport io.protostuff.StringSerializer.STRING;\n\n/**\n * Forked and modified from protostuff\n *\n * Reads and decodes protocol buffer message fields from an internal byte array buffer. This object is re-usable via\n * doing a reset on the byte array position and length. This is used internally by {@link IOUtil} where it catches\n * {@link ArrayIndexOutOfBoundsException} when a message is truncated.\n *\n * @author David Yu\n * @created Jun 22, 2010\n */\npublic final class ByteArrayInputEx implements InputEx {\n  private final byte[] buffer;\n\n  private int offset, limit, lastTag = 0;\n\n  private int packedLimit = 0;\n\n  private ArrayBuilders arrayBuilders;\n\n  public ByteArrayInputEx(byte[] buffer) {\n    this(buffer, 0, buffer.length);\n  }\n\n  public ByteArrayInputEx(byte[] buffer, int offset, int len) {\n    this.buffer = buffer;\n    this.offset = offset;\n    this.limit = offset + len;\n  }\n\n  /**\n   * Return true if currently reading packed field\n   */\n  public boolean isCurrentFieldPacked() {\n    return packedLimit != 0 && packedLimit != offset;\n  }\n\n  /**\n   * Attempt to read a field tag, returning zero if we have reached EOF. Protocol message parsers use this to read\n   * tags, since a protocol message may legally end wherever a tag occurs, and zero is not a valid tag number.\n   */\n  public int readTag() throws IOException {\n    if (offset == limit) {\n      lastTag = 0;\n      return 0;\n    }\n\n    final int tag = readRawVarint32();\n    if (tag >>> TAG_TYPE_BITS == 0) {\n      // If we actually read zero, that's not a valid tag.\n      throw ProtobufException.invalidTag();\n    }\n    lastTag = tag;\n    return tag;\n  }\n\n  /**\n   * Verifies that the last call to readTag() returned the given tag value. This is used to verify that a nested group\n   * ended with the correct end tag.\n   *\n   * @throws ProtobufException\n   *             {@code value} does not match the last tag.\n   */\n  public void checkLastTagWas(final int value) throws ProtobufException {\n    if (lastTag != value) {\n      throw ProtobufException.invalidEndTag();\n    }\n  }\n\n  /**\n   * Reads and discards a single field, given its tag value.\n   *\n   * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped. Otherwise, returns\n   *         {@code true}.\n   */\n  public boolean skipField(final int tag) throws IOException {\n    switch (getTagWireType(tag)) {\n      case WIRETYPE_VARINT:\n        readInt32();\n        return true;\n      case WIRETYPE_FIXED64:\n        readRawLittleEndian64();\n        return true;\n      case WIRETYPE_LENGTH_DELIMITED:\n        final int size = readRawVarint32();\n        if (size < 0) {\n          throw ProtobufException.negativeSize();\n        }\n        offset += size;\n        return true;\n      case WIRETYPE_START_GROUP:\n        skipMessage();\n        checkLastTagWas(makeTag(getTagFieldNumber(tag), WIRETYPE_END_GROUP));\n        return true;\n      case WIRETYPE_END_GROUP:\n        return false;\n      case WIRETYPE_FIXED32:\n        readRawLittleEndian32();\n        return true;\n      default:\n        throw ProtobufException.invalidWireType();\n    }\n  }\n\n  /**\n   * Reads and discards an entire message. This will read either until EOF or until an endgroup tag, whichever comes\n   * first.\n   */\n  public void skipMessage() throws IOException {\n    while (true) {\n      final int tag = readTag();\n      if (tag == 0 || !skipField(tag)) {\n        return;\n      }\n    }\n  }\n\n  @Override\n  public void handleUnknownField(int fieldNumber) throws IOException {\n    skipField(lastTag);\n  }\n\n  @Override\n  public int readFieldNumber() throws IOException {\n    if (offset == limit) {\n      lastTag = 0;\n      return 0;\n    }\n\n    // are we reading packed field?\n    if (isCurrentFieldPacked()) {\n      if (packedLimit < offset) {\n        throw ProtobufException.misreportedSize();\n      }\n\n      // Return field number while reading packed field\n      return lastTag >>> TAG_TYPE_BITS;\n    }\n\n    packedLimit = 0;\n    final int tag = readRawVarint32();\n    final int fieldNumber = tag >>> TAG_TYPE_BITS;\n    if (fieldNumber == 0) {\n      // If we actually read zero, that's not a valid tag.\n      throw ProtobufException.invalidTag();\n    }\n\n    lastTag = tag;\n    return fieldNumber;\n  }\n\n  /**\n   * Check if this field have been packed into a length-delimited field. If so, update internal state to reflect that\n   * packed fields are being read.\n   *\n   */\n  private void checkIfPackedField() throws IOException {\n    // Do we have the start of a packed field?\n    if (packedLimit == 0 && getTagWireType(lastTag) == WIRETYPE_LENGTH_DELIMITED) {\n      final int length = readRawVarint32();\n      if (length < 0) {\n        throw ProtobufException.negativeSize();\n      }\n\n      if (offset + length > limit) {\n        throw ProtobufException.misreportedSize();\n      }\n\n      this.packedLimit = this.offset + length;\n    }\n  }\n\n  /**\n   * Read a {@code double} field value from the internal buffer.\n   */\n  @Override\n  public double readDouble() {\n    return Double.longBitsToDouble(readRawLittleEndian64());\n  }\n\n  /**\n   * Read a {@code float} field value from the internal buffer.\n   */\n  @Override\n  public float readFloat() {\n    return Float.intBitsToFloat(readRawLittleEndian32());\n  }\n\n  /**\n   * Read a {@code uint64} field value from the internal buffer.\n   */\n  @Override\n  public long readUInt64() throws IOException {\n    return readRawVarint64();\n  }\n\n  /**\n   * Read an {@code int64} field value from the internal buffer.\n   */\n  @Override\n  public long readInt64() throws IOException {\n    return readRawVarint64();\n  }\n\n  /**\n   * Read an {@code int32} field value from the internal buffer.\n   */\n  @Override\n  public int readInt32() throws IOException {\n    return readRawVarint32();\n  }\n\n  /**\n   * Read a {@code fixed64} field value from the internal buffer.\n   */\n  @Override\n  public long readFixed64() {\n    return readRawLittleEndian64();\n  }\n\n  /**\n   * Read a {@code fixed32} field value from the internal buffer.\n   */\n  @Override\n  public int readFixed32() {\n    return readRawLittleEndian32();\n  }\n\n  /**\n   * Read a {@code bool} field value from the internal buffer.\n   */\n  @Override\n  public boolean readBool() {\n    return buffer[offset++] != 0;\n  }\n\n  /**\n   * Read a {@code uint32} field value from the internal buffer.\n   */\n  @Override\n  public int readUInt32() throws IOException {\n    return readRawVarint32();\n  }\n\n  /**\n   * Read an enum field value from the internal buffer. Caller is responsible for converting the numeric value to an\n   * actual enum.\n   */\n  @Override\n  public int readEnum() throws IOException {\n    return readRawVarint32();\n  }\n\n  /**\n   * Read an {@code sfixed32} field value from the internal buffer.\n   */\n  @Override\n  public int readSFixed32() {\n    return readRawLittleEndian32();\n  }\n\n  /**\n   * Read an {@code sfixed64} field value from the internal buffer.\n   */\n  @Override\n  public long readSFixed64() {\n    return readRawLittleEndian64();\n  }\n\n  /**\n   * Read an {@code sint32} field value from the internal buffer.\n   */\n  @Override\n  public int readSInt32() throws IOException {\n    final int n = readRawVarint32();\n    return (n >>> 1) ^ -(n & 1);\n  }\n\n  /**\n   * Read an {@code sint64} field value from the internal buffer.\n   */\n  @Override\n  public long readSInt64() throws IOException {\n    final long n = readRawVarint64();\n    return (n >>> 1) ^ -(n & 1);\n  }\n\n  @Override\n  public String readString() throws IOException {\n    final int length = readRawVarint32();\n    if (length < 0) {\n      throw ProtobufException.negativeSize();\n    }\n\n    if (offset + length > limit) {\n      throw ProtobufException.misreportedSize();\n    }\n\n    final int offset = this.offset;\n\n    this.offset += length;\n\n    return STRING.deser(buffer, offset, length);\n  }\n\n  @Override\n  public ByteString readBytes() throws IOException {\n    return ByteString.wrap(readByteArray());\n  }\n\n  @Override\n  public byte[] readByteArray() throws IOException {\n    final int length = readRawVarint32();\n    if (length < 0) {\n      throw ProtobufException.negativeSize();\n    }\n\n    if (offset + length > limit) {\n      throw ProtobufException.misreportedSize();\n    }\n\n    final byte[] copy = new byte[length];\n    System.arraycopy(buffer, offset, copy, 0, length);\n\n    offset += length;\n\n    return copy;\n  }\n\n  @Override\n  public <T> T mergeObject(T value, final SchemaReader<T> schema) throws IOException {\n    final int length = readRawVarint32();\n    if (length < 0) {\n      throw ProtobufException.negativeSize();\n    }\n\n    // save old limit\n    final int oldLimit = this.limit;\n\n    this.limit = offset + length;\n\n    if (value == null) {\n      value = schema.newMessage();\n    }\n    schema.mergeFrom(this, value);\n    checkLastTagWas(0);\n\n    // restore old limit\n    this.limit = oldLimit;\n\n    return value;\n  }\n\n  /**\n   * Reads a var int 32 from the internal byte buffer.\n   */\n  public int readRawVarint32() throws IOException {\n    byte tmp = buffer[offset++];\n    if (tmp >= 0) {\n      return tmp;\n    }\n    int result = tmp & 0x7f;\n    if ((tmp = buffer[offset++]) >= 0) {\n      result |= tmp << 7;\n    } else {\n      result |= (tmp & 0x7f) << 7;\n      if ((tmp = buffer[offset++]) >= 0) {\n        result |= tmp << 14;\n      } else {\n        result |= (tmp & 0x7f) << 14;\n        if ((tmp = buffer[offset++]) >= 0) {\n          result |= tmp << 21;\n        } else {\n          result |= (tmp & 0x7f) << 21;\n          result |= (tmp = buffer[offset++]) << 28;\n          if (tmp < 0) {\n            // Discard upper 32 bits.\n            for (int i = 0; i < 5; i++) {\n              if (buffer[offset++] >= 0) {\n                return result;\n              }\n            }\n            throw ProtobufException.malformedVarint();\n          }\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Reads a var int 64 from the internal byte buffer.\n   */\n  public long readRawVarint64() throws IOException {\n    final byte[] buffer = this.buffer;\n    int offset = this.offset;\n\n    int shift = 0;\n    long result = 0;\n    while (shift < 64) {\n      final byte b = buffer[offset++];\n      result |= (long) (b & 0x7F) << shift;\n      if ((b & 0x80) == 0) {\n        this.offset = offset;\n        return result;\n      }\n      shift += 7;\n    }\n    throw ProtobufException.malformedVarint();\n  }\n\n  /**\n   * Read a 32-bit little-endian integer from the internal buffer.\n   */\n  public int readRawLittleEndian32() {\n    final byte[] buffer = this.buffer;\n    int offset = this.offset;\n\n    final byte b1 = buffer[offset++];\n    final byte b2 = buffer[offset++];\n    final byte b3 = buffer[offset++];\n    final byte b4 = buffer[offset++];\n\n    this.offset = offset;\n\n    return (((int) b1 & 0xff)) |\n        (((int) b2 & 0xff) << 8) |\n        (((int) b3 & 0xff) << 16) |\n        (((int) b4 & 0xff) << 24);\n  }\n\n  /**\n   * Read a 64-bit little-endian integer from the internal byte buffer.\n   */\n  public long readRawLittleEndian64() {\n    final byte[] buffer = this.buffer;\n    int offset = this.offset;\n\n    final byte b1 = buffer[offset++];\n    final byte b2 = buffer[offset++];\n    final byte b3 = buffer[offset++];\n    final byte b4 = buffer[offset++];\n    final byte b5 = buffer[offset++];\n    final byte b6 = buffer[offset++];\n    final byte b7 = buffer[offset++];\n    final byte b8 = buffer[offset++];\n\n    this.offset = offset;\n\n    return (((long) b1 & 0xff)) |\n        (((long) b2 & 0xff) << 8) |\n        (((long) b3 & 0xff) << 16) |\n        (((long) b4 & 0xff) << 24) |\n        (((long) b5 & 0xff) << 32) |\n        (((long) b6 & 0xff) << 40) |\n        (((long) b7 & 0xff) << 48) |\n        (((long) b8 & 0xff) << 56);\n  }\n\n  /**\n   * Reads a byte array/ByteBuffer value.\n   */\n  @Override\n  public ByteBuffer readByteBuffer() throws IOException {\n    return ByteBuffer.wrap(readByteArray());\n  }\n\n  @Override\n  public ArrayBuilders getArrayBuilders() {\n    if (arrayBuilders == null) {\n      arrayBuilders = new ArrayBuilders();\n    }\n    return arrayBuilders;\n  }\n\n  @Override\n  public int readPackedInt32() throws IOException {\n    checkIfPackedField();\n    return readRawVarint32();\n  }\n\n  @Override\n  public int readPackedUInt32() throws IOException {\n    checkIfPackedField();\n    return readRawVarint32();\n  }\n\n  @Override\n  public int readPackedSInt32() throws IOException {\n    checkIfPackedField();\n    final int n = readRawVarint32();\n    return (n >>> 1) ^ -(n & 1);\n  }\n\n  @Override\n  public int readPackedFixed32() throws IOException {\n    checkIfPackedField();\n    return readRawLittleEndian32();\n  }\n\n  @Override\n  public int readPackedSFixed32() throws IOException {\n    checkIfPackedField();\n    return readRawLittleEndian32();\n  }\n\n  @Override\n  public long readPackedInt64() throws IOException {\n    checkIfPackedField();\n    return readRawVarint64();\n  }\n\n  @Override\n  public long readPackedUInt64() throws IOException {\n    checkIfPackedField();\n    return readRawVarint64();\n  }\n\n  @Override\n  public long readPackedSInt64() throws IOException {\n    checkIfPackedField();\n    final long n = readRawVarint64();\n    return (n >>> 1) ^ -(n & 1);\n  }\n\n  @Override\n  public long readPackedFixed64() throws IOException {\n    checkIfPackedField();\n    return readRawLittleEndian64();\n  }\n\n  @Override\n  public long readPackedSFixed64() throws IOException {\n    checkIfPackedField();\n    return readRawLittleEndian64();\n  }\n\n  @Override\n  public float readPackedFloat() throws IOException {\n    checkIfPackedField();\n    return Float.intBitsToFloat(readRawLittleEndian32());\n  }\n\n  @Override\n  public double readPackedDouble() throws IOException {\n    checkIfPackedField();\n    return Double.longBitsToDouble(readRawLittleEndian64());\n  }\n\n  @Override\n  public boolean readPackedBool() throws IOException {\n    checkIfPackedField();\n    return buffer[offset++] != 0;\n  }\n\n  @Override\n  public int readPackedEnum() throws IOException {\n    checkIfPackedField();\n    return readRawVarint32();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/InputEx.java",
    "content": "//========================================================================\n//Copyright 2007-2009 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\nimport com.fasterxml.jackson.databind.util.ArrayBuilders;\n\n/**\n * Forked and modified from protostuff<br>\n *\n * An Input lets an application read primitive data types and objects from a source of data.\n *\n * @author David Yu\n * @created Nov 9, 2009\n */\npublic interface InputEx {\n\n  /**\n   * The underlying implementation should handle the unknown field.\n   */\n  <T> void handleUnknownField(int fieldNumber) throws IOException;\n\n  /**\n   * Reads field number.\n   */\n  int readFieldNumber() throws IOException;\n\n  /**\n   * Reads a variable int field value.\n   */\n  int readInt32() throws IOException;\n\n  /**\n   * Reads an unsigned int field value.\n   */\n  int readUInt32() throws IOException;\n\n  /**\n   * Reads a signed int field value.\n   */\n  int readSInt32() throws IOException;\n\n  /**\n   * Reads a fixed int(4 bytes) field value.\n   */\n  int readFixed32() throws IOException;\n\n  /**\n   * Reads a signed+fixed int(4 bytes) field value.\n   */\n  int readSFixed32() throws IOException;\n\n  /**\n   * Reads a variable long field value.\n   */\n  long readInt64() throws IOException;\n\n  /**\n   * Reads an unsigned long field value.\n   */\n  long readUInt64() throws IOException;\n\n  /**\n   * Reads a signed long field value.\n   */\n  long readSInt64() throws IOException;\n\n  /**\n   * Reads a fixed long(8 bytes) field value.\n   */\n  long readFixed64() throws IOException;\n\n  /**\n   * Reads a signed+fixed long(8 bytes) field value.\n   */\n  long readSFixed64() throws IOException;\n\n  /**\n   * Reads a float field value.\n   */\n  float readFloat() throws IOException;\n\n  /**\n   * Reads a double field value.\n   */\n  double readDouble() throws IOException;\n\n  /**\n   * Reads a boolean field value.\n   */\n  boolean readBool() throws IOException;\n\n  /**\n   * Reads an enum(its number) field value.\n   */\n  int readEnum() throws IOException;\n\n  /**\n   * Reads a {@link String} field value.\n   */\n  String readString() throws IOException;\n\n  /**\n   * Reads a {@link ByteString} field value.\n   */\n  ByteString readBytes() throws IOException;\n\n  /**\n   * Reads a byte array field value.\n   */\n  byte[] readByteArray() throws IOException;\n\n  ByteBuffer readByteBuffer() throws IOException;\n\n  /**\n   * Merges an object(with schema) field value. The provided {@link Schema schema} handles the deserialization for the\n   * object.\n   */\n  <T> T mergeObject(T value, SchemaReader<T> schema) throws IOException;\n\n  ArrayBuilders getArrayBuilders();\n\n  int readPackedInt32() throws IOException;\n\n  int readPackedUInt32() throws IOException;\n\n  int readPackedSInt32() throws IOException;\n\n  int readPackedFixed32() throws IOException;\n\n  int readPackedSFixed32() throws IOException;\n\n  long readPackedInt64() throws IOException;\n\n  long readPackedUInt64() throws IOException;\n\n  long readPackedSInt64() throws IOException;\n\n  long readPackedFixed64() throws IOException;\n\n  long readPackedSFixed64() throws IOException;\n\n  float readPackedFloat() throws IOException;\n\n  double readPackedDouble() throws IOException;\n\n  boolean readPackedBool() throws IOException;\n\n  int readPackedEnum() throws IOException;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/OutputEx.java",
    "content": "//========================================================================\n//Copyright 2007-2009 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\nimport static io.protostuff.ProtobufOutputEx.encodeZigZag64;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\n\n/**\n * <pre>\n * Forked and modified from protostuff\n * difference for scalar types:\n *                   OutputEx         OutputEx\n * writeXXX          all scenes     repeated not packed, write with tag, not ignore default value\n * writePackedXXX    ---            repeated packed, write without tag, not ignore default value\n * writeScalarXXX    ---            not repeated field, not write default value\n * </pre>\n *\n * An OutputEx lets an application write primitive data types and objects to a sink of data.\n *\n * @author David Yu\n * @created Nov 9, 2009\n */\npublic interface OutputEx {\n\n  /**\n   * Writes a variable int field.\n   */\n  void writeInt32(int tag, int tagSize, int value) throws IOException;\n\n  /**\n   * Writes an unsigned int field.\n   */\n  void writeUInt32(int tag, int tagSize, int value) throws IOException;\n\n  /**\n   * Writes a signed int field.\n   */\n  void writeSInt32(int tag, int tagSize, int value) throws IOException;\n\n  /**\n   * Writes a fixed int(4 bytes) field.\n   */\n  void writeFixed32(int tag, int tagSize, int value) throws IOException;\n\n  /**\n   * Writes a signed+fixed int(4 bytes) field.\n   */\n  void writeSFixed32(int tag, int tagSize, int value) throws IOException;\n\n  /**\n   * Writes a variable long field.\n   */\n  void writeInt64(int tag, int tagSize, long value) throws IOException;\n\n  /**\n   * Writes an unsigned long field.\n   */\n  void writeUInt64(int tag, int tagSize, long value) throws IOException;\n\n  /**\n   * Writes a signed long field.\n   */\n  void writeSInt64(int tag, int tagSize, long value) throws IOException;\n\n  /**\n   * Writes a fixed long(8 bytes) field.\n   */\n  void writeFixed64(int tag, int tagSize, long value) throws IOException;\n\n  /**\n   * Writes a signed+fixed long(8 bytes) field.\n   */\n  void writeSFixed64(int tag, int tagSize, long value) throws IOException;\n\n  /**\n   * Writes a float field.\n   */\n  void writeFloat(int tag, int tagSize, float value) throws IOException;\n\n  /**\n   * Writes a double field.\n   */\n  void writeDouble(int tag, int tagSize, double value) throws IOException;\n\n  /**\n   * Writes a boolean field.\n   */\n  void writeBool(int tag, int tagSize, boolean value) throws IOException;\n\n  /**\n   * Writes a enum(its number) field.\n   */\n  void writeEnum(int tag, int tagSize, int value) throws IOException;\n\n  /**\n   * Writes a String field.\n   */\n  void writeString(int tag, int tagSize, String value) throws IOException;\n\n  /**\n   * Writes a ByteString(wraps byte array) field.\n   */\n  void writeBytes(int tag, int tagSize, ByteString value) throws IOException;\n\n  /**\n   * Writes a byte array field.\n   */\n  void writeByteArray(int tag, int tagSize, byte[] value) throws IOException;\n\n  /**\n   * Writes a binary or a pre-encoded utf8 string.\n   */\n  void writeByteRange(boolean utf8String, int tag, int tagSize, byte[] value, int offset, int length)\n      throws IOException;\n\n  /**\n   * Writes an object(using its schema) field.\n   */\n  <T> void writeObject(int tag, int tagSize, T value, SchemaWriter<T> schemaWriter) throws IOException;\n\n  void writeBytes(int tag, int tagSize, ByteBuffer value) throws IOException;\n\n  byte[] toByteArray();\n\n  void writePackedInt32(int value) throws IOException;\n\n  void writeScalarInt32(int tag, int tagSize, int value) throws IOException;\n\n  default void writePackedInt64(long value) throws IOException {\n    writePackedUInt64(value);\n  }\n\n  void writeScalarInt64(int tag, int tagSize, long value) throws IOException;\n\n  void writePackedUInt32(int value) throws IOException;\n\n  void writeScalarUInt32(int tag, int tagSize, int value) throws IOException;\n\n  void writePackedUInt64(long value) throws IOException;\n\n  void writeScalarUInt64(int tag, int tagSize, long value) throws IOException;\n\n  void writePackedSInt32(int value) throws IOException;\n\n  void writeScalarSInt32(int tag, int tagSize, int value) throws IOException;\n\n  default void writePackedSInt64(long value) throws IOException {\n    writePackedUInt64(encodeZigZag64(value));\n  }\n\n  void writeScalarSInt64(int tag, int tagSize, long value) throws IOException;\n\n  void writePackedFixed32(int value) throws IOException;\n\n  void writeScalarFixed32(int tag, int tagSize, int value) throws IOException;\n\n  void writePackedFixed64(long value) throws IOException;\n\n  void writeScalarFixed64(int tag, int tagSize, long value) throws IOException;\n\n  default void writePackedSFixed32(int value) throws IOException {\n    writePackedFixed32(value);\n  }\n\n  void writeScalarSFixed32(int tag, int tagSize, int value) throws IOException;\n\n  default void writePackedSFixed64(long value) throws IOException {\n    writePackedFixed64(value);\n  }\n\n  void writeScalarSFixed64(int tag, int tagSize, long value) throws IOException;\n\n  default void writePackedFloat(float value) throws IOException {\n    writePackedFixed32(Float.floatToRawIntBits(value));\n  }\n\n  void writeScalarFloat(int tag, int tagSize, float value) throws IOException;\n\n  default void writePackedDouble(double value) throws IOException {\n    writePackedFixed64(Double.doubleToRawLongBits(value));\n  }\n\n  void writeScalarDouble(int tag, int tagSize, double value) throws IOException;\n\n  void writePackedBool(boolean value) throws IOException;\n\n  void writeScalarBool(int tag, int tagSize, boolean value) throws IOException;\n\n  default void writePackedEnum(int value) throws IOException {\n    writePackedInt32(value);\n  }\n\n  void writeScalarEnum(int tag, int tagSize, int value) throws IOException;\n\n  void writeScalarString(int tag, int tagSize, String value) throws IOException;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java",
    "content": "//========================================================================\n//Copyright 2007-2010 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\nimport static io.protostuff.StringSerializer.writeUTF8VarDelimited;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.nio.ByteBuffer;\n\n/**\n * Forked and modified from protostuff<br>\n *\n * Protobuf serialization where the messages must be fully buffered on memory before it can be written to the socket (\n * {@link OutputStream}).\n *\n * @author David Yu\n * @created May 18, 2010\n */\npublic final class ProtobufOutputEx extends WriteSession implements OutputEx {\n  public static final int LITTLE_ENDIAN_32_SIZE = 4, LITTLE_ENDIAN_64_SIZE = 8;\n\n  public ProtobufOutputEx() {\n    super(LinkedBuffer.allocate());\n  }\n\n  public ProtobufOutputEx(LinkedBuffer buffer) {\n    super(buffer);\n  }\n\n  public ProtobufOutputEx(LinkedBuffer buffer, int nextBufferSize) {\n    super(buffer, nextBufferSize);\n  }\n\n  /**\n   * Resets this output for re-use.\n   */\n  @Override\n  public ProtobufOutputEx clear() {\n    super.clear();\n    return this;\n  }\n\n  @Override\n  public void writeInt32(int tag, int tagSize, int value) {\n    if (value < 0) {\n      tail = writeTagAndRawVarInt64(tag, tagSize, value, this, tail);\n      return;\n    }\n\n    tail = writeTagAndRawVarInt32(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeUInt32(int tag, int tagSize, int value) {\n    tail = writeTagAndRawVarInt32(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeSInt32(int tag, int tagSize, int value) {\n    tail = writeTagAndRawVarInt32(tag, tagSize, encodeZigZag32(value), this, tail);\n  }\n\n  @Override\n  public void writeFixed32(int tag, int tagSize, int value) {\n    tail = writeTagAndRawLittleEndian32(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeSFixed32(int tag, int tagSize, int value) {\n    tail = writeTagAndRawLittleEndian32(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeInt64(int tag, int tagSize, long value) {\n    tail = writeTagAndRawVarInt64(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeUInt64(int tag, int tagSize, long value) {\n    tail = writeTagAndRawVarInt64(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeSInt64(int tag, int tagSize, long value) {\n    tail = writeTagAndRawVarInt64(tag, tagSize, encodeZigZag64(value), this, tail);\n  }\n\n  @Override\n  public void writeFixed64(int tag, int tagSize, long value) {\n    tail = writeTagAndRawLittleEndian64(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeSFixed64(int tag, int tagSize, long value) {\n    tail = writeTagAndRawLittleEndian64(tag, tagSize, value, this, tail);\n  }\n\n  @Override\n  public void writeFloat(int tag, int tagSize, float value) {\n    tail = writeTagAndRawLittleEndian32(tag, tagSize, Float.floatToRawIntBits(value), this, tail);\n  }\n\n  @Override\n  public void writeDouble(int tag, int tagSize, double value) {\n    tail = writeTagAndRawLittleEndian64(tag, tagSize, Double.doubleToRawLongBits(value), this, tail);\n  }\n\n  @Override\n  public void writeBool(int tag, int tagSize, boolean value) {\n    tail = writeTagAndRawVarInt32(tag, tagSize, value ? 1 : 0, this, tail);\n  }\n\n  @Override\n  public void writeEnum(int tag, int tagSize, int number) {\n    writeInt32(tag, tagSize, number);\n  }\n\n  @Override\n  public void writeString(int tag, int tagSize, String value) {\n    tail = writeUTF8VarDelimited(\n        value,\n        this,\n        writeRawVarInt32(tag, this, tail));\n  }\n\n  @Override\n  public void writeBytes(int tag, int tagSize, ByteString value) {\n    writeByteArray(tag, tagSize, value.getBytes());\n  }\n\n  @Override\n  public void writeByteArray(int tag, int tagSize, byte[] bytes) {\n    tail = writeTagAndByteArray(\n        tag, tagSize,\n        bytes, 0, bytes.length,\n        this,\n        tail);\n  }\n\n  @Override\n  public void writeByteRange(boolean utf8String, int tag, int tagSize, byte[] value, int offset, int length) {\n    tail = writeTagAndByteArray(\n        tag, tagSize,\n        value, offset, length,\n        this,\n        tail);\n  }\n\n  @Override\n  public <T> void writeObject(final int tag, int tagSize, final T value, final SchemaWriter<T> schemaWriter)\n      throws IOException {\n    final LinkedBuffer lastBuffer;\n\n    // write the tag\n    if (tagSize == 1 && tail.offset != tail.buffer.length) {\n      lastBuffer = tail;\n      size++;\n      lastBuffer.buffer[lastBuffer.offset++] = (byte) tag;\n    } else {\n      tail = lastBuffer = writeRawVarInt32(tag, this, tail);\n    }\n\n    final int lastOffset = tail.offset, lastSize = size;\n\n    if (lastOffset == lastBuffer.buffer.length) {\n      // not enough size for the 1-byte delimiter\n      final LinkedBuffer nextBuffer = new LinkedBuffer(nextBufferSize);\n      // new buffer for the content\n      tail = nextBuffer;\n\n      schemaWriter.writeTo(this, value);\n\n      final int msgSize = size - lastSize;\n\n      final byte[] delimited = new byte[computeRawVarint32Size(msgSize)];\n      writeRawVarInt32(msgSize, delimited, 0);\n\n      size += delimited.length;\n\n      // wrap the byte array (delimited) and insert between the two buffers\n      new LinkedBuffer(delimited, 0, delimited.length, lastBuffer).next = nextBuffer;\n      return;\n    }\n\n    // we have enough space for the 1-byte delim\n    lastBuffer.offset++;\n    size++;\n\n    schemaWriter.writeTo(this, value);\n\n    final int msgSize = size - lastSize - 1;\n\n    // optimize for small messages\n    if (msgSize < 128) {\n      // fits\n      lastBuffer.buffer[lastOffset] = (byte) msgSize;\n      return;\n    }\n\n    // split into two buffers\n\n    // the second buffer (contains the message contents)\n    final LinkedBuffer view = new LinkedBuffer(lastBuffer.buffer,\n        lastOffset + 1, lastBuffer.offset);\n\n    if (lastBuffer == tail) {\n      tail = view;\n    } else {\n      view.next = lastBuffer.next;\n    }\n\n    // the first buffer (contains the tag)\n    lastBuffer.offset = lastOffset;\n\n    final byte[] delimited = new byte[computeRawVarint32Size(msgSize)];\n    writeRawVarInt32(msgSize, delimited, 0);\n\n    // add the difference\n    size += (delimited.length - 1);\n\n    // wrap the byte array (delimited) and insert between the two buffers\n    new LinkedBuffer(delimited, 0, delimited.length, lastBuffer).next = view;\n  }\n\n  /*\n   * Write the nested message encoded as group.\n   *\n   * <T> void writeObjectEncodedAsGroup(final int fieldNumber, final T value, final SchemaEx<T> schema, final boolean\n   * repeated) throws IOException { tail = writeRawVarInt32( makeTag(fieldNumber, WIRETYPE_START_GROUP), this, tail);\n   *\n   * schema.writeTo(this, value);\n   *\n   * tail = writeRawVarInt32( makeTag(fieldNumber, WIRETYPE_END_GROUP), this, tail); }\n   */\n\n  /* ----------------------------------------------------------------- */\n\n  /**\n   * Returns the buffer encoded with the variable int 32.\n   */\n  public static LinkedBuffer writeRawVarInt32(int value, final WriteSession session,\n      LinkedBuffer lb) {\n    final int size = computeRawVarint32Size(value);\n\n    if (lb.offset + size > lb.buffer.length) {\n      lb = new LinkedBuffer(session.nextBufferSize, lb);\n    }\n\n    final byte[] buffer = lb.buffer;\n    int offset = lb.offset;\n    lb.offset += size;\n    session.size += size;\n\n    if (size == 1) {\n      buffer[offset] = (byte) value;\n    } else {\n      for (int i = 0, last = size - 1; i < last; i++, value >>>= 7) {\n        buffer[offset++] = (byte) ((value & 0x7F) | 0x80);\n      }\n\n      buffer[offset] = (byte) value;\n    }\n\n    return lb;\n  }\n\n  /**\n   * Returns the buffer encoded with the tag and byte array\n   */\n  public static LinkedBuffer writeTagAndByteArray(int tag, int tagSize, final byte[] value,\n      int offset, int valueLen,\n      final WriteSession session, LinkedBuffer lb) {\n    if (valueLen == 0) {\n      // write only the tag and delimiter\n      return writeTagAndRawVarInt32(tag, tagSize, valueLen, session, lb);\n    }\n\n    lb = writeTagAndRawVarInt32(tag, tagSize, valueLen, session, lb);\n\n    session.size += valueLen;\n\n    final int available = lb.buffer.length - lb.offset;\n    if (valueLen > available) {\n      if (available + session.nextBufferSize < valueLen) {\n        // too large ... so we wrap and insert (zero-copy)\n        if (available == 0) {\n          // buffer was actually full ... return a fresh buffer\n          return new LinkedBuffer(session.nextBufferSize,\n              new LinkedBuffer(value, offset, offset + valueLen, lb));\n        }\n\n        // continue with the existing byte array of the previous buffer\n        return new LinkedBuffer(lb,\n            new LinkedBuffer(value, offset, offset + valueLen, lb));\n      }\n\n      // copy what can fit\n      System.arraycopy(value, offset, lb.buffer, lb.offset, available);\n\n      lb.offset += available;\n\n      // grow\n      lb = new LinkedBuffer(session.nextBufferSize, lb);\n\n      final int leftover = valueLen - available;\n\n      // copy what's left\n      System.arraycopy(value, offset + available, lb.buffer, 0, leftover);\n\n      lb.offset += leftover;\n\n      return lb;\n    }\n\n    // it fits\n    System.arraycopy(value, offset, lb.buffer, lb.offset, valueLen);\n\n    lb.offset += valueLen;\n\n    return lb;\n  }\n\n  /**\n   * Returns the buffer encoded with the tag and var int 32\n   */\n  public static LinkedBuffer writeTagAndRawVarInt32(int tag, int tagSize, int value,\n      final WriteSession session, LinkedBuffer lb) {\n    final int size = computeRawVarint32Size(value);\n    final int totalSize = tagSize + size;\n\n    if (lb.offset + totalSize > lb.buffer.length) {\n      lb = new LinkedBuffer(session.nextBufferSize, lb);\n    }\n\n    final byte[] buffer = lb.buffer;\n    int offset = lb.offset;\n    lb.offset += totalSize;\n    session.size += totalSize;\n\n    if (tagSize == 1) {\n      buffer[offset++] = (byte) tag;\n    } else {\n      for (int i = 0, last = tagSize - 1; i < last; i++, tag >>>= 7) {\n        buffer[offset++] = (byte) ((tag & 0x7F) | 0x80);\n      }\n\n      buffer[offset++] = (byte) tag;\n    }\n\n    if (size == 1) {\n      buffer[offset] = (byte) value;\n    } else {\n      for (int i = 0, last = size - 1; i < last; i++, value >>>= 7) {\n        buffer[offset++] = (byte) ((value & 0x7F) | 0x80);\n      }\n\n      buffer[offset] = (byte) value;\n    }\n\n    return lb;\n  }\n\n  /**\n   * Returns the buffer encoded with the tag and var int 64\n   */\n  public static LinkedBuffer writeTagAndRawVarInt64(int tag, int tagSize, long value,\n      final WriteSession session, LinkedBuffer lb) {\n    final int size = computeRawVarint64Size(value);\n    final int totalSize = tagSize + size;\n\n    if (lb.offset + totalSize > lb.buffer.length) {\n      lb = new LinkedBuffer(session.nextBufferSize, lb);\n    }\n\n    final byte[] buffer = lb.buffer;\n    int offset = lb.offset;\n    lb.offset += totalSize;\n    session.size += totalSize;\n\n    if (tagSize == 1) {\n      buffer[offset++] = (byte) tag;\n    } else {\n      for (int i = 0, last = tagSize - 1; i < last; i++, tag >>>= 7) {\n        buffer[offset++] = (byte) ((tag & 0x7F) | 0x80);\n      }\n\n      buffer[offset++] = (byte) tag;\n    }\n\n    if (size == 1) {\n      buffer[offset] = (byte) value;\n    } else {\n      for (int i = 0, last = size - 1; i < last; i++, value >>>= 7) {\n        buffer[offset++] = (byte) (((int) value & 0x7F) | 0x80);\n      }\n\n      buffer[offset] = (byte) value;\n    }\n\n    return lb;\n  }\n\n  /**\n   * Returns the buffer encoded with the tag and little endian 32\n   */\n  public static LinkedBuffer writeTagAndRawLittleEndian32(int tag, int tagSize, int value,\n      final WriteSession session, LinkedBuffer lb) {\n    final int totalSize = tagSize + LITTLE_ENDIAN_32_SIZE;\n\n    if (lb.offset + totalSize > lb.buffer.length) {\n      lb = new LinkedBuffer(session.nextBufferSize, lb);\n    }\n\n    final byte[] buffer = lb.buffer;\n    int offset = lb.offset;\n    lb.offset += totalSize;\n    session.size += totalSize;\n\n    if (tagSize == 1) {\n      buffer[offset++] = (byte) tag;\n    } else {\n      for (int i = 0, last = tagSize - 1; i < last; i++, tag >>>= 7) {\n        buffer[offset++] = (byte) ((tag & 0x7F) | 0x80);\n      }\n\n      buffer[offset++] = (byte) tag;\n    }\n\n    writeRawLittleEndian32(value, buffer, offset);\n\n    return lb;\n  }\n\n  /**\n   * Returns the buffer encoded with the tag and little endian 64\n   */\n  public static LinkedBuffer writeTagAndRawLittleEndian64(int tag, int tagSize, long value,\n      final WriteSession session, LinkedBuffer lb) {\n    final int totalSize = tagSize + LITTLE_ENDIAN_64_SIZE;\n\n    if (lb.offset + totalSize > lb.buffer.length) {\n      lb = new LinkedBuffer(session.nextBufferSize, lb);\n    }\n\n    final byte[] buffer = lb.buffer;\n    int offset = lb.offset;\n    lb.offset += totalSize;\n    session.size += totalSize;\n\n    if (tagSize == 1) {\n      buffer[offset++] = (byte) tag;\n    } else {\n      for (int i = 0, last = tagSize - 1; i < last; i++, tag >>>= 7) {\n        buffer[offset++] = (byte) ((tag & 0x7F) | 0x80);\n      }\n\n      buffer[offset++] = (byte) tag;\n    }\n\n    writeRawLittleEndian64(value, buffer, offset);\n\n    return lb;\n  }\n\n  /** Encode and write a varint to the byte array */\n  public static void writeRawVarInt32(int value, final byte[] buf, int offset) throws IOException {\n    while (true) {\n      if ((value & ~0x7F) == 0) {\n        buf[offset] = (byte) value;\n        return;\n      } else {\n        buf[offset++] = (byte) ((value & 0x7F) | 0x80);\n        value >>>= 7;\n      }\n    }\n  }\n\n  /**\n   * Writes the encoded little endian 32 and returns the bytes written\n   */\n  public static int writeRawLittleEndian32(int value, byte[] buffer, int offset) {\n    if (buffer.length - offset < LITTLE_ENDIAN_32_SIZE) {\n      throw new IllegalArgumentException(\"buffer capacity not enough.\");\n    }\n\n    buffer[offset++] = (byte) (value & 0xFF);\n    buffer[offset++] = (byte) (value >> 8 & 0xFF);\n    buffer[offset++] = (byte) (value >> 16 & 0xFF);\n    buffer[offset] = (byte) (value >> 24 & 0xFF);\n\n    return LITTLE_ENDIAN_32_SIZE;\n  }\n\n  /**\n   * Writes the encoded little endian 64 and returns the bytes written\n   */\n  public static int writeRawLittleEndian64(long value, byte[] buffer, int offset) {\n    if (buffer.length - offset < LITTLE_ENDIAN_64_SIZE) {\n      throw new IllegalArgumentException(\"buffer capacity not enough.\");\n    }\n\n    buffer[offset++] = (byte) (value & 0xFF);\n    buffer[offset++] = (byte) (value >> 8 & 0xFF);\n    buffer[offset++] = (byte) (value >> 16 & 0xFF);\n    buffer[offset++] = (byte) (value >> 24 & 0xFF);\n    buffer[offset++] = (byte) (value >> 32 & 0xFF);\n    buffer[offset++] = (byte) (value >> 40 & 0xFF);\n    buffer[offset++] = (byte) (value >> 48 & 0xFF);\n    buffer[offset] = (byte) (value >> 56 & 0xFF);\n\n    return LITTLE_ENDIAN_64_SIZE;\n  }\n\n  /* METHODS FROM CodedOutput */\n\n  // Protocol Buffers - Google's data interchange format\n  // Copyright 2008 Google Inc. All rights reserved.\n  // http://code.google.com/p/protobuf/\n  //\n  // Redistribution and use in source and binary forms, with or without\n  // modification, are permitted provided that the following conditions are\n  // met:\n  //\n  // * Redistributions of source code must retain the above copyright\n  // notice, this list of conditions and the following disclaimer.\n  // * Redistributions in binary form must reproduce the above\n  // copyright notice, this list of conditions and the following disclaimer\n  // in the documentation and/or other materials provided with the\n  // distribution.\n  // * Neither the name of Google Inc. nor the names of its\n  // contributors may be used to endorse or promote products derived from\n  // this software without specific prior written permission.\n  //\n  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  // \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n  /**\n   * Compute the number of bytes that would be needed to encode a varint. {@code value} is treated as unsigned, so it\n   * won't be sign-extended if negative.\n   */\n  public static int computeRawVarint32Size(final int value) {\n    if ((value & (0xffffffff << 7)) == 0) {\n      return 1;\n    }\n    if ((value & (0xffffffff << 14)) == 0) {\n      return 2;\n    }\n    if ((value & (0xffffffff << 21)) == 0) {\n      return 3;\n    }\n    if ((value & (0xffffffff << 28)) == 0) {\n      return 4;\n    }\n    return 5;\n  }\n\n  /**\n   * Compute the number of bytes that would be needed to encode a varint.\n   */\n  public static int computeRawVarint64Size(final long value) {\n    if ((value & (0xffffffffffffffffL << 7)) == 0) {\n      return 1;\n    }\n    if ((value & (0xffffffffffffffffL << 14)) == 0) {\n      return 2;\n    }\n    if ((value & (0xffffffffffffffffL << 21)) == 0) {\n      return 3;\n    }\n    if ((value & (0xffffffffffffffffL << 28)) == 0) {\n      return 4;\n    }\n    if ((value & (0xffffffffffffffffL << 35)) == 0) {\n      return 5;\n    }\n    if ((value & (0xffffffffffffffffL << 42)) == 0) {\n      return 6;\n    }\n    if ((value & (0xffffffffffffffffL << 49)) == 0) {\n      return 7;\n    }\n    if ((value & (0xffffffffffffffffL << 56)) == 0) {\n      return 8;\n    }\n    if ((value & (0xffffffffffffffffL << 63)) == 0) {\n      return 9;\n    }\n    return 10;\n  }\n\n  /**\n   * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into values that can be efficiently encoded\n   * with varint. (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, thus always\n   * taking 10 bytes on the wire.)\n   *\n   * @param n\n   *            A signed 32-bit integer.\n   * @return An unsigned 32-bit integer, stored in a signed int because Java has no explicit unsigned support.\n   */\n  public static int encodeZigZag32(final int n) {\n    // Note: the right-shift must be arithmetic\n    return (n << 1) ^ (n >> 31);\n  }\n\n  /**\n   * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be efficiently encoded\n   * with varint. (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, thus always\n   * taking 10 bytes on the wire.)\n   *\n   * @param n\n   *            A signed 64-bit integer.\n   * @return An unsigned 64-bit integer, stored in a signed int because Java has no explicit unsigned support.\n   */\n  public static long encodeZigZag64(final long n) {\n    // Note: the right-shift must be arithmetic\n    return (n << 1) ^ (n >> 63);\n  }\n\n  /**\n   * Writes a ByteBuffer field.\n   */\n  @Override\n  public void writeBytes(int tag, int tagSize, ByteBuffer value) {\n    writeByteRange(false, tag, tagSize, value.array(), value.arrayOffset() + value.position(), value.remaining());\n  }\n\n  public void toOutputStream(OutputStream outputStream) throws IOException {\n    LinkedBuffer.writeTo(outputStream, head);\n  }\n\n  @Override\n  public void writePackedInt32(int value) {\n    if (value >= 0) {\n      tail = writeRawVarInt32(value, this, tail);\n      return;\n    }\n\n    writePackedUInt64(value);\n  }\n\n  @Override\n  public void writeScalarInt32(int tag, int tagSize, int value) {\n    if (value != 0) {\n      writeInt32(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarInt64(int tag, int tagSize, long value) {\n    if (value != 0) {\n      writeInt64(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writePackedUInt32(int value) {\n    tail = writeRawVarInt32(value, this, tail);\n  }\n\n  @Override\n  public void writeScalarUInt32(int tag, int tagSize, int value) {\n    if (value != 0) {\n      writeUInt32(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writePackedUInt64(long value) {\n    final int size = computeRawVarint64Size(value);\n\n    if (tail.offset + size > tail.buffer.length) {\n      tail = new LinkedBuffer(this.nextBufferSize, tail);\n    }\n\n    final byte[] buffer = tail.buffer;\n    int offset = tail.offset;\n    tail.offset += size;\n    this.size += size;\n\n    if (size == 1) {\n      buffer[offset] = (byte) value;\n    } else {\n      for (int i = 0, last = size - 1; i < last; i++, value >>>= 7) {\n        buffer[offset++] = (byte) (((int) value & 0x7F) | 0x80);\n      }\n\n      buffer[offset] = (byte) value;\n    }\n  }\n\n  @Override\n  public void writeScalarUInt64(int tag, int tagSize, long value) {\n    if (value != 0) {\n      writeUInt64(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writePackedSInt32(int value) {\n    tail = writeRawVarInt32(encodeZigZag32(value), this, tail);\n  }\n\n  @Override\n  public void writeScalarSInt32(int tag, int tagSize, int value) {\n    if (value != 0) {\n      writeSInt32(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarSInt64(int tag, int tagSize, long value) {\n    if (value != 0) {\n      writeSInt64(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writePackedFixed32(int value) {\n    final int size = LITTLE_ENDIAN_32_SIZE;\n\n    if (tail.offset + size > tail.buffer.length) {\n      tail = new LinkedBuffer(this.nextBufferSize, tail);\n    }\n\n    final byte[] buffer = tail.buffer;\n    int offset = tail.offset;\n    tail.offset += size;\n    this.size += size;\n\n    buffer[offset++] = (byte) (value & 0xFF);\n    buffer[offset++] = (byte) (value >> 8 & 0xFF);\n    buffer[offset++] = (byte) (value >> 16 & 0xFF);\n    buffer[offset] = (byte) (value >> 24 & 0xFF);\n  }\n\n  @Override\n  public void writeScalarFixed32(int tag, int tagSize, int value) {\n    if (value != 0) {\n      writeFixed32(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writePackedFixed64(long value) {\n    final int size = LITTLE_ENDIAN_64_SIZE;\n\n    if (tail.offset + size > tail.buffer.length) {\n      tail = new LinkedBuffer(this.nextBufferSize, tail);\n    }\n\n    final byte[] buffer = tail.buffer;\n    int offset = tail.offset;\n    tail.offset += size;\n    this.size += size;\n\n    buffer[offset++] = (byte) (value & 0xFF);\n    buffer[offset++] = (byte) (value >> 8 & 0xFF);\n    buffer[offset++] = (byte) (value >> 16 & 0xFF);\n    buffer[offset++] = (byte) (value >> 24 & 0xFF);\n    buffer[offset++] = (byte) (value >> 32 & 0xFF);\n    buffer[offset++] = (byte) (value >> 40 & 0xFF);\n    buffer[offset++] = (byte) (value >> 48 & 0xFF);\n    buffer[offset] = (byte) (value >> 56 & 0xFF);\n  }\n\n  @Override\n  public void writeScalarFixed64(int tag, int tagSize, long value) {\n    if (value != 0) {\n      writeFixed64(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarSFixed32(int tag, int tagSize, int value) {\n    if (value != 0) {\n      writeSFixed32(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarSFixed64(int tag, int tagSize, long value) {\n    if (value != 0) {\n      writeSFixed64(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarFloat(int tag, int tagSize, float value) {\n    if (value != 0) {\n      writeFloat(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarDouble(int tag, int tagSize, double value) {\n    if (value != 0) {\n      writeDouble(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writePackedBool(boolean value) {\n    final int size = 1;\n\n    if (tail.offset + size > tail.buffer.length) {\n      tail = new LinkedBuffer(this.nextBufferSize, tail);\n    }\n\n    final byte[] buffer = tail.buffer;\n    int offset = tail.offset;\n    tail.offset += size;\n    this.size += size;\n\n    buffer[offset] = (byte) (value ? 1 : 0);\n  }\n\n  @Override\n  public void writeScalarBool(int tag, int tagSize, boolean value) {\n    if (value) {\n      writeBool(tag, tagSize, value);\n    }\n  }\n\n  @Override\n  public void writeScalarEnum(int tag, int tagSize, int value) {\n    writeScalarInt32(tag, tagSize, value);\n  }\n\n  public void writeScalarString(int tag, int tagSize, String value) {\n    writeString(tag, tagSize, value);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaEx.java",
    "content": "//========================================================================\n//Copyright 2007-2009 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\n/**\n * Forked and modified from protostuff\n *\n * Handles the serialization and deserialization of a message/object tied to this.\n * <p>\n * Basically, any object can be serialized via protobuf. As long as its schema is provided, it does not need to\n * implement {@link Message}. This was designed with \"unobtrusive\" in mind. The goal was to be able to\n * serialize/deserialize any existing object without having to touch its source. This will enable you to customize the\n * serialization of objects from 3rd party libraries.\n *\n * @author David Yu\n * @created Nov 9, 2009\n */\npublic interface SchemaEx<T> extends SchemaWriter<T>, SchemaReader<T> {\n  /**\n   * Returns the simple name of the message tied to this schema. Allows custom schemas to provide a custom name other\n   * than typeClass().getSimpleName();\n   */\n  default String messageName() {\n    throw new UnsupportedOperationException();\n  }\n\n  void init();\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaReader.java",
    "content": "//========================================================================\n//Copyright 2007-2009 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\nimport java.io.IOException;\n\npublic interface SchemaReader<T> {\n  /**\n   * Creates the message/object tied to this schema.\n   */\n  default T newMessage() {\n    return null;\n  }\n\n  void mergeFrom(InputEx input, T message) throws IOException;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/SchemaWriter.java",
    "content": "//========================================================================\n//Copyright 2007-2009 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff;\n\nimport java.io.IOException;\n\npublic interface SchemaWriter<T> {\n  void writeTo(OutputEx output, T value) throws IOException;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/package-info.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * <pre>\n * classes in protostuff are \"final\" or not all suitable for ServiceComb\n *   1.final\n *     io.protostuff.ProtobufOutputEx\n *     io.protostuff.ByteArrayInput\n *   2.not suitable\n *     1) io.protostuff.OutputEx\n *        fieldNumber changed to tag, avoid makeTag every time\n *        not support write packed value\n *        not support ignore default scalar value\n *     2) io.protostuff.SchemaEx\n *        make it simpler\n *     3) codec of map is not compatible to protobuf\n * so we must copy and modified them\n * </pre>\n */\n\npackage io.protostuff;\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/ArrayFieldMapEx.java",
    "content": "//========================================================================\n//Copyright 2007-2010 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff.runtime;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Forked and modified from protostuff\n *\n * Field mapping implemented on top of java array for lookup by number.\n *\n * This is the most efficient implementation for almost all cases. But\n * it should not be used when field numbers are sparse and especially\n * when max field number is big - as this mapping internally uses array\n * of integers with size equal to max field number. In latter case\n * {@code HashFieldMapEx} should be used.\n *\n * @see HashFieldMapEx\n *\n * @author Kostiantyn Shchepanovskyi\n */\npublic final class ArrayFieldMapEx<T> implements FieldMapEx<T> {\n  private final List<FieldSchema<T>> fields;\n\n  private final FieldSchema<T>[] fieldsByNumber;\n\n  private final Map<String, FieldSchema<T>> fieldsByName;\n\n  @SuppressWarnings(\"unchecked\")\n  public ArrayFieldMapEx(Collection<FieldSchema<T>> fields, int lastFieldNumber) {\n    fieldsByName = new HashMap<>();\n    fieldsByNumber = (FieldSchema<T>[]) new FieldSchema<?>[lastFieldNumber + 1];\n    for (FieldSchema<T> f : fields) {\n      FieldSchema<T> last = this.fieldsByName.put(f.name, f);\n      if (last != null) {\n        throw new IllegalStateException(last + \" and \" + f + \" cannot have the same name.\");\n      }\n      if (fieldsByNumber[f.getFieldNumber()] != null) {\n        throw new IllegalStateException(\n            fieldsByNumber[f.getFieldNumber()] + \" and \" + f + \" cannot have the same number.\");\n      }\n\n      fieldsByNumber[f.getFieldNumber()] = f;\n    }\n\n    List<FieldSchema<T>> fieldList = new ArrayList<>(fields.size());\n    for (FieldSchema<T> field : fieldsByNumber) {\n      if (field != null) {\n        fieldList.add(field);\n      }\n    }\n    this.fields = Collections.unmodifiableList(fieldList);\n  }\n\n  @Override\n  public FieldSchema<T> getFieldByNumber(int n) {\n    return n < fieldsByNumber.length ? fieldsByNumber[n] : null;\n  }\n\n  @Override\n  public FieldSchema<T> getFieldByName(String fieldName) {\n    return fieldsByName.get(fieldName);\n  }\n\n  /**\n   * Returns the message's total number of fields.\n   */\n  @Override\n  public int getFieldCount() {\n    return fields.size();\n  }\n\n  @Override\n  public List<FieldSchema<T>> getFields() {\n    return fields;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldMapEx.java",
    "content": "//========================================================================\n//Copyright 2007-2010 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff.runtime;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Forked and modified from protostuff\n *\n * Interface for map of fields - defines how to you get field by name or number (tag).\n *\n * @author Kostiantyn Shchepanovskyi\n */\npublic interface FieldMapEx<T> {\n  int MIN_TAG_FOR_HASH_FIELD_MAP = 100;\n\n  static boolean preferHashFieldMap(int fieldCount, int lastFieldNumber) {\n    return lastFieldNumber > MIN_TAG_FOR_HASH_FIELD_MAP && lastFieldNumber >= 2 * fieldCount;\n  }\n\n  static <T> FieldMapEx<T> createFieldMap(Collection<FieldSchema<T>> fields) {\n    int lastFieldNumber = 0;\n    for (FieldSchema<T> field : fields) {\n      if (field.getFieldNumber() > lastFieldNumber) {\n        lastFieldNumber = field.getFieldNumber();\n      }\n    }\n    if (preferHashFieldMap(fields.size(), lastFieldNumber)) {\n      return new HashFieldMapEx<>(fields);\n    }\n    // array field map should be more efficient\n    return new ArrayFieldMapEx<>(fields, lastFieldNumber);\n  }\n\n  FieldSchema<T> getFieldByNumber(int n);\n\n  FieldSchema<T> getFieldByName(String fieldName);\n\n  int getFieldCount();\n\n  List<FieldSchema<T>> getFields();\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldSchema.java",
    "content": "//========================================================================\n//Copyright 2007-2009 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff.runtime;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.ProtobufOutputEx;\nimport io.protostuff.WireFormat;\nimport io.protostuff.compiler.model.Field;\n\n/**\n * Forked and modified from protostuff\n *\n * Represents a field of a message/pojo.\n */\npublic abstract class FieldSchema<T> {\n  protected final Field protoField;\n\n  protected final String name;\n\n  protected final int fieldNumber;\n\n  protected final int tag;\n\n  protected final int tagSize;\n\n  protected final boolean packed;\n\n  protected final JavaType javaType;\n\n  protected final boolean primitive;\n\n  public FieldSchema(Field protoField, JavaType javaType) {\n    this.protoField = protoField;\n    this.name = protoField.getName();\n    this.fieldNumber = protoField.getTag();\n    this.packed = ProtoUtils.isPacked(protoField);\n\n    int wireType = packed && protoField.isRepeated() ? WireFormat.WIRETYPE_LENGTH_DELIMITED\n        : FieldTypeUtils.convert(protoField.getType()).wireType;\n    this.tag = WireFormat.makeTag(fieldNumber, wireType);\n    this.tagSize = ProtobufOutputEx.computeRawVarint32Size(tag);\n\n    this.javaType = javaType;\n    this.primitive = javaType.isPrimitive();\n  }\n\n  public int getFieldNumber() {\n    return fieldNumber;\n  }\n\n  public Field getProtoField() {\n    return protoField;\n  }\n\n  public int mergeFrom(InputEx input, T message) throws IOException {\n    throw new UnsupportedOperationException();\n  }\n\n  public boolean isPrimitive() {\n    return primitive;\n  }\n\n  public void getAndWriteTo(OutputEx output, T message) throws IOException {\n    throw new UnsupportedOperationException();\n  }\n\n  /**\n   * write from map\n   *\n   * @param output\n   * @param value field value, will not be null\n   * @throws IOException\n   */\n  public void writeTo(OutputEx output, Object value) throws IOException {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/FieldTypeUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage io.protostuff.runtime;\n\nimport io.protostuff.WireFormat.FieldType;\nimport io.protostuff.compiler.model.ScalarFieldType;\n\npublic final class FieldTypeUtils {\n  public static FieldType convert(io.protostuff.compiler.model.FieldType fieldType) {\n    if (fieldType.isEnum()) {\n      return FieldType.ENUM;\n    }\n\n    if (fieldType.isScalar()) {\n      switch ((ScalarFieldType) fieldType) {\n        case INT32:\n          return FieldType.INT32;\n        case INT64:\n          return FieldType.INT64;\n        case UINT32:\n          return FieldType.UINT32;\n        case UINT64:\n          return FieldType.UINT64;\n        case SINT32:\n          return FieldType.SINT32;\n        case SINT64:\n          return FieldType.SINT64;\n        case FIXED32:\n          return FieldType.FIXED32;\n        case FIXED64:\n          return FieldType.FIXED64;\n        case SFIXED32:\n          return FieldType.SFIXED32;\n        case SFIXED64:\n          return FieldType.SFIXED64;\n        case FLOAT:\n          return FieldType.FLOAT;\n        case DOUBLE:\n          return FieldType.DOUBLE;\n        case BOOL:\n          return FieldType.BOOL;\n        case STRING:\n          return FieldType.STRING;\n        case BYTES:\n          return FieldType.BYTES;\n        default:\n          throw new IllegalStateException(\"bug: miss process of \" + fieldType);\n      }\n    }\n\n    if (fieldType.isMessage()) {\n      return FieldType.MESSAGE;\n    }\n\n    throw new IllegalStateException(\"bug: miss process of \" + fieldType);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/io/protostuff/runtime/HashFieldMapEx.java",
    "content": "//========================================================================\n//Copyright 2007-2010 David Yu dyuproject@gmail.com\n//------------------------------------------------------------------------\n//Licensed under the Apache License, Version 2.0 (the \"License\");\n//you may not use this file except in compliance with the License.\n//You may obtain a copy of the License at\n//http://www.apache.org/licenses/LICENSE-2.0\n//Unless required by applicable law or agreed to in writing, software\n//distributed under the License is distributed on an \"AS IS\" BASIS,\n//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//See the License for the specific language governing permissions and\n//limitations under the License.\n//========================================================================\n\npackage io.protostuff.runtime;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Forked and modified from protostuff\n *\n * Field mapping implemented on top of hash for field lookup by number.\n *\n * This is the less efficient than {@code ArrayFieldMapEx} for almost all cases.\n * But in case when field numbers are sparse and especially when max field\n * number is big - this mapping should be used.\n *\n * @see ArrayFieldMapEx\n *\n * @author Kostiantyn Shchepanovskyi\n */\npublic final class HashFieldMapEx<T> implements FieldMapEx<T> {\n  private final List<FieldSchema<T>> fields;\n\n  private final Map<Integer, FieldSchema<T>> fieldsByNumber;\n\n  private final Map<String, FieldSchema<T>> fieldsByName;\n\n  public HashFieldMapEx(Collection<FieldSchema<T>> fields) {\n    fieldsByName = new HashMap<>();\n    fieldsByNumber = new HashMap<>();\n    for (FieldSchema<T> f : fields) {\n      if (fieldsByName.containsKey(f.name)) {\n        FieldSchema<T> prev = fieldsByName.get(f.name);\n        throw new IllegalStateException(prev + \" and \" + f + \" cannot have the same name.\");\n      }\n      if (fieldsByNumber.containsKey(f.fieldNumber)) {\n        FieldSchema<T> prev = fieldsByNumber.get(f.fieldNumber);\n        throw new IllegalStateException(prev + \" and \" + f + \" cannot have the same number.\");\n      }\n      this.fieldsByNumber.put(f.fieldNumber, f);\n      this.fieldsByName.put(f.name, f);\n    }\n\n    List<FieldSchema<T>> fieldList = new ArrayList<>(fields.size());\n    fieldList.addAll(fields);\n    fieldList.sort(Comparator.comparingInt(FieldSchema::getFieldNumber));\n    this.fields = Collections.unmodifiableList(fieldList);\n  }\n\n  @Override\n  public FieldSchema<T> getFieldByNumber(int n) {\n    return fieldsByNumber.get(n);\n  }\n\n  @Override\n  public FieldSchema<T> getFieldByName(String fieldName) {\n    return fieldsByName.get(fieldName);\n  }\n\n  @Override\n  public int getFieldCount() {\n    return fields.size();\n  }\n\n  @Override\n  public List<FieldSchema<T>> getFields() {\n    return fields;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptorManager;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.DeserializerSchemaManager;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.SerializerSchemaManager;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.Proto;\nimport io.protostuff.compiler.model.Service;\nimport io.protostuff.compiler.model.ServiceMethod;\n\npublic class ProtoMapper {\n  private final ObjectMapper jsonMapper;\n\n  private final BeanDescriptorManager beanDescriptorManager;\n\n  private final Proto proto;\n\n  private final SerializerSchemaManager serializerSchemaManager;\n\n  private final DeserializerSchemaManager deserializerSchemaManager;\n\n  // key is message canonical name\n  // this allowed developer to control any type deserializer\n  // otherwise any type will be deserialized to LinkedHashMap\n  private final Map<String, JavaType> anyTypes = new ConcurrentHashMapEx<>();\n\n  protected ProtoMapper(ObjectMapper jsonMapper, BeanDescriptorManager beanDescriptorManager, Proto proto) {\n    this.jsonMapper = jsonMapper;\n    this.beanDescriptorManager = beanDescriptorManager;\n    this.proto = proto;\n\n    serializerSchemaManager = new SerializerSchemaManager(this);\n    deserializerSchemaManager = new DeserializerSchemaManager(this);\n  }\n\n  public Proto getProto() {\n    return proto;\n  }\n\n  public SerializerSchemaManager getSerializerSchemaManager() {\n    return serializerSchemaManager;\n  }\n\n  public DeserializerSchemaManager getDeserializerSchemaManager() {\n    return deserializerSchemaManager;\n  }\n\n  public ObjectMapper getJsonMapper() {\n    return jsonMapper;\n  }\n\n  public BeanDescriptorManager getBeanDescriptorManager() {\n    return beanDescriptorManager;\n  }\n\n  public Map<String, JavaType> getAnyTypes() {\n    return anyTypes;\n  }\n\n  public void addAnyType(String canonicalName, Type type) {\n    anyTypes.put(canonicalName, TypeFactory.defaultInstance().constructType(type));\n  }\n\n  public Message getMessageFromCanonicaName(String messageCanonicalName) {\n    for (Message message : proto.getMessages()) {\n      if (message.getCanonicalName().equals(messageCanonicalName)) {\n        return message;\n      }\n    }\n\n    return null;\n  }\n\n  public Message getRequestMessage(String operationId) {\n    Service service = proto.getServices().get(0);\n    ServiceMethod serviceMethod = service.getMethod(operationId);\n    if (serviceMethod == null) {\n      throw new IllegalArgumentException(\"operation not found, operation id=\" + operationId);\n    }\n    return serviceMethod.getArgType();\n  }\n\n  public Message getResponseMessage(String operationId) {\n    Service service = proto.getServices().get(0);\n    ServiceMethod serviceMethod = service.getMethod(operationId);\n    return serviceMethod.getReturnType();\n  }\n\n  public synchronized RootSerializer createRootSerializer(String shortMessageName, Type type) {\n    Message message = proto.getMessage(shortMessageName);\n    if (message == null) {\n      throw new IllegalStateException(\"can not find proto message to create serializer, name=\" + shortMessageName);\n    }\n\n    return createRootSerializer(message, type);\n  }\n\n  public synchronized RootSerializer createRootSerializer(Message message, Type type) {\n    return serializerSchemaManager.createRootSerializer(message, type);\n  }\n\n  public synchronized <T> RootDeserializer<T> createRootDeserializer(String shortMessageName, Type type) {\n    Message message = proto.getMessage(shortMessageName);\n    if (message == null) {\n      throw new IllegalStateException(\"can not find proto message to create deserializer, name=\" + shortMessageName);\n    }\n\n    return createRootDeserializer(message, type);\n  }\n\n  public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {\n    return deserializerSchemaManager.createRootDeserializer(message, type);\n  }\n\n  public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Map<String, Type> types) {\n    return deserializerSchemaManager.createRootDeserializer(message, types);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptorManager;\nimport org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;\n\nimport com.fasterxml.jackson.annotation.JsonInclude.Include;\nimport com.fasterxml.jackson.databind.DeserializationFeature;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\nimport io.protostuff.compiler.model.Proto;\n\npublic class ProtoMapperFactory {\n  // 1.to support \"any\" type\n  // 2.to find bean properties\n  private final ObjectMapper jsonMapper = new ObjectMapper();\n\n  private final BeanDescriptorManager beanDescriptorManager;\n\n  private final ProtoParser protoParser = new ProtoParser();\n\n  public ProtoMapperFactory() {\n    jsonMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);\n    jsonMapper.setSerializationInclusion(Include.NON_NULL);\n\n    beanDescriptorManager = new BeanDescriptorManager(jsonMapper.getSerializationConfig());\n  }\n\n  public ObjectMapper getJsonMapper() {\n    return jsonMapper;\n  }\n\n  public BeanDescriptorManager getBeanDescriptorManager() {\n    return beanDescriptorManager;\n  }\n\n  public ProtoMapper createFromContent(String content) {\n    Proto proto = protoParser.parseFromContent(content);\n    return create(proto);\n  }\n\n  public ProtoMapper createFromName(String name) {\n    Proto proto = protoParser.parse(name);\n    return create(proto);\n  }\n\n  public ProtoMapper create(Proto proto) {\n    return new ProtoMapper(jsonMapper, beanDescriptorManager, proto);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RootDeserializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf;\n\nimport java.io.IOException;\n\nimport io.protostuff.ByteArrayInputEx;\nimport io.protostuff.InputEx;\nimport io.protostuff.SchemaEx;\n\npublic class RootDeserializer<T> {\n  protected SchemaEx<T> schema;\n\n  public RootDeserializer(SchemaEx<T> schema) {\n    this.schema = schema;\n  }\n\n  public SchemaEx<T> getSchema() {\n    return schema;\n  }\n\n  public void setSchema(SchemaEx<T> schema) {\n    this.schema = schema;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public T deserialize(byte[] bytes) throws IOException {\n    InputEx input = new ByteArrayInputEx(bytes);\n    T instance = schema.newMessage();\n    schema.mergeFrom(input, instance);\n    return instance;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RootSerializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\n\nimport io.protostuff.ProtobufOutputEx;\nimport io.protostuff.SchemaEx;\n\npublic class RootSerializer {\n  private final SchemaEx<Object> schema;\n\n  public RootSerializer(SchemaEx<Object> schema) {\n    this.schema = schema;\n  }\n\n  public byte[] serialize(Object value) throws IOException {\n    ProtobufOutputEx output = new ProtobufOutputEx();\n    if (value != null) {\n      schema.writeTo(output, value);\n    }\n    return output.toByteArray();\n  }\n\n  public void serialize(OutputStream outputStream, Object value) throws IOException {\n    ProtobufOutputEx output = new ProtobufOutputEx();\n    if (value != null) {\n      schema.writeTo(output, value);\n    }\n    output.toOutputStream(outputStream);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal;\n\nimport java.util.ArrayList;\nimport java.util.LinkedHashMap;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.Proto;\n\npublic final class ProtoConst {\n  private ProtoConst() {\n  }\n\n  public static final String ANNOTATION_WRAP_ARGUMENTS = \"@WrapArguments\";\n\n  public static final String ANNOTATION_WRAP_PROPERTY = \"@WrapProperty\";\n\n  public static String ANNOTATION_RPC = \"@Rpc\";\n\n  public static final String PACK_SCHEMA = \"type.googleapis.com/\";\n\n  public static final String JSON_SCHEMA = \"json/\";\n\n  public static final String JSON_ID_NAME = \"@type\";\n\n  public static final JavaType MAP_TYPE = TypeFactory.defaultInstance().constructType(LinkedHashMap.class);\n\n  public static final JavaType LIST_TYPE = TypeFactory.defaultInstance().constructType(ArrayList.class);\n\n  public static final JavaType OBJECT_TYPE = TypeFactory.defaultInstance().constructType(Object.class);\n\n  public static final Proto ANY_PROTO;\n\n  public static final Message ANY;\n\n  public static final Proto EMPTY_PROTO;\n\n  public static final Message EMPTY;\n\n  static {\n    ProtoParser protoParser = new ProtoParser();\n\n    ANY_PROTO = protoParser.parse(\"google/protobuf/any.proto\");\n    ANY = ANY_PROTO.getMessage(\"Any\");\n\n    EMPTY_PROTO = protoParser.parse(\"google/protobuf/empty.proto\");\n    EMPTY = EMPTY_PROTO.getMessage(\"Empty\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.compiler.model.DynamicMessage;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.FieldContainer;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.ScalarFieldType;\nimport io.protostuff.compiler.model.Type;\n\npublic final class ProtoUtils {\n  private ProtoUtils() {\n  }\n\n  public static boolean isEmptyMessage(Message protoField) {\n    return protoField.getCanonicalName().equals(ProtoConst.EMPTY.getCanonicalName());\n  }\n\n  public static boolean isAnyMessage(Message protoField) {\n    return protoField.getCanonicalName().equals(ProtoConst.ANY.getCanonicalName());\n  }\n\n  public static boolean isAnyField(Field protoField) {\n    return protoField.getType().getCanonicalName().equals(ProtoConst.ANY.getCanonicalName());\n  }\n\n  public static boolean isWrapArguments(FieldContainer fieldContainer) {\n    return fieldContainer.getCommentLines().contains(ProtoConst.ANNOTATION_WRAP_ARGUMENTS);\n  }\n\n  public static boolean isWrapProperty(FieldContainer fieldContainer) {\n    return fieldContainer.getCommentLines().contains(ProtoConst.ANNOTATION_WRAP_PROPERTY);\n  }\n\n  /**\n   * all supported type, default to packed\n   * @param protoField\n   * @return\n   */\n  public static boolean isSupportPacked(Field protoField) {\n    if (protoField.getType().isEnum()) {\n      return true;\n    }\n\n    if (protoField.getType().isScalar()) {\n      ScalarFieldType scalarFieldType = (ScalarFieldType) protoField.getType();\n      return scalarFieldType != ScalarFieldType.STRING && scalarFieldType != ScalarFieldType.BYTES;\n    }\n\n    return false;\n  }\n\n  public static boolean isPacked(Field protoField) {\n    DynamicMessage.Value dynamicMessageValue = protoField.getOptions().get(\"packed\");\n    if (dynamicMessageValue != null) {\n      return dynamicMessageValue.getBoolean();\n    }\n\n    return isSupportPacked(protoField);\n  }\n\n  public static void throwNotSupportWrite(Field protoField, Object value) throws IllegalStateException {\n    throwNotSupportWrite(protoField, value.getClass());\n  }\n\n  public static void throwNotSupportWrite(Field protoField, Class<?> cls) throws IllegalStateException {\n    throw new IllegalStateException(\n        String.format(\"not support serialize from %s to proto %s, field=%s:%s\",\n            cls.getName(),\n            protoField.getTypeName(),\n            ((Type) protoField.getParent()).getCanonicalName(),\n            protoField.getName()));\n  }\n\n  public static void throwNotSupportMerge(Field protoField, JavaType javaType) throws IllegalStateException {\n    throw new IllegalStateException(\n        String.format(\"not support deserialize proto %s as %s, field=%s:%s\",\n            protoField.getTypeName(),\n            javaType.toCanonical(),\n            ((Type) protoField.getParent()).getCanonicalName(),\n            protoField.getName()));\n  }\n\n  public static void throwNotSupportNullElement(Field protoField) throws IllegalStateException {\n    throw new IllegalStateException(\n        String.format(\"not support serialize null element, field=%s:%s\",\n            ((Type) protoField.getParent()).getCanonicalName(),\n            protoField.getName()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.bean;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.databind.BeanDescription;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.SerializationConfig;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\n\npublic class BeanDescriptor {\n  private static final Logger LOGGER = LoggerFactory.getLogger(BeanDescriptor.class);\n\n  private JavaType javaType;\n\n  private final Map<String, PropertyDescriptor> propertyDescriptors = new HashMap<>();\n\n  public JavaType getJavaType() {\n    return javaType;\n  }\n\n  public Map<String, PropertyDescriptor> getPropertyDescriptors() {\n    return propertyDescriptors;\n  }\n\n  public void init(SerializationConfig serializationConfig, JavaType javaType) {\n    this.javaType = javaType;\n\n    BeanDescription beanDescription = serializationConfig.introspect(javaType);\n    for (BeanPropertyDefinition propertyDefinition : beanDescription.findProperties()) {\n      PropertyDescriptor propertyDescriptor = new PropertyDescriptor();\n      propertyDescriptor.setName(propertyDefinition.getName());\n      propertyDescriptor.setJavaType(propertyDefinition.getPrimaryType());\n\n      try {\n        propertyDescriptor.setGetter(initGetter(propertyDefinition));\n      } catch (Throwable e) {\n        LOGGER.error(\"failed to init getter for field {}:{}\", javaType.getRawClass().getName(),\n            propertyDefinition.getName(), e);\n      }\n\n      try {\n        propertyDescriptor.setSetter(initSetter(propertyDefinition));\n      } catch (Throwable e) {\n        LOGGER.error(\"failed to init setter for field {}:{}\", javaType.getRawClass().getName(),\n            propertyDefinition.getName(), e);\n      }\n\n      propertyDescriptors.put(propertyDefinition.getName(), propertyDescriptor);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T initGetter(BeanPropertyDefinition propertyDefinition) {\n    if (propertyDefinition.hasGetter()) {\n      return LambdaMetafactoryUtils.createGetter(propertyDefinition.getGetter().getAnnotated());\n    }\n\n    if (propertyDefinition.hasField() && propertyDefinition.getField().isPublic()) {\n      return (T) LambdaMetafactoryUtils.createGetter(propertyDefinition.getField().getAnnotated());\n    }\n\n    return null;\n  }\n\n  protected Object initSetter(BeanPropertyDefinition propertyDefinition) {\n    if (propertyDefinition.hasSetter()) {\n      return LambdaMetafactoryUtils.createSetter(propertyDefinition.getSetter().getAnnotated());\n    }\n\n    if (propertyDefinition.hasField() && propertyDefinition.getField().isPublic()) {\n      return LambdaMetafactoryUtils.createSetter(propertyDefinition.getField().getAnnotated());\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/BeanDescriptorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.bean;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.SerializationConfig;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\npublic class BeanDescriptorManager {\n  private final SerializationConfig serializationConfig;\n\n  private final Map<Type, BeanDescriptor> beanDescriptors = new ConcurrentHashMapEx<>();\n\n  public BeanDescriptorManager(SerializationConfig serializationConfig) {\n    this.serializationConfig = serializationConfig;\n  }\n\n  public BeanDescriptor getOrCreateBeanDescriptor(Type type) {\n    return beanDescriptors.computeIfAbsent(type, this::createBeanDescriptor);\n  }\n\n  protected BeanDescriptor createBeanDescriptor(Type type) {\n    return createBeanDescriptor(TypeFactory.defaultInstance().constructType(type));\n  }\n\n  protected BeanDescriptor createBeanDescriptor(JavaType javaType) {\n    BeanDescriptor beanDescriptor = new BeanDescriptor();\n    beanDescriptor.init(serializationConfig, javaType);\n    return beanDescriptor;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyDescriptor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.bean;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic class PropertyDescriptor {\n  private String name;\n\n  private JavaType javaType;\n\n  private Object getter;\n\n  private Object setter;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public JavaType getJavaType() {\n    return javaType;\n  }\n\n  public void setJavaType(JavaType javaType) {\n    this.javaType = javaType;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getGetter() {\n    return (T) getter;\n  }\n\n  public void setGetter(Object getter) {\n    this.getter = getter;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getSetter() {\n    return (T) setter;\n  }\n\n  public void setSetter(Object setter) {\n    this.setter = setter;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.bean;\n\npublic class PropertyWrapper<T> {\n  private T value;\n\n  public T getValue() {\n    return value;\n  }\n\n  public void setValue(T value) {\n    this.value = value;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/parser/ContentFileReader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.parser;\n\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.CharStreams;\n\nimport io.protostuff.compiler.parser.FileReader;\n\npublic class ContentFileReader implements FileReader {\n  private final FileReader importReader;\n\n  private final String content;\n\n  private boolean contentRead;\n\n  public ContentFileReader(FileReader importReader, String content) {\n    this.importReader = importReader;\n    this.content = content;\n  }\n\n  @Override\n  public CharStream read(String contentOrName) {\n    if (!contentRead) {\n      contentRead = true;\n      return CharStreams.fromString(this.content);\n    }\n\n    return importReader.read(contentOrName);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/parser/ProtoParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.parser;\n\nimport java.util.Collections;\n\nimport com.google.inject.Guice;\nimport com.google.inject.Injector;\n\nimport io.protostuff.compiler.ParserModule;\nimport io.protostuff.compiler.model.Proto;\nimport io.protostuff.compiler.parser.FileDescriptorLoader;\nimport io.protostuff.compiler.parser.FileReader;\nimport io.protostuff.compiler.parser.FileReaderFactory;\nimport io.protostuff.compiler.parser.ProtoContext;\n\n/**\n * can be reused\n */\npublic class ProtoParser {\n  private static final String DEFAULT_PROTO_NAME = \"default.proto\";\n\n  private final Injector injector = Guice.createInjector(new ParserModule());\n\n  private final FileReaderFactory fileReaderFactory = injector.getInstance(FileReaderFactory.class);\n\n  private final FileReader defaultReader = fileReaderFactory.create(Collections.emptyList());\n\n  private final FileDescriptorLoader loader = injector.getInstance(FileDescriptorLoader.class);\n\n  public Proto parseFromContent(String content) {\n    // io.protostuff.compiler.parser.ClasspathFileReader will use ContextClassLoader load resource, but in some environment,\n    // ContextClassLoader is null, and we use class loader instead.\n    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n    try {\n      if (classLoader == null) {\n        Thread.currentThread().setContextClassLoader(ProtoParser.class.getClassLoader());\n      }\n      ProtoContext context = loader.load(new ContentFileReader(defaultReader, content), DEFAULT_PROTO_NAME);\n      return context.getProto();\n    } finally {\n      Thread.currentThread().setContextClassLoader(classLoader);\n    }\n  }\n\n  public Proto parse(String name) {\n    // io.protostuff.compiler.parser.ClasspathFileReader will use ContextClassLoader load resource, but in some environment,\n    // ContextClassLoader is null, and we use class loader instead.\n    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n    try {\n      if (classLoader == null) {\n        Thread.currentThread().setContextClassLoader(ProtoParser.class.getClassLoader());\n      }\n      ProtoContext context = loader.load(defaultReader, name);\n      return context.getProto();\n    } finally {\n      Thread.currentThread().setContextClassLoader(classLoader);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/EnumMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.lang.reflect.Method;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.compiler.model.EnumConstant;\nimport io.protostuff.compiler.model.Field;\n\npublic class EnumMeta {\n  private final Map<String, Integer> enumNameToValueMap = new HashMap<>();\n\n  // key is idl defined enum value\n  // value is Enum<?> or null\n  private final Map<Integer, Enum<?>> enumValues = new HashMap<>();\n\n  public EnumMeta(Field protoField, JavaType javaType) {\n    io.protostuff.compiler.model.Enum enumType = (io.protostuff.compiler.model.Enum) protoField.getType();\n    for (EnumConstant enumConstant : enumType.getConstants()) {\n      enumNameToValueMap.put(enumConstant.getName(), enumConstant.getValue());\n      enumValues.put(enumConstant.getValue(), null);\n    }\n\n    if (!javaType.isEnumType()) {\n      return;\n    }\n\n    try {\n      Method method = javaType.getRawClass().getMethod(\"values\");\n      method.setAccessible(true);\n      Object[] values = (Object[]) method.invoke(null);\n      for (Object value : values) {\n        Enum<?> enumValue = (Enum<?>) value;\n        enumValues.put(enumNameToValueMap.get(enumValue.name()), enumValue);\n      }\n    } catch (Throwable e) {\n      throw new IllegalStateException(\n          \"Failed to collect enum values, class=\" + javaType.getRawClass().getName(), e);\n    }\n  }\n\n  public boolean containsValue(Integer value) {\n    return enumValues.containsKey(value);\n  }\n\n  public Enum<?> getEnumByValue(int enumValue) {\n    return enumValues.get(enumValue);\n  }\n\n  public Integer getValueByName(String name) {\n    return enumNameToValueMap.get(name);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/MessageAsFieldSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class MessageAsFieldSchema<T> extends FieldSchema<T> {\n  protected final SchemaEx<Object> schema;\n\n  protected final Getter<T, Object> getter;\n\n  protected final Setter<T, Object> setter;\n\n  public MessageAsFieldSchema(Field protoField, PropertyDescriptor propertyDescriptor, SchemaEx<Object> schema) {\n    super(protoField, propertyDescriptor.getJavaType());\n    this.schema = schema;\n    this.getter = propertyDescriptor.getGetter();\n    this.setter = propertyDescriptor.getSetter();\n  }\n\n  @Override\n  public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n    Object value = getter.get(message);\n    if (value == null) {\n      return;\n    }\n\n    output.writeObject(tag, tagSize, value, schema);\n  }\n\n  @Override\n  public final void writeTo(OutputEx output, Object value) throws IOException {\n    output.writeObject(tag, tagSize, value, schema);\n  }\n\n  @Override\n  public final int mergeFrom(InputEx input, T message) throws IOException {\n    Object value = getter.get(message);\n    if (value == null) {\n      value = schema.newMessage();\n      setter.set(message, value);\n    }\n    input.mergeObject(value, schema);\n    return input.readFieldNumber();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapperAsFieldSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.MessageReadSchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.MessageWriteSchema;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\n/**\n *\n */\npublic class PropertyWrapperAsFieldSchema<T> extends FieldSchema<T> {\n  private final SchemaEx<Object> schema;\n\n  private final FieldSchema<Object> fieldSchema;\n\n  protected final Getter<T, Object> getter;\n\n  protected final Setter<T, Object> setter;\n\n  public PropertyWrapperAsFieldSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n      SchemaEx<Object> schema) {\n    super(protoField, propertyDescriptor.getJavaType());\n    this.schema = schema;\n    this.getter = propertyDescriptor.getGetter();\n    this.setter = propertyDescriptor.getSetter();\n\n    if (schema instanceof MessageWriteSchema) {\n      fieldSchema = ((MessageWriteSchema<Object>) schema).getMainPojoFieldMaps().getFieldByNumber(1);\n      return;\n    }\n\n    fieldSchema = ((MessageReadSchema<Object>) schema).getFieldMap().getFieldByNumber(1);\n  }\n\n  @Override\n  public void getAndWriteTo(OutputEx output, T message) throws IOException {\n    output.writeObject(tag, tagSize, message, fieldSchema::writeTo);\n  }\n\n  @Override\n  public void writeTo(OutputEx output, Object value) throws IOException {\n    output.writeObject(tag, tagSize, value, fieldSchema::writeTo);\n  }\n\n  @Override\n  public int mergeFrom(InputEx input, T message) throws IOException {\n    PropertyWrapper<Object> wrapper = new PropertyWrapper<>();\n    input.mergeObject(wrapper, schema);\n    setter.set(message, wrapper.getValue());\n    return input.readFieldNumber();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isAnyField;\nimport static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isWrapProperty;\n\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.commons.lang3.ClassUtils;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.bean.MapGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.MapSetter;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.any.AnySchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.map.MapEntry;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.map.MapSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.Proto;\nimport io.protostuff.runtime.FieldMapEx;\nimport io.protostuff.runtime.FieldSchema;\n\npublic abstract class SchemaManager {\n  protected final ProtoMapper protoMapper;\n\n  protected final Proto proto;\n\n  // key is canonical message name + \":\" + canonical type name\n  protected final Map<String, SchemaEx<?>> canonicalSchemas = new ConcurrentHashMapEx<>();\n\n  // key is canonical message name + \":\" + canonical type name\n  protected final Map<String, SchemaEx<?>> canonicalSchemasCreated = new ConcurrentHashMapEx<>();\n\n  public SchemaManager(ProtoMapper protoMapper) {\n    this.protoMapper = protoMapper;\n    this.proto = protoMapper.getProto();\n  }\n\n  protected String generateCacheKey(Message message, JavaType javaType) {\n    return message.getCanonicalName() + \":\" + javaType.toCanonical();\n  }\n\n  protected abstract <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType);\n\n  protected abstract <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types);\n\n  protected abstract <T> FieldSchema<T> createScalarField(Field protoField, PropertyDescriptor propertyDescriptor);\n\n  @SuppressWarnings(\"unchecked\")\n  protected <T> SchemaEx<T> getOrCreateMessageSchema(Message message, Map<String, Type> types) {\n    String cacheKey = generateCacheKey(message, ProtoConst.MAP_TYPE);\n    return (SchemaEx<T>) canonicalSchemasCreated.computeIfAbsent(cacheKey, key -> createMessageSchema(message, types));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  protected <T> SchemaEx<T> getOrCreateMessageSchema(Message message, JavaType javaType) {\n    String cacheKey = generateCacheKey(message, javaType);\n    return (SchemaEx<T>) canonicalSchemasCreated.computeIfAbsent(cacheKey,\n        key -> createMessageSchema(message, javaType));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  protected <T> SchemaEx<T> createMessageSchema(Message message, Map<String, Type> types) {\n    String cacheKey = generateCacheKey(message, ProtoConst.MAP_TYPE);\n    SchemaEx<T> schema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);\n    if (schema != null) {\n      return schema;\n    }\n\n    schema = newMessageSchema(message, types);\n    canonicalSchemas.put(cacheKey, schema);\n\n    schema.init();\n    return schema;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  protected <T> SchemaEx<T> createMessageSchema(Message message, JavaType javaType) {\n    String cacheKey = generateCacheKey(message, javaType);\n    SchemaEx<T> schema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);\n    if (schema != null) {\n      return schema;\n    }\n\n    schema = newMessageSchema(message, javaType);\n    canonicalSchemas.put(cacheKey, schema);\n\n    schema.init();\n    return schema;\n  }\n\n  protected <T> FieldSchema<T> createMapFieldSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (javaType.isJavaLangObject()) {\n      javaType = ProtoConst.MAP_TYPE;\n    }\n\n    JavaType entryType = TypeFactory.defaultInstance().constructParametricType(MapEntry.class,\n        javaType.getKeyType(),\n        javaType.getContentType());\n    SchemaEx<Entry<Object, Object>> entrySchema = createMessageSchema((Message) protoField.getType(),\n        entryType);\n    return new MapSchema<>(protoField, propertyDescriptor, entrySchema);\n  }\n\n  // normal message write from or read to a map\n  public FieldMapEx<Map<Object, Object>> createMapFields(Message message) {\n    List<FieldSchema<Map<Object, Object>>> fieldSchemas = new ArrayList<>();\n    for (Field protoField : message.getFields()) {\n      PropertyDescriptor propertyDescriptor = new PropertyDescriptor();\n      propertyDescriptor.setJavaType(ProtoConst.OBJECT_TYPE);\n      propertyDescriptor.setGetter(new MapGetter<>(protoField.getName()));\n      propertyDescriptor.setSetter(new MapSetter<>(protoField.getName()));\n\n      FieldSchema<Map<Object, Object>> fieldSchema = createSchemaField(protoField, propertyDescriptor);\n      fieldSchemas.add(fieldSchema);\n    }\n\n    return FieldMapEx.createFieldMap(fieldSchemas);\n  }\n\n  public FieldMapEx<Map<Object, Object>> createMapFields(Message message, Map<String, Type> types) {\n    List<FieldSchema<Map<Object, Object>>> fieldSchemas = new ArrayList<>();\n    for (Field protoField : message.getFields()) {\n      PropertyDescriptor propertyDescriptor = new PropertyDescriptor();\n\n      JavaType javaType = getParameterType(types, protoField.getName());\n      if (javaType.isPrimitive()) {\n        javaType = TypeFactory.defaultInstance().constructType(ClassUtils.primitiveToWrapper(javaType.getRawClass()));\n      }\n      propertyDescriptor.setJavaType(javaType);\n      propertyDescriptor.setGetter(new MapGetter<>(protoField.getName()));\n      propertyDescriptor.setSetter(new MapSetter<>(protoField.getName()));\n\n      FieldSchema<Map<Object, Object>> fieldSchema = createSchemaField(protoField, propertyDescriptor);\n      fieldSchemas.add(fieldSchema);\n    }\n\n    return FieldMapEx.createFieldMap(fieldSchemas);\n  }\n\n  private JavaType getParameterType(Map<String, Type> types, String parameterName) {\n\n    if (types.get(parameterName) != null) {\n      return TypeFactory.defaultInstance().constructType(types.get(parameterName));\n    }\n\n    throw new IllegalArgumentException(\n        String.format(\"not found type info for parameter name [%s]\", parameterName));\n  }\n\n  public <T> FieldSchema<T> createSchemaField(Field protoField, PropertyDescriptor propertyDescriptor) {\n    // map is a special repeated\n    if (protoField.isMap()) {\n      return createMapFieldSchema(protoField, propertyDescriptor);\n    }\n\n    if (protoField.isRepeated()) {\n      return createRepeatedSchema(protoField, propertyDescriptor);\n    }\n\n    if (isAnyField(protoField)) {\n      return new AnySchema<>(protoMapper, protoField, propertyDescriptor);\n    }\n\n    if (protoField.getType().isScalar()) {\n      return createScalarField(protoField, propertyDescriptor);\n    }\n\n    // message\n    if (protoField.getType().isMessage()) {\n      SchemaEx<Object> messageSchema = createMessageSchema((Message) protoField.getType(),\n          propertyDescriptor.getJavaType());\n      if (isWrapProperty((Message) protoField.getType())) {\n        return new PropertyWrapperAsFieldSchema<>(protoField, propertyDescriptor, messageSchema);\n      }\n\n      return new MessageAsFieldSchema<>(protoField, propertyDescriptor, messageSchema);\n    }\n\n    if (protoField.isOneofPart()) {\n      throw new IllegalStateException(\"not IMPL oneof now.\");\n    }\n\n    ProtoUtils.throwNotSupportWrite(protoField, propertyDescriptor.getJavaType().getRawClass());\n    return null;\n  }\n\n  protected abstract <T> FieldSchema<T> createRepeatedSchema(Field protoField, PropertyDescriptor propertyDescriptor);\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/any/AnyEntry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.any;\n\npublic class AnyEntry {\n  private String typeUrl;\n\n  private byte[] value;\n\n  public String getTypeUrl() {\n    return typeUrl;\n  }\n\n  public void setTypeUrl(String typeUrl) {\n    this.typeUrl = typeUrl;\n  }\n\n  public byte[] getValue() {\n    return value;\n  }\n\n  public void setValue(byte[] value) {\n    this.value = value;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/any/AnyEntrySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.any;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.SchemaWriter;\nimport io.protostuff.WireFormat;\nimport io.protostuff.compiler.model.Message;\n\npublic class AnyEntrySchema implements SchemaEx<Object> {\n  private final ProtoMapper protoMapper;\n\n  // key is message short name\n  private final Map<String, SchemaWriter<Object>> anyEntrySserializers = new ConcurrentHashMapEx<>();\n\n  // key is message canonical name\n  private final Map<String, RootDeserializer<Object>> rootDeserializers = new ConcurrentHashMapEx<>();\n\n  private final int keyTag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);\n\n  private final int valueTag = WireFormat.makeTag(2, WireFormat.WIRETYPE_LENGTH_DELIMITED);\n\n  private final Type anyTargetType;\n\n  public AnyEntrySchema(ProtoMapper protoMapper, Type type) {\n    this.protoMapper = protoMapper;\n    this.anyTargetType = type;\n  }\n\n  @Override\n  public void init() {\n\n  }\n\n  @Override\n  public Object newMessage() {\n    return new PropertyWrapper<>();\n  }\n\n  @Override\n  @SuppressWarnings({\"rawtypes\", \"unchecked\"})\n  public void mergeFrom(InputEx input, Object message) throws IOException {\n    input.readFieldNumber();\n    String typeUrl = input.readString();\n\n    input.readFieldNumber();\n    byte[] bytes = input.readByteArray();\n\n    input.readFieldNumber();\n\n    if (message instanceof PropertyWrapper) {\n      if (typeUrl.startsWith(ProtoConst.PACK_SCHEMA)) {\n        ((PropertyWrapper) message).setValue(standardUnpack(typeUrl, bytes));\n      } else {\n        ((PropertyWrapper) message).setValue(jsonExtendMergeFrom(typeUrl, bytes));\n      }\n    } else if (message instanceof AnyEntry) {\n      ((AnyEntry) message).setTypeUrl(typeUrl);\n      ((AnyEntry) message).setValue(bytes);\n    }\n  }\n\n  public Object deserialize(InputEx input) throws IOException {\n    AnyEntry anyEntry = new AnyEntry();\n    input.mergeObject(anyEntry, this);\n\n    if (anyEntry.getTypeUrl().startsWith(ProtoConst.PACK_SCHEMA)) {\n      return standardUnpack(anyEntry.getTypeUrl(), anyEntry.getValue());\n    }\n\n    return jsonExtendMergeFrom(anyEntry.getTypeUrl(), anyEntry.getValue());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  protected Object standardUnpack(String typeUrl, byte[] bytes) throws IOException {\n    String msgCanonicalName = typeUrl.substring(ProtoConst.PACK_SCHEMA.length());\n    RootDeserializer<Object> valueDeserializer = rootDeserializers\n        .computeIfAbsent(msgCanonicalName, this::createRootDeserializerFromCanonicaName);\n    Object value = valueDeserializer.deserialize(bytes);\n    if (value instanceof Map) {\n      ((Map<String, Object>) value).put(ProtoConst.JSON_ID_NAME, valueDeserializer.getSchema().messageName());\n    }\n    return value;\n  }\n\n  protected RootDeserializer<Object> createRootDeserializerFromCanonicaName(String msgCanonicalName) {\n    Message message = protoMapper.getMessageFromCanonicaName(msgCanonicalName);\n    if (message == null) {\n      throw new IllegalStateException(\n          \"can not find proto message to create deserializer, name=\" + msgCanonicalName);\n    }\n\n    JavaType javaType = protoMapper.getAnyTypes()\n        .getOrDefault(msgCanonicalName, constructRuntimeType(ProtoConst.MAP_TYPE));\n    return protoMapper.createRootDeserializer(message, javaType);\n  }\n\n  protected Object jsonExtendMergeFrom(String typeUrl, byte[] bytes) throws IOException {\n    try {\n      return protoMapper.getJsonMapper()\n          .readValue(bytes, Class.forName(typeUrl.substring(ProtoConst.JSON_SCHEMA.length())));\n    } catch (ClassNotFoundException e) {\n      return protoMapper.getJsonMapper()\n          .readValue(bytes, constructRuntimeType(ProtoConst.OBJECT_TYPE));\n    }\n  }\n\n  private JavaType constructRuntimeType(JavaType defaultType) {\n    if (this.anyTargetType == null) {\n      return defaultType;\n    } else {\n      return TypeFactory.defaultInstance().constructType(anyTargetType);\n    }\n  }\n\n  protected String getInputActualTypeName(Object input) {\n    if (!(input instanceof Map)) {\n      return input.getClass().getSimpleName();\n    }\n\n    // @JsonTypeInfo(use = Id.NAME)\n    Object actualTypeName = ((Map<?, ?>) input).get(ProtoConst.JSON_ID_NAME);\n    if (actualTypeName instanceof String) {\n      return (String) actualTypeName;\n    }\n\n    return null;\n  }\n\n  /**\n   * <pre>\n   * if message is type of CustomGeneric&lt;User&gt;\n   * we can not get any information of \"User\" from message.getClass()\n   *\n   * when use with ServiceComb\n   * proto definition convert from swagger, the proto type will be \"CustomGenericUser\"\n   * is not match to \"CustomGeneric\"\n   * so message will be serialized with json schema\n   * </pre>\n   * @param output\n   * @param value\n   * @throws IOException\n   */\n  @Override\n  public void writeTo(OutputEx output, Object value) throws IOException {\n    String actualTypeName = getInputActualTypeName(value);\n    SchemaWriter<Object> entryWriter = actualTypeName == null ? this::jsonExtend : anyEntrySserializers\n        .computeIfAbsent(actualTypeName, n -> createEntryWriter(n, value));\n    entryWriter.writeTo(output, value);\n  }\n\n  private SchemaWriter<Object> createEntryWriter(String actualTypeName, Object _value) {\n    Message message = protoMapper.getProto().getMessage(actualTypeName);\n    if (message == null) {\n      // not standard, protobuf can not support or not define this type , just extend\n      return this::jsonExtend;\n    }\n\n    // standard pack\n    RootSerializer valueSerializer = protoMapper.createRootSerializer(message, _value.getClass());\n    String valueCanonicalName = message.getCanonicalName();\n    return (output, value) -> standardPack(output, value, valueCanonicalName, valueSerializer);\n  }\n\n  protected void standardPack(OutputEx output, Object message, String canonicalName, RootSerializer valueSerializer)\n      throws IOException {\n    output.writeString(keyTag, 1, ProtoConst.PACK_SCHEMA + canonicalName);\n\n    byte[] bytes = valueSerializer.serialize(message);\n    output.writeByteArray(valueTag, 1, bytes);\n  }\n\n  protected void jsonExtend(OutputEx output, Object input) throws IOException {\n    output.writeString(keyTag, 1, ProtoConst.JSON_SCHEMA + input.getClass().getName());\n\n    byte[] bytes = protoMapper.getJsonMapper().writeValueAsBytes(input);\n    output.writeByteArray(valueTag, 1, bytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/any/AnySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.any;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class AnySchema<T> extends FieldSchema<T> {\n  private final AnyEntrySchema anyEntrySchema;\n\n  private final Getter<T, Object> getter;\n\n  private final Setter<T, Object> setter;\n\n  public AnySchema(ProtoMapper protoMapper, Field protoField, PropertyDescriptor propertyDescriptor) {\n    super(protoField, propertyDescriptor.getJavaType());\n\n    this.anyEntrySchema = new AnyEntrySchema(protoMapper, null);\n    this.getter = propertyDescriptor.getGetter();\n    this.setter = propertyDescriptor.getSetter();\n  }\n\n  @Override\n  public final int mergeFrom(InputEx input, T message) throws IOException {\n    Object anyValue = anyEntrySchema.deserialize(input);\n    setter.set(message, anyValue);\n\n    return input.readFieldNumber();\n  }\n\n  @Override\n  public void getAndWriteTo(OutputEx output, T message) throws IOException {\n    Object anyEntry = getter.get(message);\n    if (anyEntry == null) {\n      return;\n    }\n\n    output.writeObject(tag, tagSize, anyEntry, anyEntrySchema);\n  }\n\n  @Override\n  public final void writeTo(OutputEx output, Object value) throws IOException {\n    output.writeObject(tag, tagSize, value, anyEntrySchema);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer;\n\nimport static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isWrapProperty;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.TypesUtil;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.SchemaManager;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.any.AnyEntrySchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.AnyRepeatedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.BytesRepeatedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.MessageRepeatedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.PropertyWrapperRepeatedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.StringRepeatedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools.impl.BoolNotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools.impl.BoolPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles.impl.DoubleNotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles.impl.DoublePackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.enums.EnumNotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.enums.EnumPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats.impl.FloatNotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats.impl.FloatPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.Fixed32NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.Fixed32PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.Int32NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.Int32PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.SFixed32NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.SFixed32PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.SInt32NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.SInt32PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.UInt32NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl.UInt32PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.Fixed64NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.Fixed64PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.Int64NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.Int64PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.SFixed64NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.SFixed64PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.SInt64NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.SInt64PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.UInt64NotPackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl.UInt64PackedReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.BoolReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.BytesReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.DoubleReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.EnumsReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.Fixed32ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.Fixed64ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.FloatReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.Int32ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.Int64ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.SFixed32ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.SFixed64ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.SInt32ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.SInt64ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.StringReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.UInt32ReadSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.UInt64ReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.ScalarFieldType;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DeserializerSchemaManager extends SchemaManager {\n  public DeserializerSchemaManager(ProtoMapper protoMapper) {\n    super(protoMapper);\n  }\n\n  public <T> RootDeserializer<T> createRootDeserializer(Message message, Map<String, Type> types) {\n    SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, types);\n    return new RootDeserializer<>(messageSchema);\n  }\n\n  @SuppressWarnings({\"rawtypes\", \"unchecked\"})\n  public <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {\n    if (ProtoUtils.isAnyMessage(message)) {\n      SchemaEx<Object> messageSchema = new AnyEntrySchema(protoMapper, type);\n      return new RootDeserializer(messageSchema);\n    }\n    JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n    SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, javaType);\n    return new RootDeserializer<>(messageSchema);\n  }\n\n  @Override\n  protected <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types) {\n    return new MessageReadSchema<>(protoMapper, message, types);\n  }\n\n  @Override\n  protected <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType) {\n    if (ProtoUtils.isWrapProperty(message) && javaType.getRawClass() != PropertyWrapper.class) {\n      Field protoField = message.getField(1);\n      if (javaType.isJavaLangObject()) {\n        javaType =\n            protoField.isRepeated() && !protoField.isMap() ? ProtoConst.LIST_TYPE\n                : ProtoConst.MAP_TYPE;\n      }\n\n      if (javaType.isPrimitive()) {\n        javaType = TypeFactory.defaultInstance()\n            .constructParametricType(PropertyWrapper.class, TypesUtil.primitiveJavaTypeToWrapper(javaType));\n      } else {\n        javaType = TypeFactory.defaultInstance().constructParametricType(PropertyWrapper.class, javaType);\n      }\n    }\n\n    if (javaType.isJavaLangObject()) {\n      javaType = ProtoConst.MAP_TYPE;\n    }\n\n    return new MessageReadSchema<>(protoMapper, message, javaType);\n  }\n\n  protected <T> FieldSchema<T> createScalarField(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (protoField.getType().isEnum()) {\n      return EnumsReadSchemas.create(protoField, propertyDescriptor);\n    }\n\n    switch ((ScalarFieldType) protoField.getType()) {\n      case INT32:\n        return Int32ReadSchemas.create(protoField, propertyDescriptor);\n      case UINT32:\n        return UInt32ReadSchemas.create(protoField, propertyDescriptor);\n      case SINT32:\n        return SInt32ReadSchemas.create(protoField, propertyDescriptor);\n      case FIXED32:\n        return Fixed32ReadSchemas.create(protoField, propertyDescriptor);\n      case SFIXED32:\n        return SFixed32ReadSchemas.create(protoField, propertyDescriptor);\n      case INT64:\n        return Int64ReadSchemas.create(protoField, propertyDescriptor);\n      case UINT64:\n        return UInt64ReadSchemas.create(protoField, propertyDescriptor);\n      case SINT64:\n        return SInt64ReadSchemas.create(protoField, propertyDescriptor);\n      case FIXED64:\n        return Fixed64ReadSchemas.create(protoField, propertyDescriptor);\n      case SFIXED64:\n        return SFixed64ReadSchemas.create(protoField, propertyDescriptor);\n      case FLOAT:\n        return FloatReadSchemas.create(protoField, propertyDescriptor);\n      case DOUBLE:\n        return DoubleReadSchemas.create(protoField, propertyDescriptor);\n      case BOOL:\n        return BoolReadSchemas.create(protoField, propertyDescriptor);\n      case STRING:\n        return StringReadSchemas.create(protoField, propertyDescriptor);\n      case BYTES:\n        return BytesReadSchemas.create(protoField, propertyDescriptor);\n      default:\n        throw new IllegalStateException(\"unknown proto field type: \" + protoField.getType());\n    }\n  }\n\n  @Override\n  protected <T> FieldSchema<T> createRepeatedSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n    boolean packed = ProtoUtils.isPacked(protoField);\n    if (protoField.getType().isEnum()) {\n      return packed ? EnumPackedReadSchemas.create(protoField, propertyDescriptor) :\n          EnumNotPackedReadSchemas.create(protoField, propertyDescriptor);\n    }\n\n    if (protoField.getType().isScalar()) {\n      switch ((ScalarFieldType) protoField.getType()) {\n        case INT32:\n          return packed ? Int32PackedReadSchemas.create(protoField, propertyDescriptor) :\n              Int32NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case UINT32:\n          return packed ? UInt32PackedReadSchemas.create(protoField, propertyDescriptor) :\n              UInt32NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case SINT32:\n          return packed ? SInt32PackedReadSchemas.create(protoField, propertyDescriptor) :\n              SInt32NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case FIXED32:\n          return packed ? Fixed32PackedReadSchemas.create(protoField, propertyDescriptor) :\n              Fixed32NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case SFIXED32:\n          return packed ? SFixed32PackedReadSchemas.create(protoField, propertyDescriptor) :\n              SFixed32NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case INT64:\n          return packed ? Int64PackedReadSchemas.create(protoField, propertyDescriptor) :\n              Int64NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case UINT64:\n          return packed ? UInt64PackedReadSchemas.create(protoField, propertyDescriptor) :\n              UInt64NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case SINT64:\n          return packed ? SInt64PackedReadSchemas.create(protoField, propertyDescriptor) :\n              SInt64NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case FIXED64:\n          return packed ? Fixed64PackedReadSchemas.create(protoField, propertyDescriptor) :\n              Fixed64NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case SFIXED64:\n          return packed ? SFixed64PackedReadSchemas.create(protoField, propertyDescriptor) :\n              SFixed64NotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case FLOAT:\n          return packed ? FloatPackedReadSchemas.create(protoField, propertyDescriptor) :\n              FloatNotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case DOUBLE:\n          return packed ? DoublePackedReadSchemas.create(protoField, propertyDescriptor) :\n              DoubleNotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case BOOL:\n          return packed ? BoolPackedReadSchemas.create(protoField, propertyDescriptor) :\n              BoolNotPackedReadSchemas.create(protoField, propertyDescriptor);\n        case STRING:\n          return StringRepeatedReadSchemas.create(protoField, propertyDescriptor);\n        case BYTES:\n          return BytesRepeatedReadSchemas.create(protoField, propertyDescriptor);\n        default:\n          ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n      }\n    }\n\n    if (ProtoUtils.isAnyField(protoField)) {\n      AnyEntrySchema anyEntrySchema = new AnyEntrySchema(protoMapper, null);\n      return AnyRepeatedReadSchemas.create(protoField, propertyDescriptor, anyEntrySchema);\n    }\n\n    if (protoField.getType().isMessage()) {\n      JavaType contentType = propertyDescriptor.getJavaType().getContentType();\n      if (contentType == null) {\n        contentType = ProtoConst.OBJECT_TYPE;\n      }\n      SchemaEx<Object> contentSchema = createMessageSchema((Message) protoField.getType(), contentType);\n      if (isWrapProperty((Message) protoField.getType())) {\n        return PropertyWrapperRepeatedReadSchemas.create(protoField, propertyDescriptor, contentSchema);\n      }\n\n      return MessageRepeatedReadSchemas.create(protoField, propertyDescriptor, contentSchema);\n    }\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.runtime.FieldMapEx;\nimport io.protostuff.runtime.FieldSchema;\nimport io.protostuff.runtime.RuntimeEnv;\nimport io.protostuff.runtime.RuntimeEnv.Instantiator;\n\n/**\n * <pre>\n * map.put(\"user\", new User())\n * root write from map, but user should write from pojo\n * so one schema should support dynamic and concrete logic at the same time\n * </pre>\n */\npublic class MessageReadSchema<T> implements SchemaEx<T> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(MessageReadSchema.class);\n\n  protected final ProtoMapper protoMapper;\n\n  protected final Message message;\n\n  private FieldMapEx<T> fieldMap;\n\n  private final Instantiator<T> instantiator;\n\n  private JavaType javaType;\n\n  Map<String, Type> argumentsTypes;\n\n  private boolean argumentsRoot = false;\n\n  @SuppressWarnings(\"unchecked\")\n  public MessageReadSchema(ProtoMapper protoMapper, Message message, Map<String, Type> argumentsTypes) {\n    this.argumentsRoot = true;\n    this.protoMapper = protoMapper;\n    this.message = message;\n    this.argumentsTypes = argumentsTypes;\n    this.instantiator = RuntimeEnv.newInstantiator((Class<T>) ProtoConst.MAP_TYPE.getRawClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public MessageReadSchema(ProtoMapper protoMapper, Message message, JavaType javaType) {\n    this.protoMapper = protoMapper;\n    this.message = message;\n    this.javaType = javaType;\n    if (javaType.isJavaLangObject() || Map.class.isAssignableFrom(javaType.getRawClass())) {\n      javaType = ProtoConst.MAP_TYPE;\n    }\n    this.instantiator = RuntimeEnv.newInstantiator((Class<T>) javaType.getRawClass());\n  }\n\n  public Message getMessage() {\n    return message;\n  }\n\n  @Override\n  public T newMessage() {\n    return instantiator.newInstance();\n  }\n\n  @Override\n  public String messageName() {\n    return message.getName();\n  }\n\n  public FieldMapEx<T> getFieldMap() {\n    return fieldMap;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public void init() {\n    if (argumentsRoot) {\n      this.fieldMap = (FieldMapEx<T>) protoMapper.getDeserializerSchemaManager()\n          .createMapFields(message, argumentsTypes);\n      return;\n    }\n\n    if (Map.class.isAssignableFrom(javaType.getRawClass())) {\n      this.fieldMap = (FieldMapEx<T>) protoMapper.getDeserializerSchemaManager()\n          .createMapFields(message);\n      return;\n    }\n\n    this.createFieldMap();\n  }\n\n  private void createFieldMap() {\n    DeserializerSchemaManager deserializerSchemaManager = protoMapper.getDeserializerSchemaManager();\n    BeanDescriptor beanDescriptor = protoMapper.getBeanDescriptorManager().getOrCreateBeanDescriptor(javaType);\n\n    List<FieldSchema<T>> fieldSchemas = new ArrayList<>();\n    for (PropertyDescriptor propertyDescriptor : beanDescriptor.getPropertyDescriptors().values()) {\n      Field protoField = message.getField(propertyDescriptor.getName());\n      if (protoField == null) {\n        LOGGER.info(\"java field {}:{} not exist in proto message {}, ignore it.\",\n            beanDescriptor.getJavaType().getRawClass().getName(),\n            propertyDescriptor.getName(), message.getCanonicalName());\n        continue;\n      }\n      if (propertyDescriptor.getSetter() == null) {\n        LOGGER.info(\"no setter for java field {}:{} in proto message {}, ignore it.\",\n            beanDescriptor.getJavaType().getRawClass().getName(),\n            propertyDescriptor.getName(), message.getCanonicalName());\n        continue;\n      }\n\n      FieldSchema<T> fieldSchema = deserializerSchemaManager.createSchemaField(protoField, propertyDescriptor);\n      fieldSchemas.add(fieldSchema);\n    }\n\n    this.fieldMap = FieldMapEx.createFieldMap(fieldSchemas);\n  }\n\n  @Override\n  public void mergeFrom(InputEx input, T message) throws IOException {\n    FieldSchema<T> fieldSchema = null;\n    try {\n      for (int n = input.readFieldNumber(); n != 0; ) {\n        fieldSchema = fieldMap.getFieldByNumber(n);\n        if (fieldSchema != null) {\n          n = fieldSchema.mergeFrom(input, message);\n          continue;\n        }\n\n        input.handleUnknownField(n);\n        n = input.readFieldNumber();\n      }\n    } catch (Throwable e) {\n      if (fieldSchema != null) {\n        Field protoField = fieldSchema.getProtoField();\n        LOGGER.error(\"Failed to mergeFrom, field={}:{}, type={}, error {}\",\n            protoField.getType().getCanonicalName(),\n            protoField.getName(),\n            protoField.getTypeName(),\n            e.getMessage());\n      }\n      throw e;\n    }\n  }\n\n  @Override\n  public void writeTo(OutputEx output, Object value) throws IOException {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/AbstractPrimitiveReaders.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated;\n\nimport io.protostuff.compiler.model.Field;\n\npublic abstract class AbstractPrimitiveReaders<PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> extends\n    AbstractReaders<PRIMITIVE_WRAPPER> {\n  public RepeatedReader<PrimitiveArrayBuilderWrapper<PRIMITIVE_ARRAY>> primitiveArrayReader;\n\n  @SuppressWarnings(\"unchecked\")\n  public AbstractPrimitiveReaders(Field protoField) {\n    super(protoField);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/AbstractReaders.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated;\n\nimport static org.apache.servicecomb.foundation.common.utils.ReflectUtils.getFieldArgument;\n\nimport java.util.Collection;\n\nimport io.protostuff.compiler.model.Field;\n\npublic abstract class AbstractReaders<T> {\n  protected final Field protoField;\n\n  protected final int fieldNumber;\n\n  public RepeatedReader<Collection<T>> collectionReader;\n\n  public final Class<T[]> arrayClass;\n\n  @SuppressWarnings(\"unchecked\")\n  public AbstractReaders(Field protoField) {\n    this(protoField, null);\n  }\n\n  public AbstractReaders(Field protoField, Class<T[]> arrayClass) {\n    this.protoField = protoField;\n    this.fieldNumber = protoField.getTag();\n\n    if (arrayClass == null) {\n      arrayClass = getFieldArgument(this.getClass(), \"arrayClass\");\n    }\n    this.arrayClass = arrayClass;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/PrimitiveArrayBuilderWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\npublic class PrimitiveArrayBuilderWrapper<T> {\n  private final PrimitiveArrayBuilder<T> builder;\n\n  private T array;\n\n  public PrimitiveArrayBuilderWrapper(PrimitiveArrayBuilder<T> builder) {\n    this.builder = builder;\n  }\n\n  public T getArray() {\n    return array;\n  }\n\n  public void setArray(T array) {\n    this.array = array;\n  }\n\n  public PrimitiveArrayBuilder<T> getBuilder() {\n    return builder;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/RepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated;\n\nimport java.io.IOException;\nimport java.lang.reflect.Array;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class RepeatedReadSchemas {\n  public static <T, ELE_TYPE> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AbstractReaders<ELE_TYPE> readers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (readers.arrayClass.isAssignableFrom(javaType.getRawClass())) {\n      return new ArrayRepeatedSchema<>(protoField, propertyDescriptor, readers);\n    }\n\n    if (Collection.class.isAssignableFrom(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new CollectionRepeatedSchema<>(protoField, propertyDescriptor, readers);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, javaType);\n    return null;\n  }\n\n  static class AbstractRepeatedSchema<T, ELE_TYPE> extends FieldSchema<T> {\n    protected final AbstractReaders<ELE_TYPE> readers;\n\n    public AbstractRepeatedSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractReaders<ELE_TYPE> readers) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.readers = readers;\n    }\n  }\n\n  static class CollectionRepeatedSchema<T, ELE_TYPE> extends AbstractRepeatedSchema<T, ELE_TYPE> {\n    private final Getter<T, Collection<ELE_TYPE>> getter;\n\n    private final Setter<T, Collection<ELE_TYPE>> setter;\n\n    public CollectionRepeatedSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractReaders<ELE_TYPE> readers) {\n      super(protoField, propertyDescriptor, readers);\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public final int mergeFrom(InputEx input, T message) throws IOException {\n      Collection<ELE_TYPE> collection = getter.get(message);\n      if (collection == null) {\n        if (Set.class.equals(javaType.getRawClass())) {\n          collection = new HashSet<>();\n        } else {\n          collection = new ArrayList<>();\n        }\n        setter.set(message, collection);\n      }\n\n      return readers.collectionReader.read(input, collection);\n    }\n  }\n\n  static class ArrayRepeatedSchema<T, ELE_TYPE> extends AbstractRepeatedSchema<T, ELE_TYPE> {\n    private final Getter<T, ELE_TYPE[]> getter;\n\n    private final Setter<T, ELE_TYPE[]> setter;\n\n    public ArrayRepeatedSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractReaders<ELE_TYPE> readers) {\n      super(protoField, propertyDescriptor, readers);\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public final int mergeFrom(InputEx input, T message) throws IOException {\n      ELE_TYPE[] array = getter.get(message);\n      Collection<ELE_TYPE> collection = array == null ? new ArrayList<>() : new ArrayList<>(Arrays.asList(array));\n      int fieldNumber = readers.collectionReader.read(input, collection);\n\n      ELE_TYPE[] newArray = (ELE_TYPE[]) Array.newInstance(readers.arrayClass.getComponentType(), collection.size());\n      setter.set(message, collection.toArray(newArray));\n      return fieldNumber;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/RepeatedReader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated;\n\nimport java.io.IOException;\n\nimport io.protostuff.InputEx;\n\npublic interface RepeatedReader<T> {\n  int read(InputEx input, T value) throws IOException;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/AnyRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.any.AnyEntrySchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class AnyRepeatedReadSchemas {\n  private static class MessageReaders extends AbstractReaders<Object> {\n    public MessageReaders(Field protoField, AnyEntrySchema anyEntrySchema) {\n      super(protoField);\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          Object value = anyEntrySchema.deserialize(input);\n          collection.add(value);\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AnyEntrySchema anyEntrySchema) {\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, new MessageReaders(protoField, anyEntrySchema));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/BytesRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BytesRepeatedReadSchemas {\n  private static class BytesReaders extends AbstractReaders<byte[]> {\n    public BytesReaders(Field protoField) {\n      super(protoField);\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readByteArray());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, new BytesReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/MessageRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport io.protostuff.SchemaReader;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class MessageRepeatedReadSchemas {\n  private static class MessageReaders extends AbstractReaders<Object> {\n    public MessageReaders(Field protoField, SchemaReader<Object> elementSchema) {\n      super(protoField);\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          Object value = input.mergeObject(null, elementSchema);\n          collection.add(value);\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      SchemaReader<Object> elementSchema) {\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, new MessageReaders(protoField, elementSchema));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/PropertyWrapperRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport io.protostuff.SchemaReader;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class PropertyWrapperRepeatedReadSchemas {\n  private static class PropertyWrapperReaders extends AbstractReaders<Object> {\n    public PropertyWrapperReaders(Field protoField, SchemaReader<Object> elementSchema) {\n      super(protoField);\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          PropertyWrapper<Object> wrapper = new PropertyWrapper<>();\n          input.mergeObject(wrapper, elementSchema);\n          collection.add(wrapper.getValue());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      SchemaReader<Object> elementSchema) {\n    return RepeatedReadSchemas\n        .create(protoField, propertyDescriptor, new PropertyWrapperReaders(protoField, elementSchema));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/StringRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class StringRepeatedReadSchemas {\n  private static class StringReaders extends AbstractReaders<String> {\n    public StringReaders(Field protoField) {\n      super(protoField);\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readString());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, new StringReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/bools/BoolRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.PrimitiveArrayBuilderWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolRepeatedReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AbstractPrimitiveReaders<boolean[], Boolean> readers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (boolean[].class.equals(javaType.getRawClass())) {\n      return new BoolPrimitiveArray<>(protoField, propertyDescriptor, readers);\n    }\n\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, readers);\n  }\n\n  static class BoolPrimitiveArray<T> extends FieldSchema<T> {\n    private final Getter<T, boolean[]> getter;\n\n    private final Setter<T, boolean[]> setter;\n\n    private final AbstractPrimitiveReaders<boolean[], Boolean> readers;\n\n    public BoolPrimitiveArray(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractPrimitiveReaders<boolean[], Boolean> readers) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n      this.readers = readers;\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      PrimitiveArrayBuilderWrapper<boolean[]> builderWrapper = new PrimitiveArrayBuilderWrapper<>(\n          input.getArrayBuilders().getBooleanBuilder());\n\n      int fieldNumber = readers.primitiveArrayReader.read(input, builderWrapper);\n      boolean[] newValue = builderWrapper.getArray();\n      newValue = mergeArray(getter.get(message), newValue);\n      setter.set(message, newValue);\n\n      return fieldNumber;\n    }\n\n    private boolean[] mergeArray(boolean[] oldValue, boolean[] newValue) {\n      if (oldValue == null || oldValue.length == 0) {\n        return newValue;\n      }\n\n      return concatArray(oldValue, newValue);\n    }\n\n    private boolean[] concatArray(boolean[] oldValue, boolean[] newValue) {\n      int len1 = oldValue.length;\n      int len2 = newValue.length;\n      boolean[] result = Arrays.copyOf(oldValue, len1 + len2);\n      System.arraycopy(newValue, 0, result, len1, len2);\n      return result;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/bools/impl/BoolNotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools.BoolRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolNotPackedReadSchemas {\n  private static class BoolNotPackedReaders extends AbstractPrimitiveReaders<boolean[], Boolean> {\n    public BoolNotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<boolean[]> builder = builderWrapper.getBuilder();\n        boolean[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readBool();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readBool());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return BoolRepeatedReadSchemas.create(protoField, propertyDescriptor, new BoolNotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/bools/impl/BoolPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.bools.BoolRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolPackedReadSchemas {\n  private static class BoolPackedReaders extends AbstractPrimitiveReaders<boolean[], Boolean> {\n    public BoolPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<boolean[]> builder = builderWrapper.getBuilder();\n        boolean[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedBool();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedBool());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return BoolRepeatedReadSchemas.create(protoField, propertyDescriptor, new BoolPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/doubles/DoubleRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.PrimitiveArrayBuilderWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoubleRepeatedReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AbstractPrimitiveReaders<double[], Double> readers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (double[].class.equals(javaType.getRawClass())) {\n      return new PrimitiveArraySchema<>(protoField, propertyDescriptor, readers);\n    }\n\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, readers);\n  }\n\n  static class PrimitiveArraySchema<T> extends FieldSchema<T> {\n    private final Getter<T, double[]> getter;\n\n    private final Setter<T, double[]> setter;\n\n    private final AbstractPrimitiveReaders<double[], Double> readers;\n\n    public PrimitiveArraySchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractPrimitiveReaders<double[], Double> readers) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n      this.readers = readers;\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      PrimitiveArrayBuilderWrapper<double[]> builderWrapper = new PrimitiveArrayBuilderWrapper<>(\n          input.getArrayBuilders().getDoubleBuilder());\n\n      int fieldNumber = readers.primitiveArrayReader.read(input, builderWrapper);\n      double[] newValue = builderWrapper.getArray();\n      newValue = mergeArray(getter.get(message), newValue);\n      setter.set(message, newValue);\n\n      return fieldNumber;\n    }\n\n    public double[] mergeArray(double[] oldValue, double[] newValue) {\n      if (oldValue == null || oldValue.length == 0) {\n        return newValue;\n      }\n\n      return concatArray(oldValue, newValue);\n    }\n\n    private double[] concatArray(double[] oldValue, double[] newValue) {\n      int len1 = oldValue.length;\n      int len2 = newValue.length;\n      double[] result = Arrays.copyOf(oldValue, len1 + len2);\n      System.arraycopy(newValue, 0, result, len1, len2);\n      return result;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/doubles/impl/DoubleNotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles.DoubleRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoubleNotPackedReadSchemas {\n  private static class NotPackedReaders extends AbstractPrimitiveReaders<double[], Double> {\n    public NotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<double[]> builder = builderWrapper.getBuilder();\n        double[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readDouble();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readDouble());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return DoubleRepeatedReadSchemas.create(protoField, propertyDescriptor, new NotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/doubles/impl/DoublePackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.doubles.DoubleRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoublePackedReadSchemas {\n  private static class DoublePackedReaders extends AbstractPrimitiveReaders<double[], Double> {\n    public DoublePackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<double[]> builder = builderWrapper.getBuilder();\n        double[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedDouble();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedDouble());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return DoubleRepeatedReadSchemas.create(protoField, propertyDescriptor, new DoublePackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/enums/EnumNotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.enums;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.EnumMeta;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class EnumNotPackedReadSchemas {\n  private static class EnumNotPackedReaders extends AbstractReaders<Enum<?>> {\n    private final EnumMeta enumMeta;\n\n    public EnumNotPackedReaders(Field protoField, JavaType javaType) {\n      super(protoField, EnumSchemaUtils.constructEnumArrayClass(javaType));\n      this.enumMeta = new EnumMeta(protoField, javaType.getContentType());\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          int value = input.readEnum();\n          Enum<?> enumValue = enumMeta.getEnumByValue(value);\n          if (enumValue == null) {\n            throw new IllegalStateException(\n                String.format(\"invalid enum value %d for %s, proto field=%s:%s\",\n                    value,\n                    javaType.getRawClass().getName(),\n                    ((Type) protoField.getParent()).getCanonicalName(),\n                    protoField.getName()));\n          }\n\n          collection.add(enumValue);\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  private static class EnumIntNotPackedSchema<T> extends FieldSchema<T> {\n    private final Getter<T, Collection<Integer>> getter;\n\n    private final Setter<T, Collection<Integer>> setter;\n\n    public EnumIntNotPackedSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      Collection<Integer> collection = getter.get(message);\n      if (collection == null) {\n        collection = new ArrayList<>();\n        setter.set(message, collection);\n      }\n\n      while (true) {\n        int value = input.readEnum();\n        collection.add(value);\n\n        int fieldNumber = input.readFieldNumber();\n        if (fieldNumber != this.fieldNumber) {\n          return fieldNumber;\n        }\n      }\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (javaType.isJavaLangObject()) {\n      return new EnumIntNotPackedSchema<>(protoField, propertyDescriptor);\n    }\n\n    return RepeatedReadSchemas\n        .create(protoField, propertyDescriptor, new EnumNotPackedReaders(protoField, propertyDescriptor.getJavaType()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/enums/EnumPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.enums;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.EnumMeta;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class EnumPackedReadSchemas {\n  private static class EnumPackedReaders extends AbstractReaders<Enum<?>> {\n    private final EnumMeta enumMeta;\n\n    public EnumPackedReaders(Field protoField, JavaType javaType) {\n      super(protoField, EnumSchemaUtils.constructEnumArrayClass(javaType));\n      this.enumMeta = new EnumMeta(protoField, javaType.getContentType());\n\n      collectionReader = (input, collection) -> {\n        while (true) {\n          int value = input.readPackedEnum();\n          Enum<?> enumValue = enumMeta.getEnumByValue(value);\n          if (enumValue == null) {\n            throw new IllegalStateException(\n                String.format(\"invalid enum value %d for %s, proto field=%s:%s\",\n                    value,\n                    javaType.getRawClass().getName(),\n                    ((Type) protoField.getParent()).getCanonicalName(),\n                    protoField.getName()));\n          }\n\n          collection.add(enumValue);\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  private static class EnumIntPackedSchema<T> extends FieldSchema<T> {\n    private final Getter<T, Collection<Integer>> getter;\n\n    private final Setter<T, Collection<Integer>> setter;\n\n    public EnumIntPackedSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      Collection<Integer> collection = getter.get(message);\n      if (collection == null) {\n        collection = new ArrayList<>();\n        setter.set(message, collection);\n      }\n\n      while (true) {\n        int value = input.readPackedEnum();\n        collection.add(value);\n\n        int fieldNumber = input.readFieldNumber();\n        if (fieldNumber != this.fieldNumber) {\n          return fieldNumber;\n        }\n      }\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (javaType.isJavaLangObject()) {\n      return new EnumIntPackedSchema<>(protoField, propertyDescriptor);\n    }\n\n    return RepeatedReadSchemas\n        .create(protoField, propertyDescriptor, new EnumPackedReaders(protoField, propertyDescriptor.getJavaType()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/enums/EnumSchemaUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.enums;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic final class EnumSchemaUtils {\n  private EnumSchemaUtils() {\n  }\n\n  public static <T> T constructEnumArrayClass(JavaType javaType) {\n    if (javaType.isArrayType()) {\n      return ReflectUtils.constructArrayType(javaType.getContentType().getRawClass());\n    }\n\n    return ReflectUtils.constructArrayType(Object.class);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/floats/FloatRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.PrimitiveArrayBuilderWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatRepeatedReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AbstractPrimitiveReaders<float[], Float> readers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (float[].class.equals(javaType.getRawClass())) {\n      return new FloatPrimitiveArraySchema<>(protoField, propertyDescriptor, readers);\n    }\n\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, readers);\n  }\n\n  static class FloatPrimitiveArraySchema<T> extends FieldSchema<T> {\n    private final Getter<T, float[]> getter;\n\n    private final Setter<T, float[]> setter;\n\n    private final AbstractPrimitiveReaders<float[], Float> readers;\n\n    public FloatPrimitiveArraySchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractPrimitiveReaders<float[], Float> readers) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n      this.readers = readers;\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      PrimitiveArrayBuilderWrapper<float[]> builderWrapper = new PrimitiveArrayBuilderWrapper<>(\n          input.getArrayBuilders().getFloatBuilder());\n\n      int fieldNumber = readers.primitiveArrayReader.read(input, builderWrapper);\n      float[] newValue = builderWrapper.getArray();\n      newValue = mergeArray(getter.get(message), newValue);\n      setter.set(message, newValue);\n\n      return fieldNumber;\n    }\n\n    public float[] mergeArray(float[] oldValue, float[] newValue) {\n      if (oldValue == null || oldValue.length == 0) {\n        return newValue;\n      }\n\n      return concatArray(oldValue, newValue);\n    }\n\n    private float[] concatArray(float[] oldValue, float[] newValue) {\n      int len1 = oldValue.length;\n      int len2 = newValue.length;\n      float[] result = Arrays.copyOf(oldValue, len1 + len2);\n      System.arraycopy(newValue, 0, result, len1, len2);\n      return result;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/floats/impl/FloatNotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats.FloatRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatNotPackedReadSchemas {\n  private static class FloatNotPackedReaders extends AbstractPrimitiveReaders<float[], Float> {\n    public FloatNotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<float[]> builder = builderWrapper.getBuilder();\n        float[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readFloat();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readFloat());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return FloatRepeatedReadSchemas.create(protoField, propertyDescriptor, new FloatNotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/floats/impl/FloatPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.floats.FloatRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatPackedReadSchemas {\n  private static class FloatPackedReaders extends AbstractPrimitiveReaders<float[], Float> {\n    public FloatPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<float[]> builder = builderWrapper.getBuilder();\n        float[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedFloat();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedFloat());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return FloatRepeatedReadSchemas.create(protoField, propertyDescriptor, new FloatPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/IntRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.PrimitiveArrayBuilderWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class IntRepeatedReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AbstractPrimitiveReaders<int[], Integer> readers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (int[].class.equals(javaType.getRawClass())) {\n      return new IntPrimitiveArraySchema<>(protoField, propertyDescriptor, readers);\n    }\n\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, readers);\n  }\n\n  static class IntPrimitiveArraySchema<T> extends FieldSchema<T> {\n    private final Getter<T, int[]> getter;\n\n    private final Setter<T, int[]> setter;\n\n    private final AbstractPrimitiveReaders<int[], Integer> readers;\n\n    public IntPrimitiveArraySchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractPrimitiveReaders<int[], Integer> readers) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n      this.readers = readers;\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      PrimitiveArrayBuilderWrapper<int[]> builderWrapper = new PrimitiveArrayBuilderWrapper<>(\n          input.getArrayBuilders().getIntBuilder());\n\n      int fieldNumber = readers.primitiveArrayReader.read(input, builderWrapper);\n      int[] newValue = builderWrapper.getArray();\n      newValue = mergeArray(getter.get(message), newValue);\n      setter.set(message, newValue);\n\n      return fieldNumber;\n    }\n\n    public int[] mergeArray(int[] oldValue, int[] newValue) {\n      if (oldValue == null || oldValue.length == 0) {\n        return newValue;\n      }\n\n      return concatArray(oldValue, newValue);\n    }\n\n    private int[] concatArray(int[] oldValue, int[] newValue) {\n      int len1 = oldValue.length;\n      int len2 = newValue.length;\n      int[] result = Arrays.copyOf(oldValue, len1 + len2);\n      System.arraycopy(newValue, 0, result, len1, len2);\n      return result;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/Fixed32NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed32NotPackedReadSchemas {\n  private static class NotPackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public NotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readFixed32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readFixed32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new NotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/Fixed32PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed32PackedReadSchemas {\n  private static class Fixed32PackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public Fixed32PackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedFixed32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedFixed32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new Fixed32PackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/Int32NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int32NotPackedReadSchemas {\n  private static class Int32NotPackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public Int32NotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readInt32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readInt32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new Int32NotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/Int32PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int32PackedReadSchemas {\n  private static class Int32PackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public Int32PackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedInt32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedInt32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new Int32PackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/SFixed32NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed32NotPackedReadSchemas {\n  private static class NotPackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public NotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readSFixed32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readSFixed32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new NotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/SFixed32PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed32PackedReadSchemas {\n  private static class SFixed32PackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public SFixed32PackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedSFixed32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedSFixed32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new SFixed32PackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/SInt32NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt32NotPackedReadSchemas {\n  private static class SInt32NotPackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public SInt32NotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readSInt32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readSInt32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new SInt32NotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/SInt32PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt32PackedReadSchemas {\n  private static class SInt32PackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public SInt32PackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedSInt32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedSInt32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new SInt32PackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/UInt32NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt32NotPackedReadSchemas {\n  private static class UInt32NotPackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public UInt32NotPackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readUInt32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readUInt32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new UInt32NotPackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/ints/impl/UInt32PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.ints.IntRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt32PackedReadSchemas {\n  private static class UInt32PackedReaders extends AbstractPrimitiveReaders<int[], Integer> {\n    public UInt32PackedReaders(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<int[]> builder = builderWrapper.getBuilder();\n        int[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedUInt32();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedUInt32());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return IntRepeatedReadSchemas.create(protoField, propertyDescriptor, new UInt32PackedReaders(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/LongRepeatedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.PrimitiveArrayBuilderWrapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.RepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class LongRepeatedReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      AbstractPrimitiveReaders<long[], Long> readers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (long[].class.equals(javaType.getRawClass())) {\n      return new LongPrimitiveArraySchema<>(protoField, propertyDescriptor, readers);\n    }\n\n    return RepeatedReadSchemas.create(protoField, propertyDescriptor, readers);\n  }\n\n  static class LongPrimitiveArraySchema<T> extends FieldSchema<T> {\n    private final Getter<T, long[]> getter;\n\n    private final Setter<T, long[]> setter;\n\n    private final AbstractPrimitiveReaders<long[], Long> readers;\n\n    public LongPrimitiveArraySchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractPrimitiveReaders<long[], Long> readers) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.getter = propertyDescriptor.getGetter();\n      this.setter = propertyDescriptor.getSetter();\n      this.readers = readers;\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      PrimitiveArrayBuilderWrapper<long[]> builderWrapper = new PrimitiveArrayBuilderWrapper<>(\n          input.getArrayBuilders().getLongBuilder());\n\n      int fieldNumber = readers.primitiveArrayReader.read(input, builderWrapper);\n      long[] newValue = builderWrapper.getArray();\n      newValue = mergeArray(getter.get(message), newValue);\n      setter.set(message, newValue);\n\n      return fieldNumber;\n    }\n\n    public long[] mergeArray(long[] oldValue, long[] newValue) {\n      if (oldValue == null || oldValue.length == 0) {\n        return newValue;\n      }\n\n      return concatArray(oldValue, newValue);\n    }\n\n    private long[] concatArray(long[] oldValue, long[] newValue) {\n      int len1 = oldValue.length;\n      int len2 = newValue.length;\n      long[] result = Arrays.copyOf(oldValue, len1 + len2);\n      System.arraycopy(newValue, 0, result, len1, len2);\n      return result;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/Fixed64NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed64NotPackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readFixed64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readFixed64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/Fixed64PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed64PackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedFixed64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedFixed64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/Int64NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int64NotPackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readInt64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readInt64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/Int64PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int64PackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedInt64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedInt64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/SFixed64NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed64NotPackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readSFixed64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readSFixed64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/SFixed64PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed64PackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedSFixed64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedSFixed64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/SInt64NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt64NotPackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readSInt64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readSInt64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/SInt64PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt64PackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedSInt64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedSInt64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/UInt64NotPackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt64NotPackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readUInt64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readUInt64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/repeated/impl/longs/impl/UInt64PackedReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.AbstractPrimitiveReaders;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.repeated.impl.longs.LongRepeatedReadSchemas;\n\nimport com.fasterxml.jackson.databind.util.PrimitiveArrayBuilder;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt64PackedReadSchemas {\n  private static class Readers extends AbstractPrimitiveReaders<long[], Long> {\n    public Readers(Field protoField) {\n      super(protoField);\n\n      this.primitiveArrayReader = (input, builderWrapper) -> {\n        PrimitiveArrayBuilder<long[]> builder = builderWrapper.getBuilder();\n        long[] chunk = builder.resetAndStart();\n        int ix = 0;\n\n        while (true) {\n          if (ix >= chunk.length) {\n            chunk = builder.appendCompletedChunk(chunk, ix);\n            ix = 0;\n          }\n          chunk[ix++] = input.readPackedUInt64();\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            builderWrapper.setArray(builder.completeAndClearBuffer(chunk, ix));\n            return fieldNumber;\n          }\n        }\n      };\n\n      this.collectionReader = (input, collection) -> {\n        while (true) {\n          collection.add(input.readPackedUInt64());\n\n          int fieldNumber = input.readFieldNumber();\n          if (fieldNumber != this.fieldNumber) {\n            return fieldNumber;\n          }\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return LongRepeatedReadSchemas.create(protoField, propertyDescriptor, new Readers(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/AbstractScalarReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class AbstractScalarReadSchemas {\n  abstract static class AbstractIntSchema<T> extends FieldSchema<T> {\n    protected final Setter<T, Object> setter;\n\n    public AbstractIntSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n  }\n\n  abstract static class AbstractLongSchema<T> extends FieldSchema<T> {\n    protected final Setter<T, Object> setter;\n\n    public AbstractLongSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/BoolReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.BoolSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (boolean.class.equals(javaType.getRawClass())) {\n      return new BooleanPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Boolean.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new BooleanSchema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class BooleanSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Boolean> setter;\n\n    public BooleanSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      boolean value = input.readBool();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class BooleanPrimitiveSchema<T> extends FieldSchema<T> {\n    private final BoolSetter<T> setter;\n\n    public BooleanPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      boolean value = input.readBool();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/BytesReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BytesReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (byte[].class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new BytesSchema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class BytesSchema<T> extends FieldSchema<T> {\n    private final Setter<T, byte[]> setter;\n\n    public BytesSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      byte[] value = input.readByteArray();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/DoubleReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.DoubleSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoubleReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (double.class.equals(javaType.getRawClass())) {\n      return new DoublePrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Double.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new DoubleSchema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class DoubleSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Double> setter;\n\n    public DoubleSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      double value = input.readDouble();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class DoublePrimitiveSchema<T> extends FieldSchema<T> {\n    private final DoubleSetter<T> setter;\n\n    public DoublePrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      double value = input.readDouble();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/EnumsReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.base.DynamicEnum;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.EnumMeta;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class EnumsReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (javaType.isEnumType()) {\n      return new EnumSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new IntEnumSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (int.class.equals(javaType.getRawClass())) {\n      return new IntPrimitiveEnumSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (javaType.isTypeOrSubTypeOf(DynamicEnum.class)) {\n      return new DynamicEnumSchema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class EnumSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Enum<?>> setter;\n\n    private final EnumMeta enumMeta;\n\n    public EnumSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n      enumMeta = new EnumMeta(protoField, javaType);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      Enum<?> enumValue = enumMeta.getEnumByValue(value);\n      if (enumValue != null) {\n        setter.set(message, enumValue);\n        return input.readFieldNumber();\n      }\n\n      throw new IllegalStateException(\n          String.format(\"invalid enum value %d for %s, proto field=%s:%s\",\n              value,\n              javaType.getRawClass().getName(),\n              ((Type) protoField.getParent()).getCanonicalName(),\n              protoField.getName()));\n    }\n  }\n\n  private static class DynamicEnumSchema<T> extends FieldSchema<T> {\n    public DynamicEnumSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      throw new IllegalStateException(\n          String.format(\"currently, protobuf not support dynamic enum, type=%s, proto field=%s:%s\",\n              javaType.getRawClass().getName(),\n              ((Type) protoField.getParent()).getCanonicalName(),\n              protoField.getName()));\n    }\n  }\n\n  private static class IntEnumSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Integer> setter;\n\n    public IntEnumSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class IntPrimitiveEnumSchema<T> extends FieldSchema<T> {\n    private final IntSetter<T> setter;\n\n    public IntPrimitiveEnumSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/Fixed32ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractIntSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed32ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (int.class.equals(javaType.getRawClass())) {\n      return new Fixed32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new Fixed32Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class Fixed32Schema<T> extends AbstractIntSchema<T> {\n    public Fixed32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readFixed32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class Fixed32PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final IntSetter<T> setter;\n\n    public Fixed32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readFixed32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/Fixed64ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.LongSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractLongSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed64ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (long.class.equals(javaType.getRawClass())) {\n      return new Fixed64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new Fixed64Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class Fixed64Schema<T> extends AbstractLongSchema<T> {\n    public Fixed64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readFixed64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class Fixed64PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final LongSetter<T> setter;\n\n    public Fixed64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readFixed64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/FloatReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.FloatSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (float.class.equals(javaType.getRawClass())) {\n      return new FloatPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Float.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new FloatSchema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class FloatSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Float> setter;\n\n    public FloatSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      float value = input.readFloat();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class FloatPrimitiveSchema<T> extends FieldSchema<T> {\n    private final FloatSetter<T> setter;\n\n    public FloatPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      float value = input.readFloat();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/Int32ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.ByteSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ShortSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractIntSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int32ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (int.class.equals(javaType.getRawClass())) {\n      return new IntFieldIntPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (short.class.equals(javaType.getRawClass())) {\n      return new ShortFieldIntPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (byte.class.equals(javaType.getRawClass())) {\n      return new ByteFieldIntPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(javaType.getRawClass()) || Byte.class.equals(javaType.getRawClass()) || Short.class\n        .equals(javaType.getRawClass()) || javaType\n        .isJavaLangObject()) {\n      return new Int32Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class Int32Schema<T> extends AbstractIntSchema<T> {\n    public Int32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      if (Byte.class.equals(javaType.getRawClass())) {\n        setter.set(message, (byte) value);\n      } else if (Short.class.equals(javaType.getRawClass())) {\n        setter.set(message, (short) value);\n      } else {\n        setter.set(message, value);\n      }\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class IntFieldIntPrimitiveSchema<T> extends FieldSchema<T> {\n    protected final IntSetter<T> setter;\n\n    public IntFieldIntPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class ShortFieldIntPrimitiveSchema<T> extends FieldSchema<T> {\n    protected final ShortSetter<T> setter;\n\n    public ShortFieldIntPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      setter.set(message, (short) value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class ByteFieldIntPrimitiveSchema<T> extends FieldSchema<T> {\n    protected final ByteSetter<T> setter;\n\n    public ByteFieldIntPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readInt32();\n      setter.set(message, (byte) value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/Int64ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\nimport java.time.Instant;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.ZoneOffset;\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.LongSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractLongSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int64ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (long.class.equals(javaType.getRawClass())) {\n      return new LongFiledLongPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new Int64Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class Int64Schema<T> extends AbstractLongSchema<T> {\n    public Int64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readInt64();\n      if (Date.class.equals(javaType.getRawClass())) {\n        setter.set(message, new Date(value));\n      } else if (LocalDate.class.equals(javaType.getRawClass())) {\n        setter.set(message, LocalDate.ofEpochDay(value));\n      } else if (LocalDateTime.class.equals(javaType.getRawClass())) {\n        setter.set(message, LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC));\n      } else {\n        setter.set(message, value);\n      }\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class LongFiledLongPrimitiveSchema<T> extends FieldSchema<T> {\n    protected final LongSetter<T> setter;\n\n    public LongFiledLongPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readInt64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/SFixed32ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractIntSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed32ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (int.class.equals(javaType.getRawClass())) {\n      return new SFixed32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new SFixed32Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class SFixed32Schema<T> extends AbstractIntSchema<T> {\n    public SFixed32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readSFixed32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class SFixed32PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final IntSetter<T> setter;\n\n    public SFixed32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readSFixed32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/SFixed64ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.LongSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractLongSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed64ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (long.class.equals(javaType.getRawClass())) {\n      return new SFixed64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new SFixed64Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class SFixed64Schema<T> extends AbstractLongSchema<T> {\n    public SFixed64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readSFixed64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class SFixed64PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final LongSetter<T> setter;\n\n    public SFixed64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readSFixed64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/SInt32ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.ByteSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ShortSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractIntSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt32ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (int.class.equals(javaType.getRawClass())) {\n      return new SInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (short.class.equals(javaType.getRawClass())) {\n      return new ShortFieldSInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (byte.class.equals(javaType.getRawClass())) {\n      return new ByteFieldSInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(javaType.getRawClass())\n        || Byte.class.equals(javaType.getRawClass())\n        || Short.class.equals(javaType.getRawClass())\n        || javaType.isJavaLangObject()) {\n      return new SInt32Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class SInt32Schema<T> extends AbstractIntSchema<T> {\n    public SInt32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readSInt32();\n      if (Byte.class.equals(javaType.getRawClass())) {\n        setter.set(message, (byte) value);\n      } else if (Short.class.equals(javaType.getRawClass())) {\n        setter.set(message, (short) value);\n      } else {\n        setter.set(message, value);\n      }\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class SInt32PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final IntSetter<T> setter;\n\n    public SInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readSInt32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class ShortFieldSInt32PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final ShortSetter<T> setter;\n\n    public ShortFieldSInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readSInt32();\n      setter.set(message, (short) value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class ByteFieldSInt32PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final ByteSetter<T> setter;\n\n    public ByteFieldSInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readSInt32();\n      setter.set(message, (byte) value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/SInt64ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.LongSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractLongSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt64ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (long.class.equals(javaType.getRawClass())) {\n      return new SInt64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new SInt64Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class SInt64Schema<T> extends AbstractLongSchema<T> {\n    public SInt64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readSInt64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class SInt64PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final LongSetter<T> setter;\n\n    public SInt64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readSInt64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/StringReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.CharSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class StringReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n\n    if (char.class.equals(javaType.getRawClass())) {\n      return new CharFieldStringSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (String.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject() || Character.class\n        .equals(javaType.getRawClass())) {\n      return new StringSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (BigDecimal.class.equals(javaType.getRawClass())) {\n      return new BigDecimalSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (BigInteger.class.equals(javaType.getRawClass())) {\n      return new BigIntegerSchema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class StringSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Object> setter;\n\n    public StringSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      String value = input.readString();\n      if (char.class\n          .equals(javaType.getRawClass()) || Character.class.equals(javaType.getRawClass())) {\n        setter.set(message, value.toCharArray()[0]);\n      } else {\n        setter.set(message, value);\n      }\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class CharFieldStringSchema<T> extends FieldSchema<T> {\n    private final CharSetter<T> setter;\n\n    public CharFieldStringSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      String value = input.readString();\n      setter.set(message, value.toCharArray()[0]);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class BigDecimalSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Object> setter;\n\n    public BigDecimalSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      String value = input.readString();\n      setter.set(message, new BigDecimal(value));\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class BigIntegerSchema<T> extends FieldSchema<T> {\n    private final Setter<T, Object> setter;\n\n    public BigIntegerSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      String value = input.readString();\n      setter.set(message, new BigInteger(value));\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/UInt32ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractIntSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt32ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (int.class.equals(javaType.getRawClass())) {\n      return new UInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new UInt32Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class UInt32Schema<T> extends AbstractIntSchema<T> {\n    public UInt32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readUInt32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class UInt32PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final IntSetter<T> setter;\n\n    public UInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      int value = input.readUInt32();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/UInt64ReadSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.LongSetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.scalar.AbstractScalarReadSchemas.AbstractLongSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt64ReadSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (long.class.equals(javaType.getRawClass())) {\n      return new UInt64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(javaType.getRawClass()) || javaType.isJavaLangObject()) {\n      return new UInt64Schema<>(protoField, propertyDescriptor);\n    }\n\n    ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());\n    return null;\n  }\n\n  private static class UInt64Schema<T> extends AbstractLongSchema<T> {\n    public UInt64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readUInt64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n\n  private static class UInt64PrimitiveSchema<T> extends FieldSchema<T> {\n    protected final LongSetter<T> setter;\n\n    public UInt64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.setter = propertyDescriptor.getSetter();\n    }\n\n    @Override\n    public int mergeFrom(InputEx input, T message) throws IOException {\n      long value = input.readUInt64();\n      setter.set(message, value);\n      return input.readFieldNumber();\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/map/MapEntry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.map;\n\nimport java.util.Map.Entry;\n\nimport com.fasterxml.jackson.annotation.JsonSetter;\n\npublic class MapEntry<K, V> implements Entry<K, V> {\n  private K key;\n\n  private V value;\n\n  public K getKey() {\n    return key;\n  }\n\n  public void setKey(K key) {\n    this.key = key;\n  }\n\n  public V getValue() {\n    return value;\n  }\n\n  public V setValue(V value) {\n    this.value = value;\n    return value;\n  }\n\n  @JsonSetter(\"value\")\n  public void valueSetter(V value) {\n    this.value = value;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/map/MapEntrySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.map;\n\nimport java.io.IOException;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.MessageReadSchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.MessageWriteSchema;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class MapEntrySchema implements SchemaEx<Entry<Object, Object>> {\n  private final FieldSchema<Entry<Object, Object>> keySchema;\n\n  private final FieldSchema<Entry<Object, Object>> valueSchema;\n\n  public MapEntrySchema(SchemaEx<Entry<Object, Object>> entrySchema) {\n    if (entrySchema instanceof MessageWriteSchema) {\n      keySchema = ((MessageWriteSchema<Entry<Object, Object>>) entrySchema).getMainPojoFieldMaps().getFieldByNumber(1);\n      valueSchema = ((MessageWriteSchema<Entry<Object, Object>>) entrySchema).getMainPojoFieldMaps()\n          .getFieldByNumber(2);\n      return;\n    }\n\n    keySchema = ((MessageReadSchema<Entry<Object, Object>>) entrySchema).getFieldMap().getFieldByNumber(1);\n    valueSchema = ((MessageReadSchema<Entry<Object, Object>>) entrySchema).getFieldMap().getFieldByNumber(2);\n  }\n\n  @Override\n  public void init() {\n\n  }\n\n  @Override\n  public void mergeFrom(InputEx input, Entry<Object, Object> message) throws IOException {\n    input.readFieldNumber();\n    keySchema.mergeFrom(input, message);\n    valueSchema.mergeFrom(input, message);\n  }\n\n  @Override\n  public void writeTo(OutputEx output, Entry<Object, Object> value) throws IOException {\n    keySchema.writeTo(output, value.getKey());\n    valueSchema.writeTo(output, value.getValue());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/map/MapSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.map;\n\nimport java.io.IOException;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class MapSchema<T> extends FieldSchema<T> {\n  private final Getter<T, Map<Object, Object>> getter;\n\n  private final Setter<T, Map<Object, Object>> setter;\n\n  private final SchemaEx<Entry<Object, Object>> entrySchema;\n\n  public MapSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n      SchemaEx<Entry<Object, Object>> entrySchema) {\n    super(protoField, propertyDescriptor.getJavaType());\n    this.entrySchema = new MapEntrySchema(entrySchema);\n    this.getter = propertyDescriptor.getGetter();\n    this.setter = propertyDescriptor.getSetter();\n  }\n\n  @Override\n  public final int mergeFrom(InputEx input, T message) throws IOException {\n    Map<Object, Object> map = getter.get(message);\n    if (map == null) {\n      map = new LinkedHashMap<>();\n      setter.set(message, map);\n    }\n\n    Entry<Object, Object> entry = new MapEntry<>();\n    while (true) {\n      input.mergeObject(entry, entrySchema);\n      map.put(entry.getKey(), entry.getValue());\n      entry.setValue(null);\n\n      int fieldNumber = input.readFieldNumber();\n      if (fieldNumber != this.fieldNumber) {\n        return fieldNumber;\n      }\n    }\n  }\n\n  @Override\n  public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n    Map<Object, Object> map = getter.get(message);\n    if (map == null) {\n      return;\n    }\n\n    writeMap(output, map);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public final void writeTo(OutputEx output, Object value) throws IOException {\n    writeMap(output, (Map<Object, Object>) value);\n  }\n\n  private void writeMap(OutputEx output, Map<Object, Object> map) throws IOException {\n    for (Entry<Object, Object> entry : map.entrySet()) {\n      if (entry.getKey() == null || entry.getValue() == null) {\n        continue;\n      }\n\n      output.writeObject(tag, tagSize, entry, entrySchema);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.InputEx;\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.runtime.FieldMapEx;\nimport io.protostuff.runtime.FieldSchema;\n\n/**\n * <pre>\n * map.put(\"user\", new User())\n * root write from map, but user should write from pojo\n * so one schema should support dynamic and concrete logic at the same time\n * </pre>\n */\npublic class MessageWriteSchema<T> implements SchemaEx<T> {\n  protected final ProtoMapper protoMapper;\n\n  protected final Message message;\n\n  private final JavaType javaType;\n\n  // mostly, one message only relate to one pojo\n  private final Class<T> mainPojoCls;\n\n  private FieldMapEx<T> mainPojoFieldMaps;\n\n  private FieldMapEx<Map<Object, Object>> mapFieldMaps;\n\n  // if not equals to mainPojoCls, then will find from pojoFieldMaps\n  private final Map<Class<?>, FieldMapEx<?>> pojoFieldMaps = new ConcurrentHashMapEx<>();\n\n  @SuppressWarnings(\"unchecked\")\n  public MessageWriteSchema(ProtoMapper protoMapper, Message message, JavaType javaType) {\n    this.protoMapper = protoMapper;\n    this.message = message;\n    this.javaType = javaType;\n    this.mainPojoCls = (Class<T>) javaType.getRawClass();\n  }\n\n  public Message getMessage() {\n    return message;\n  }\n\n  @Override\n  public T newMessage() {\n    throw new UnsupportedOperationException();\n  }\n\n  @Override\n  public String messageName() {\n    return message.getName();\n  }\n\n  public JavaType getJavaType() {\n    return javaType;\n  }\n\n  public Class<T> getMainPojoCls() {\n    return mainPojoCls;\n  }\n\n  public FieldMapEx<T> getMainPojoFieldMaps() {\n    return mainPojoFieldMaps;\n  }\n\n  @Override\n  public void init() {\n    this.mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);\n\n    if (ProtoUtils.isWrapProperty(message)) {\n      this.mainPojoFieldMaps = createPropertyWrapperFields(javaType);\n      return;\n    }\n\n    this.mainPojoFieldMaps = createPojoFields(javaType);\n  }\n\n  private FieldMapEx<T> createPropertyWrapperFields(JavaType javaType) {\n    Field protoField = message.getField(1);\n\n    PropertyDescriptor propertyDescriptor = new PropertyDescriptor();\n    propertyDescriptor.setName(protoField.getName());\n    propertyDescriptor.setJavaType(javaType);\n\n    FieldSchema<T> fieldSchema = protoMapper.getSerializerSchemaManager()\n        .createSchemaField(protoField, propertyDescriptor);\n    return FieldMapEx.createFieldMap(Arrays.asList(fieldSchema));\n  }\n\n  private FieldMapEx<T> createPojoFields(Type type) {\n    SerializerSchemaManager serializerSchemaManager = protoMapper.getSerializerSchemaManager();\n    BeanDescriptor beanDescriptor = protoMapper.getBeanDescriptorManager().getOrCreateBeanDescriptor(type);\n\n    List<FieldSchema<T>> fieldSchemas = new ArrayList<>();\n    for (Field protoField : message.getFields()) {\n      PropertyDescriptor propertyDescriptor = beanDescriptor.getPropertyDescriptors().get(protoField.getName());\n      if (propertyDescriptor == null) {\n        continue;\n      }\n\n      Object getter = propertyDescriptor.getGetter();\n      if (getter == null) {\n        continue;\n      }\n\n      FieldSchema<T> fieldSchema = serializerSchemaManager.createSchemaField(protoField, propertyDescriptor);\n      fieldSchemas.add(fieldSchema);\n    }\n\n    return FieldMapEx.createFieldMap(fieldSchemas);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public void writeTo(OutputEx output, Object value) throws IOException {\n    if (value instanceof Map) {\n      writeFromMap(output, (Map<String, Object>) value);\n      return;\n    }\n\n    if (mainPojoCls == value.getClass()) {\n      writeFromMainPojo(output, (T) value);\n      return;\n    }\n\n    writeDynamicPojo(output, value);\n  }\n\n  private void writeFromMainPojo(OutputEx output, T value) throws IOException {\n    for (FieldSchema<T> fieldSchema : mainPojoFieldMaps.getFields()) {\n      fieldSchema.getAndWriteTo(output, value);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private <T> void writeDynamicPojo(OutputEx output, Object dynamicValue) throws IOException {\n    FieldMapEx<T> fieldMapEx = (FieldMapEx<T>) this.pojoFieldMaps\n        .computeIfAbsent(dynamicValue.getClass(), this::createPojoFields);\n\n    T value = (T) dynamicValue;\n    for (FieldSchema<T> fieldSchema : fieldMapEx.getFields()) {\n      fieldSchema.getAndWriteTo(output, value);\n    }\n  }\n\n  protected final void writeFromMap(OutputEx output, Map<String, Object> map) throws IOException {\n    for (Entry<String, Object> entry : map.entrySet()) {\n      if (entry.getValue() == null) {\n        continue;\n      }\n\n      FieldSchema<Map<Object, Object>> fieldSchema = mapFieldMaps.getFieldByName(entry.getKey());\n      if (fieldSchema != null) {\n        fieldSchema.writeTo(output, entry.getValue());\n      }\n    }\n  }\n\n  @Override\n  public void mergeFrom(InputEx input, T message) throws IOException {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer;\n\nimport static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isWrapProperty;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.SchemaManager;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.any.AnyEntrySchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.any.AnySchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.AnyRepeatedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.BytesRepeatedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.MessagesRepeatedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.PropertyWrapperRepeatedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.StringsRepeatedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.bools.BoolNotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.bools.BoolPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.doubles.DoubleNotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.doubles.DoublePackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.enums.EnumNotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.enums.EnumPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.floats.FloatNotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.floats.FloatPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.Fixed32NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.Fixed32PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.Int32NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.Int32PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.SFixed32NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.SFixed32PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.SInt32NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.SInt32PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.UInt32NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints.UInt32PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.Fixed64NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.Fixed64PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.Int64NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.Int64PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.SFixed64NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.SFixed64PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.SInt64NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.SInt64PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.UInt64NotPackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs.UInt64PackedWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.BoolWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.BytesWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.DoubleWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.EnumWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.Fixed32WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.Fixed64WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.FloatWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.Int32WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.Int64WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.SFixed32WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.SFixed64WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.SInt32WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.SInt64WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.StringWriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.UInt32WriteSchemas;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar.UInt64WriteSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.protostuff.SchemaEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Message;\nimport io.protostuff.compiler.model.ScalarFieldType;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SerializerSchemaManager extends SchemaManager {\n  public SerializerSchemaManager(ProtoMapper protoMapper) {\n    super(protoMapper);\n  }\n\n  public RootSerializer createRootSerializer(Message message, Type type) {\n    if (ProtoUtils.isAnyMessage(message)) {\n      SchemaEx<Object> messageSchema = new AnyEntrySchema(protoMapper, type);\n      return new RootSerializer(messageSchema);\n    }\n    JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n    SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, javaType);\n    return new RootSerializer(messageSchema);\n  }\n\n  public RootSerializer createRootSerializer(Message message, Map<String, Type> types) {\n    throw new IllegalStateException(\"not implemented\");\n  }\n\n  @Override\n  protected <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType) {\n    return new MessageWriteSchema<>(protoMapper, message, javaType);\n  }\n\n  @Override\n  protected <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types) {\n    throw new IllegalStateException(\"not implemented\");\n  }\n\n  protected <T> FieldSchema<T> createScalarField(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (protoField.getType().isEnum()) {\n      return EnumWriteSchemas.create(protoField, propertyDescriptor);\n    }\n\n    switch ((ScalarFieldType) protoField.getType()) {\n      case INT32:\n        return Int32WriteSchemas.create(protoField, propertyDescriptor);\n      case UINT32:\n        return UInt32WriteSchemas.create(protoField, propertyDescriptor);\n      case SINT32:\n        return SInt32WriteSchemas.create(protoField, propertyDescriptor);\n      case FIXED32:\n        return Fixed32WriteSchemas.create(protoField, propertyDescriptor);\n      case SFIXED32:\n        return SFixed32WriteSchemas.create(protoField, propertyDescriptor);\n      case INT64:\n        return Int64WriteSchemas.create(protoField, propertyDescriptor);\n      case UINT64:\n        return UInt64WriteSchemas.create(protoField, propertyDescriptor);\n      case SINT64:\n        return SInt64WriteSchemas.create(protoField, propertyDescriptor);\n      case FIXED64:\n        return Fixed64WriteSchemas.create(protoField, propertyDescriptor);\n      case SFIXED64:\n        return SFixed64WriteSchemas.create(protoField, propertyDescriptor);\n      case FLOAT:\n        return FloatWriteSchemas.create(protoField, propertyDescriptor);\n      case DOUBLE:\n        return DoubleWriteSchemas.create(protoField, propertyDescriptor);\n      case BOOL:\n        return BoolWriteSchemas.create(protoField, propertyDescriptor);\n      case STRING:\n        return StringWriteSchemas.create(protoField, propertyDescriptor);\n      case BYTES:\n        return BytesWriteSchemas.create(protoField, propertyDescriptor);\n      default:\n        throw new IllegalStateException(\"unknown proto field type: \" + protoField.getType());\n    }\n  }\n\n  @Override\n  protected <T> FieldSchema<T> createRepeatedSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n    boolean packed = ProtoUtils.isPacked(protoField);\n    if (protoField.getType().isEnum()) {\n      return packed ? EnumPackedWriteSchemas.create(protoField, propertyDescriptor) :\n          EnumNotPackedWriteSchemas.create(protoField, propertyDescriptor);\n    }\n\n    if (protoField.getType().isScalar()) {\n      switch ((ScalarFieldType) protoField.getType()) {\n        case INT32:\n          return packed ? Int32PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              Int32NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case UINT32:\n          return packed ? UInt32PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              UInt32NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case SINT32:\n          return packed ? SInt32PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              SInt32NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case FIXED32:\n          return packed ? Fixed32PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              Fixed32NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case SFIXED32:\n          return packed ? SFixed32PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              SFixed32NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case INT64:\n          return packed ? Int64PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              Int64NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case UINT64:\n          return packed ? UInt64PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              UInt64NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case SINT64:\n          return packed ? SInt64PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              SInt64NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case FIXED64:\n          return packed ? Fixed64PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              Fixed64NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case SFIXED64:\n          return packed ? SFixed64PackedWriteSchemas.create(protoField, propertyDescriptor) :\n              SFixed64NotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case FLOAT:\n          return packed ? FloatPackedWriteSchemas.create(protoField, propertyDescriptor) :\n              FloatNotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case DOUBLE:\n          return packed ? DoublePackedWriteSchemas.create(protoField, propertyDescriptor) :\n              DoubleNotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case BOOL:\n          return packed ? BoolPackedWriteSchemas.create(protoField, propertyDescriptor) :\n              BoolNotPackedWriteSchemas.create(protoField, propertyDescriptor);\n        case STRING:\n          return StringsRepeatedWriteSchemas.create(protoField, propertyDescriptor);\n        case BYTES:\n          return BytesRepeatedWriteSchemas.create(protoField, propertyDescriptor);\n        default:\n          ProtoUtils.throwNotSupportWrite(protoField, propertyDescriptor.getJavaType().getRawClass());\n      }\n    }\n\n    if (ProtoUtils.isAnyField(protoField)) {\n      FieldSchema<T> anySchema = new AnySchema<>(protoMapper, protoField, propertyDescriptor);\n      return AnyRepeatedWriteSchemas.create(protoField, propertyDescriptor, anySchema);\n    }\n\n    if (protoField.getType().isMessage()) {\n      JavaType contentType = propertyDescriptor.getJavaType().getContentType();\n      if (contentType == null) {\n        contentType = ProtoConst.OBJECT_TYPE;\n      }\n      SchemaEx<Object> contentSchema = createMessageSchema((Message) protoField.getType(), contentType);\n      if (isWrapProperty((Message) protoField.getType())) {\n        return PropertyWrapperRepeatedWriteSchemas.create(protoField, propertyDescriptor, contentSchema);\n      }\n\n      return MessagesRepeatedWriteSchemas.create(protoField, propertyDescriptor, contentSchema);\n    }\n\n    ProtoUtils.throwNotSupportWrite(protoField, propertyDescriptor.getJavaType().getRawClass());\n    return null;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/AbstractPrimitiveWriters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated;\n\nimport static org.apache.servicecomb.foundation.common.utils.ReflectUtils.getFieldArgument;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.SchemaWriter;\nimport io.protostuff.compiler.model.Field;\n\npublic abstract class AbstractPrimitiveWriters<PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> extends\n    AbstractWriters<PRIMITIVE_WRAPPER> {\n  public SchemaWriter<PRIMITIVE_ARRAY> primitiveArrayWriter;\n\n  public final Class<PRIMITIVE_ARRAY> primitiveArrayClass;\n\n  @SuppressWarnings(\"unchecked\")\n  public AbstractPrimitiveWriters(Field protoField) {\n    super(protoField);\n\n    this.primitiveArrayClass = getFieldArgument(this.getClass(), \"primitiveArrayClass\");\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public final void dynamicWriteTo(OutputEx output, Object value) throws IOException {\n    // from normal model\n    if (primitiveArrayClass.isInstance(value)) {\n      primitiveArrayWriter.writeTo(output, (PRIMITIVE_ARRAY) value);\n      return;\n    }\n\n    if (arrayClass.isInstance(value)) {\n      arrayWriter.writeTo(output, (PRIMITIVE_WRAPPER[]) value);\n      return;\n    }\n\n    if (value instanceof Collection) {\n      collectionWriter.writeTo(output, (Collection<PRIMITIVE_WRAPPER>) value);\n      return;\n    }\n\n    // from http request\n    if (value instanceof String[]) {\n      stringArrayWriter.writeTo(output, (String[]) value);\n      return;\n    }\n\n    ProtoUtils.throwNotSupportWrite(protoField, value);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/AbstractWriters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated;\n\nimport static org.apache.servicecomb.foundation.common.utils.ReflectUtils.getFieldArgument;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.ProtobufOutputEx;\nimport io.protostuff.SchemaWriter;\nimport io.protostuff.WireFormat;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldTypeUtils;\n\npublic abstract class AbstractWriters<T> {\n  protected final Field protoField;\n\n  protected final int tag;\n\n  protected final int tagSize;\n\n  public SchemaWriter<T[]> arrayWriter;\n\n  public SchemaWriter<Collection<T>> collectionWriter;\n\n  public SchemaWriter<String[]> stringArrayWriter;\n\n  public final Class<T[]> arrayClass;\n\n  @SuppressWarnings(\"unchecked\")\n  public AbstractWriters(Field protoField) {\n    this(protoField, null);\n  }\n\n  public AbstractWriters(Field protoField, Class<T[]> arrayClass) {\n    this.protoField = protoField;\n    int wireType = ProtoUtils.isPacked(protoField) && protoField.isRepeated() ? WireFormat.WIRETYPE_LENGTH_DELIMITED\n        : FieldTypeUtils.convert(protoField.getType()).wireType;\n    this.tag = WireFormat.makeTag(protoField.getTag(), wireType);\n    this.tagSize = ProtobufOutputEx.computeRawVarint32Size(tag);\n\n    if (arrayClass == null) {\n      arrayClass = getFieldArgument(this.getClass(), \"arrayWriter\");\n    }\n    this.arrayClass = arrayClass;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public void dynamicWriteTo(OutputEx output, Object value) throws IOException {\n    if (value instanceof Collection) {\n      collectionWriter.writeTo(output, (Collection<T>) value);\n      return;\n    }\n\n    // from normal model\n    if (arrayClass.isInstance(value)) {\n      arrayWriter.writeTo(output, (T[]) value);\n      return;\n    }\n\n    // from http request\n    if (value instanceof String[]) {\n      stringArrayWriter.writeTo(output, (String[]) value);\n      return;\n    }\n\n    ProtoUtils.throwNotSupportWrite(protoField, value);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/RepeatedPrimitiveWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas.DynamicSchema;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class RepeatedPrimitiveWriteSchemas {\n  public static <T, PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> FieldSchema<T> create(Field protoField,\n      PropertyDescriptor propertyDescriptor,\n      AbstractPrimitiveWriters<PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> writers) {\n    JavaType javaType = propertyDescriptor.getJavaType();\n    if (writers.primitiveArrayClass == javaType.getRawClass()) {\n      return new PrimitiveArraySchema<>(protoField, propertyDescriptor, writers);\n    }\n\n    return RepeatedWriteSchemas.create(protoField, propertyDescriptor, writers);\n  }\n\n  private static class PrimitiveArraySchema<T, PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> extends\n      DynamicSchema<T, PRIMITIVE_WRAPPER> {\n    private final Getter<T, PRIMITIVE_ARRAY> getter;\n\n    private final AbstractPrimitiveWriters<PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> primitiveWriters;\n\n    public PrimitiveArraySchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractPrimitiveWriters<PRIMITIVE_ARRAY, PRIMITIVE_WRAPPER> writers) {\n      super(protoField, propertyDescriptor, writers);\n      this.getter = propertyDescriptor.getGetter();\n      this.primitiveWriters = writers;\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      PRIMITIVE_ARRAY value = getter.get(message);\n      if (value == null) {\n        return;\n      }\n\n      primitiveWriters.primitiveArrayWriter.writeTo(output, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/RepeatedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class RepeatedWriteSchemas {\n  public static <T, ELE_TYPE> FieldSchema<T> create(Field protoField,\n      PropertyDescriptor propertyDescriptor,\n      AbstractWriters<ELE_TYPE> writers) {\n    return new CollectionSchema<>(protoField, propertyDescriptor, writers);\n  }\n\n  static class DynamicSchema<T, ELE_TYPE> extends FieldSchema<T> {\n    protected final AbstractWriters<ELE_TYPE> writers;\n\n    @SuppressWarnings(\"unchecked\")\n    public DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractWriters<ELE_TYPE> writers) {\n      super(protoField, propertyDescriptor.getJavaType());\n\n      this.writers = writers;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      writers.dynamicWriteTo(output, value);\n    }\n  }\n\n  private static class CollectionSchema<T, ELE_TYPE> extends DynamicSchema<T, ELE_TYPE> {\n    private final Getter<T, Object> getter;\n\n    public CollectionSchema(Field protoField, PropertyDescriptor propertyDescriptor,\n        AbstractWriters<ELE_TYPE> writers) {\n      super(protoField, propertyDescriptor, writers);\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value == null) {\n        return;\n      }\n      this.writeTo(output, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/AnyRepeatedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class AnyRepeatedWriteSchemas {\n  private static class AnyWriters<T> extends AbstractWriters<T> {\n    public AnyWriters(Field protoField, FieldSchema<T> anySchema) {\n      super(protoField);\n\n      arrayWriter = (output, array) -> {\n        for (Object element : array) {\n          if (element != null) {\n            anySchema.writeTo(output, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        for (Object element : collection) {\n          if (element != null) {\n            anySchema.writeTo(output, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      FieldSchema<T> anySchema) {\n    return RepeatedWriteSchemas.create(protoField, propertyDescriptor, new AnyWriters<>(protoField, anySchema));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/BytesRepeatedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BytesRepeatedWriteSchemas {\n  private static class BytesWriters extends AbstractWriters<byte[]> {\n    public BytesWriters(Field protoField) {\n      super(protoField);\n\n      arrayWriter = (output, array) -> {\n        for (byte[] element : array) {\n          if (element != null) {\n            output.writeByteArray(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        for (byte[] element : collection) {\n          if (element != null) {\n            output.writeByteArray(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedWriteSchemas.create(protoField, propertyDescriptor, new BytesWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/MessagesRepeatedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl;\n\nimport java.lang.reflect.Array;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.MessageWriteSchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport io.protostuff.SchemaWriter;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class MessagesRepeatedWriteSchemas {\n  private static class MessageWriters extends AbstractWriters<Object> {\n    @SuppressWarnings(\"unchecked\")\n    public MessageWriters(Field protoField, SchemaWriter<Object> elementSchema) {\n      super(protoField,\n          (Class<Object[]>) Array.newInstance(((MessageWriteSchema<Object>) elementSchema).getMainPojoCls(), 0)\n              .getClass());\n\n      arrayWriter = (output, array) -> {\n        for (Object element : array) {\n          if (element != null) {\n            output.writeObject(tag, tagSize, element, elementSchema);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        for (Object element : collection) {\n          if (element != null) {\n            output.writeObject(tag, tagSize, element, elementSchema);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      SchemaWriter<Object> elementSchema) {\n    return RepeatedWriteSchemas.create(protoField, propertyDescriptor, new MessageWriters(protoField, elementSchema));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/PropertyWrapperRepeatedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl;\n\nimport java.lang.reflect.Array;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.MessageWriteSchema;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.SchemaWriter;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class PropertyWrapperRepeatedWriteSchemas {\n  private static class PropertyWrapperWriters extends AbstractWriters<Object> {\n    public PropertyWrapperWriters(Field protoField, SchemaWriter<Object> elementSchema, Class<Object[]> arrayClass) {\n      super(protoField, arrayClass);\n\n      FieldSchema<Object> fieldSchema =\n          (elementSchema instanceof MessageWriteSchema) ? ((MessageWriteSchema<Object>) elementSchema)\n              .getMainPojoFieldMaps()\n              .getFieldByNumber(1) : null;\n      arrayWriter = (output, array) -> {\n        for (Object element : array) {\n          if (element != null) {\n            output.writeObject(tag, tagSize, element, fieldSchema::writeTo);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        for (Object element : collection) {\n          if (element != null) {\n            output.writeObject(tag, tagSize, element, fieldSchema::writeTo);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor,\n      SchemaWriter<Object> elementSchema) {\n    JavaType contentType = propertyDescriptor.getJavaType().getContentType();\n    Class<Object> contentClass = contentType == null ? Object.class : (Class<Object>) contentType.getRawClass();\n    Class<Object[]> arrayClass = (Class<Object[]>) Array.newInstance(contentClass, 0).getClass();\n    return RepeatedWriteSchemas\n        .create(protoField, propertyDescriptor, new PropertyWrapperWriters(protoField, elementSchema, arrayClass));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/StringsRepeatedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class StringsRepeatedWriteSchemas {\n  private static class StringWriters extends AbstractWriters<String> {\n    public StringWriters(Field protoField) {\n      super(protoField);\n\n      arrayWriter = (output, array) -> {\n        for (String element : array) {\n          if (element != null) {\n            output.writeString(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        for (String element : collection) {\n          if (element != null) {\n            output.writeString(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedWriteSchemas.create(protoField, propertyDescriptor, new StringWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/bools/BoolNotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.bools;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolNotPackedWriteSchemas {\n  private static class BoolNotPackedWriters extends AbstractPrimitiveWriters<boolean[], Boolean> {\n    public BoolNotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, boolean[] array) -> {\n        for (boolean element : array) {\n          output.writeBool(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Boolean[] array) -> {\n        for (Boolean element : array) {\n          if (element != null) {\n            output.writeBool(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Boolean> collection) -> {\n        for (Boolean element : collection) {\n          if (element != null) {\n            output.writeBool(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            boolean parsedValue = Boolean.parseBoolean(element);\n            output.writeBool(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new BoolNotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/bools/BoolPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.bools;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolPackedWriteSchemas {\n  private static class BoolPackedWriters extends AbstractPrimitiveWriters<boolean[], Boolean> {\n    public BoolPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (boolean element : array) {\n              output.writePackedBool(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Boolean element : array) {\n              if (element != null) {\n                output.writePackedBool(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Boolean element : collection) {\n              if (element != null) {\n                output.writePackedBool(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                boolean parsedValue = Boolean.parseBoolean(element);\n                output.writePackedBool(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new BoolPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/doubles/DoubleNotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.doubles;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoubleNotPackedWriteSchemas {\n  private static class DoubleNotPackedWriters extends AbstractPrimitiveWriters<double[], Double> {\n    public DoubleNotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, double[] array) -> {\n        for (double element : array) {\n          output.writeDouble(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Double[] array) -> {\n        for (Double element : array) {\n          if (element != null) {\n            output.writeDouble(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Double> collection) -> {\n        for (Double element : collection) {\n          if (element != null) {\n            output.writeDouble(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            double parsedValue = Double.parseDouble(element);\n            output.writeDouble(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new DoubleNotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/doubles/DoublePackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.doubles;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoublePackedWriteSchemas {\n  private static class DoublePackedWriters extends AbstractPrimitiveWriters<double[], Double> {\n    public DoublePackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (double element : array) {\n              output.writePackedDouble(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Double element : array) {\n              if (element != null) {\n                output.writePackedDouble(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Double element : collection) {\n              if (element != null) {\n                output.writePackedDouble(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                double parsedValue = Double.parseDouble(element);\n                output.writePackedDouble(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new DoublePackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/enums/EnumNotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.enums;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.EnumMeta;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class EnumNotPackedWriteSchemas {\n  private static class EnumNotPackedWriters extends AbstractWriters<Enum<?>> {\n    private final EnumMeta enumMeta;\n\n    @SuppressWarnings(\"unchecked\")\n    public EnumNotPackedWriters(Field protoField, JavaType javaType) {\n      super(protoField, ReflectUtils.constructArrayType(Enum.class));\n      this.enumMeta = new EnumMeta(protoField, javaType);\n\n      arrayWriter = (output, array) -> {\n        for (Enum<?> element : array) {\n          if (element == null) {\n            ProtoUtils.throwNotSupportNullElement(protoField);\n            return;\n          }\n\n          String name = element.name();\n          Integer enumValue = enumMeta.getValueByName(name);\n          if (enumValue == null) {\n            throw new IllegalStateException(\n                String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                    name,\n                    protoField.getTypeName(),\n                    ((Type) protoField.getParent()).getCanonicalName(),\n                    protoField.getName()));\n          }\n\n          output.writeEnum(tag, tagSize, enumValue);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        if (collection.isEmpty()) {\n          return;\n        }\n\n        Object first = collection.iterator().next();\n        if (first.getClass().isEnum()) {\n          writeEnumCollection(output, collection);\n          return;\n        }\n\n        if (first.getClass() == String.class) {\n          writeStringCollection(output, (Collection<String>) (Object) collection);\n          return;\n        }\n\n        writeIntCollection(output, (Collection<Number>) (Object) collection);\n      };\n\n      stringArrayWriter = (output, array) -> {\n        for (String element : array) {\n          if (element == null) {\n            ProtoUtils.throwNotSupportNullElement(protoField);\n            return;\n          }\n\n          Integer enumValue = enumMeta.getValueByName(element);\n          if (enumValue == null) {\n            throw new IllegalStateException(\n                String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                    element,\n                    protoField.getTypeName(),\n                    ((Type) protoField.getParent()).getCanonicalName(),\n                    protoField.getName()));\n          }\n\n          output.writeEnum(tag, tagSize, enumValue);\n        }\n      };\n    }\n\n    private void writeStringCollection(OutputEx output, Collection<String> collection) throws IOException {\n      for (String element : collection) {\n        if (element == null) {\n          ProtoUtils.throwNotSupportNullElement(protoField);\n          return;\n        }\n\n        Integer enumValue = enumMeta.getValueByName(element);\n        if (enumValue == null) {\n          throw new IllegalStateException(\n              String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                  element,\n                  protoField.getTypeName(),\n                  ((Type) protoField.getParent()).getCanonicalName(),\n                  protoField.getName()));\n        }\n\n        output.writeEnum(tag, tagSize, enumValue);\n      }\n    }\n\n    private void writeIntCollection(OutputEx output, Collection<Number> collection) throws IOException {\n      for (Number element : collection) {\n        if (element == null) {\n          ProtoUtils.throwNotSupportNullElement(protoField);\n          return;\n        }\n\n        output.writeInt32(tag, tagSize, element.intValue());\n      }\n    }\n\n    private void writeEnumCollection(OutputEx output, Collection<Enum<?>> collection) throws IOException {\n      for (Enum<?> element : collection) {\n        if (element == null) {\n          ProtoUtils.throwNotSupportNullElement(protoField);\n          return;\n        }\n\n        String name = element.name();\n        Integer enumValue = enumMeta.getValueByName(name);\n        if (enumValue == null) {\n          throw new IllegalStateException(\n              String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                  name,\n                  protoField.getTypeName(),\n                  ((Type) protoField.getParent()).getCanonicalName(),\n                  protoField.getName()));\n        }\n\n        output.writeEnum(tag, tagSize, enumValue);\n      }\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedWriteSchemas.create(protoField, propertyDescriptor,\n        new EnumNotPackedWriters(protoField, propertyDescriptor.getJavaType()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/enums/EnumPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.enums;\n\nimport java.io.IOException;\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.EnumMeta;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedWriteSchemas;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class EnumPackedWriteSchemas {\n  private static class EnumsPackedWriters extends AbstractWriters<Enum<?>> {\n    private final EnumMeta enumMeta;\n\n    @SuppressWarnings(\"unchecked\")\n    public EnumsPackedWriters(Field protoField, JavaType javaType) {\n      super(protoField, ReflectUtils.constructArrayType(Enum.class));\n      this.enumMeta = new EnumMeta(protoField, javaType);\n\n      arrayWriter = (o, value) -> o.writeObject(tag, tagSize, value, (output, array) -> {\n        for (Enum<?> element : array) {\n          if (element == null) {\n            ProtoUtils.throwNotSupportNullElement(protoField);\n            return;\n          }\n\n          String name = element.name();\n          Integer enumValue = enumMeta.getValueByName(name);\n          if (enumValue == null) {\n            throw new IllegalStateException(\n                String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                    name,\n                    protoField.getTypeName(),\n                    ((Type) protoField.getParent()).getCanonicalName(),\n                    protoField.getName()));\n          }\n\n          output.writePackedEnum(enumValue);\n        }\n      });\n\n      collectionWriter = (o, value) -> o.writeObject(tag, tagSize, value, (output, collection) -> {\n        Object first = collection.iterator().next();\n        if (first.getClass().isEnum()) {\n          writeEnumCollection(output, collection);\n          return;\n        }\n\n        if (first.getClass() == String.class) {\n          writeStringCollection(output, (Collection<String>) (Object) collection);\n          return;\n        }\n\n        writeIntCollection(output, (Collection<Number>) (Object) collection);\n      });\n\n      stringArrayWriter = (o, value) -> o.writeObject(tag, tagSize, value, (output, array) -> {\n        for (String element : array) {\n          if (element == null) {\n            ProtoUtils.throwNotSupportNullElement(protoField);\n            return;\n          }\n\n          Integer enumValue = enumMeta.getValueByName(element);\n          if (enumValue == null) {\n            throw new IllegalStateException(\n                String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                    element,\n                    protoField.getTypeName(),\n                    ((Type) protoField.getParent()).getCanonicalName(),\n                    protoField.getName()));\n          }\n\n          output.writePackedEnum(enumValue);\n        }\n      });\n    }\n\n    private void writeStringCollection(OutputEx output, Collection<String> collection) throws IOException {\n      for (String element : collection) {\n        if (element == null) {\n          ProtoUtils.throwNotSupportNullElement(protoField);\n          return;\n        }\n\n        Integer enumValue = enumMeta.getValueByName(element);\n        if (enumValue == null) {\n          throw new IllegalStateException(\n              String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                  element,\n                  protoField.getTypeName(),\n                  ((Type) protoField.getParent()).getCanonicalName(),\n                  protoField.getName()));\n        }\n\n        output.writePackedEnum(enumValue);\n      }\n    }\n\n    private void writeIntCollection(OutputEx output, Collection<Number> collection) throws IOException {\n      for (Number element : collection) {\n        if (element == null) {\n          ProtoUtils.throwNotSupportNullElement(protoField);\n          return;\n        }\n\n        output.writePackedInt32(element.intValue());\n      }\n    }\n\n    private void writeEnumCollection(OutputEx output, Collection<Enum<?>> collection) throws IOException {\n      for (Enum<?> element : collection) {\n        if (element == null) {\n          ProtoUtils.throwNotSupportNullElement(protoField);\n          return;\n        }\n\n        String name = element.name();\n        Integer enumValue = enumMeta.getValueByName(name);\n        if (enumValue == null) {\n          throw new IllegalStateException(\n              String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                  name,\n                  protoField.getTypeName(),\n                  ((Type) protoField.getParent()).getCanonicalName(),\n                  protoField.getName()));\n        }\n\n        output.writePackedEnum(enumValue);\n      }\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedWriteSchemas\n        .create(protoField, propertyDescriptor, new EnumsPackedWriters(protoField, propertyDescriptor.getJavaType()));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/floats/FloatNotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.floats;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatNotPackedWriteSchemas {\n  private static class FloatNotPackedWriters extends AbstractPrimitiveWriters<float[], Float> {\n    public FloatNotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, float[] array) -> {\n        for (float element : array) {\n          output.writeFloat(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Float[] array) -> {\n        for (Float element : array) {\n          if (element != null) {\n            output.writeFloat(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Float> collection) -> {\n        for (Float element : collection) {\n          if (element != null) {\n            output.writeFloat(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            float parsedValue = Float.parseFloat(element);\n            output.writeFloat(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new FloatNotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/floats/FloatPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.floats;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatPackedWriteSchemas {\n  private static class FloatPackedWriters extends AbstractPrimitiveWriters<float[], Float> {\n    public FloatPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (float element : array) {\n              output.writePackedFloat(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Float element : array) {\n              if (element != null) {\n                output.writePackedFloat(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Float element : collection) {\n              if (element != null) {\n                output.writePackedFloat(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                float parsedValue = Float.parseFloat(element);\n                output.writePackedFloat(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new FloatPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Fixed32NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed32NotPackedWriteSchemas {\n  private static class Fixed32NotPackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public Fixed32NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, int[] array) -> {\n        for (int element : array) {\n          output.writeFixed32(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Integer[] array) -> {\n        for (Integer element : array) {\n          if (element != null) {\n            output.writeFixed32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Integer> collection) -> {\n        for (Integer element : collection) {\n          if (element != null) {\n            output.writeFixed32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            int parsedValue = Integer.parseInt(element, 10);\n            output.writeFixed32(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas\n        .create(protoField, propertyDescriptor, new Fixed32NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Fixed32PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed32PackedWriteSchemas {\n  private static class Fixed32PackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public Fixed32PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (int element : array) {\n            output.writePackedFixed32(element);\n          }\n        });\n      };\n\n      arrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (Integer element : array) {\n            if (element != null) {\n              output.writePackedFixed32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      collectionWriter = (o, value) -> {\n        if (value.isEmpty()) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, collection) -> {\n          for (Integer element : collection) {\n            if (element != null) {\n              output.writePackedFixed32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      stringArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (String element : array) {\n            if (element != null) {\n              int parsedValue = Integer.parseInt(element, 10);\n              output.writePackedFixed32(parsedValue);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new Fixed32PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Int32NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int32NotPackedWriteSchemas {\n  private static class Int32NotPackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public Int32NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, int[] array) -> {\n        for (int element : array) {\n          output.writeInt32(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Integer[] array) -> {\n        for (Integer element : array) {\n          if (element != null) {\n            output.writeInt32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Integer> collection) -> {\n        for (Integer element : collection) {\n          if (element != null) {\n            output.writeInt32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            int parsedValue = Integer.parseInt(element, 10);\n            output.writeInt32(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new Int32NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Int32PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int32PackedWriteSchemas {\n  private static class Int32PackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public Int32PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (int element : array) {\n            output.writePackedInt32(element);\n          }\n        });\n      };\n\n      arrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (Integer element : array) {\n            if (element != null) {\n              output.writePackedInt32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      collectionWriter = (o, value) -> {\n        if (value.isEmpty()) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, collection) -> {\n          for (Integer element : collection) {\n            if (element != null) {\n              output.writePackedInt32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      stringArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (String element : array) {\n            if (element != null) {\n              int parsedValue = Integer.parseInt(element, 10);\n              output.writePackedInt32(parsedValue);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new Int32PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SFixed32NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed32NotPackedWriteSchemas {\n  private static class SFixed32NotPackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public SFixed32NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, int[] array) -> {\n        for (int element : array) {\n          output.writeSFixed32(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Integer[] array) -> {\n        for (Integer element : array) {\n          if (element != null) {\n            output.writeSFixed32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Integer> collection) -> {\n        for (Integer element : collection) {\n          if (element != null) {\n            output.writeSFixed32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            int parsedValue = Integer.parseInt(element, 10);\n            output.writeSFixed32(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas\n        .create(protoField, propertyDescriptor, new SFixed32NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SFixed32PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed32PackedWriteSchemas {\n  private static class SFixed32PackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public SFixed32PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (int element : array) {\n            output.writePackedSFixed32(element);\n          }\n        });\n      };\n\n      arrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (Integer element : array) {\n            if (element != null) {\n              output.writePackedSFixed32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      collectionWriter = (o, value) -> {\n        if (value.isEmpty()) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, collection) -> {\n          for (Integer element : collection) {\n            if (element != null) {\n              output.writePackedSFixed32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      stringArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (String element : array) {\n            if (element != null) {\n              int parsedValue = Integer.parseInt(element, 10);\n              output.writePackedSFixed32(parsedValue);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new SFixed32PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SInt32NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt32NotPackedWriteSchemas {\n  private static class SInt32NotPackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public SInt32NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, int[] array) -> {\n        for (int element : array) {\n          output.writeSInt32(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Integer[] array) -> {\n        for (Integer element : array) {\n          if (element != null) {\n            output.writeSInt32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Integer> collection) -> {\n        for (Integer element : collection) {\n          if (element != null) {\n            output.writeSInt32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            int parsedValue = Integer.parseInt(element, 10);\n            output.writeSInt32(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new SInt32NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SInt32PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt32PackedWriteSchemas {\n  private static class SInt32PackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public SInt32PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (int element : array) {\n            output.writePackedSInt32(element);\n          }\n        });\n      };\n\n      arrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (Integer element : array) {\n            if (element != null) {\n              output.writePackedSInt32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      collectionWriter = (o, value) -> {\n        if (value.isEmpty()) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, collection) -> {\n          for (Integer element : collection) {\n            if (element != null) {\n              output.writePackedSInt32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      stringArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (String element : array) {\n            if (element != null) {\n              int parsedValue = Integer.parseInt(element, 10);\n              output.writePackedSInt32(parsedValue);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new SInt32PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/UInt32NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt32NotPackedWriteSchemas {\n  private static class UInt32NotPackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public UInt32NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, int[] array) -> {\n        for (int element : array) {\n          output.writeUInt32(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Integer[] array) -> {\n        for (Integer element : array) {\n          if (element != null) {\n            output.writeUInt32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Integer> collection) -> {\n        for (Integer element : collection) {\n          if (element != null) {\n            output.writeUInt32(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            int parsedValue = Integer.parseInt(element, 10);\n            output.writeUInt32(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new UInt32NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/UInt32PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.ints;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt32PackedWriteSchemas {\n  private static class UInt32PackedWriters extends AbstractPrimitiveWriters<int[], Integer> {\n    public UInt32PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (int element : array) {\n            output.writePackedUInt32(element);\n          }\n        });\n      };\n\n      arrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (Integer element : array) {\n            if (element != null) {\n              output.writePackedUInt32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      collectionWriter = (o, value) -> {\n        if (value.isEmpty()) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, collection) -> {\n          for (Integer element : collection) {\n            if (element != null) {\n              output.writePackedUInt32(element);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n\n      stringArrayWriter = (o, value) -> {\n        if (value.length == 0) {\n          return;\n        }\n        o.writeObject(tag, tagSize, value, (output, array) -> {\n          for (String element : array) {\n            if (element != null) {\n              int parsedValue = Integer.parseInt(element, 10);\n              output.writePackedUInt32(parsedValue);\n              continue;\n            }\n\n            ProtoUtils.throwNotSupportNullElement(protoField);\n          }\n        });\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new UInt32PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/Fixed64NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed64NotPackedWriteSchemas {\n  private static class Fixed64NotPackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public Fixed64NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (output, array) -> {\n        for (long element : array) {\n          output.writeFixed64(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (output, array) -> {\n        for (Long element : array) {\n          if (element != null) {\n            output.writeFixed64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (output, collection) -> {\n        for (Long element : collection) {\n          if (element != null) {\n            output.writeFixed64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (output, array) -> {\n        for (String element : array) {\n          if (element != null) {\n            long parsedValue = Long.parseLong(element, 10);\n            output.writeFixed64(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas\n        .create(protoField, propertyDescriptor, new Fixed64NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/Fixed64PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed64PackedWriteSchemas {\n  private static class Fixed64PackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public Fixed64PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (long element : array) {\n              output.writePackedFixed64(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Long element : array) {\n              if (element != null) {\n                output.writePackedFixed64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Long element : collection) {\n              if (element != null) {\n                output.writePackedFixed64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                long parsedValue = Long.parseLong(element, 10);\n                output.writePackedFixed64(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new Fixed64PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/Int64NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int64NotPackedWriteSchemas {\n  private static class Int64NotPackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public Int64NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, long[] array) -> {\n        for (long element : array) {\n          output.writeInt64(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Long[] array) -> {\n        for (Long element : array) {\n          if (element != null) {\n            output.writeInt64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Long> collection) -> {\n        for (Long element : collection) {\n          if (element != null) {\n            output.writeInt64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            long parsedValue = Long.parseLong(element, 10);\n            output.writeInt64(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new Int64NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/Int64PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int64PackedWriteSchemas {\n  private static class Int64PackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public Int64PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (long element : array) {\n              output.writePackedInt64(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Long element : array) {\n              if (element != null) {\n                output.writePackedInt64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Long element : collection) {\n              if (element != null) {\n                output.writePackedInt64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                long parsedValue = Long.parseLong(element, 10);\n                output.writePackedInt64(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new Int64PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/SFixed64NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed64NotPackedWriteSchemas {\n  private static class SFixed64NotPackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public SFixed64NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, long[] array) -> {\n        for (long element : array) {\n          output.writeSFixed64(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Long[] array) -> {\n        for (Long element : array) {\n          if (element != null) {\n            output.writeSFixed64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Long> collection) -> {\n        for (Long element : collection) {\n          if (element != null) {\n            output.writeSFixed64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            long parsedValue = Long.parseLong(element, 10);\n            output.writeSFixed64(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas\n        .create(protoField, propertyDescriptor, new SFixed64NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/SFixed64PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed64PackedWriteSchemas {\n  private static class SFixed64PackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public SFixed64PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (long element : array) {\n              output.writePackedSFixed64(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Long element : array) {\n              if (element != null) {\n                output.writePackedSFixed64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Long element : collection) {\n              if (element != null) {\n                output.writePackedSFixed64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                long parsedValue = Long.parseLong(element, 10);\n                output.writePackedSFixed64(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new SFixed64PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/SInt64NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt64NotPackedWriteSchemas {\n  private static class SInt64NotPackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public SInt64NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, long[] array) -> {\n        for (long element : array) {\n          output.writeSInt64(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Long[] array) -> {\n        for (Long element : array) {\n          if (element != null) {\n            output.writeSInt64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Long> collection) -> {\n        for (Long element : collection) {\n          if (element != null) {\n            output.writeSInt64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            long parsedValue = Long.parseLong(element, 10);\n            output.writeSInt64(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new SInt64NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/SInt64PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt64PackedWriteSchemas {\n  private static class SInt64PackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public SInt64PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (long element : array) {\n              output.writePackedSInt64(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Long element : array) {\n              if (element != null) {\n                output.writePackedSInt64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Long element : collection) {\n              if (element != null) {\n                output.writePackedSInt64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                long parsedValue = Long.parseLong(element, 10);\n                output.writePackedSInt64(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new SInt64PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/UInt64NotPackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport java.util.Collection;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt64NotPackedWriteSchemas {\n  private static class UInt64NotPackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public UInt64NotPackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (OutputEx output, long[] array) -> {\n        for (long element : array) {\n          output.writeUInt64(tag, tagSize, element);\n        }\n      };\n\n      arrayWriter = (OutputEx output, Long[] array) -> {\n        for (Long element : array) {\n          if (element != null) {\n            output.writeUInt64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      collectionWriter = (OutputEx output, Collection<Long> collection) -> {\n        for (Long element : collection) {\n          if (element != null) {\n            output.writeUInt64(tag, tagSize, element);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n\n      stringArrayWriter = (OutputEx output, String[] array) -> {\n        for (String element : array) {\n          if (element != null) {\n            long parsedValue = Long.parseLong(element, 10);\n            output.writeUInt64(tag, tagSize, parsedValue);\n            continue;\n          }\n\n          ProtoUtils.throwNotSupportNullElement(protoField);\n        }\n      };\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new UInt64NotPackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/longs/UInt64PackedWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.impl.longs;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.AbstractPrimitiveWriters;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.repeated.RepeatedPrimitiveWriteSchemas;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt64PackedWriteSchemas {\n  private static class UInt64PackedWriters extends AbstractPrimitiveWriters<long[], Long> {\n    public UInt64PackedWriters(Field protoField) {\n      super(protoField);\n\n      primitiveArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (long element : array) {\n              output.writePackedUInt64(element);\n            }\n          });\n\n      arrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (Long element : array) {\n              if (element != null) {\n                output.writePackedUInt64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      collectionWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, collection) -> {\n            for (Long element : collection) {\n              if (element != null) {\n                output.writePackedUInt64(element);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n\n      stringArrayWriter = (o, value) ->\n          o.writeObject(tag, tagSize, value, (output, array) -> {\n            for (String element : array) {\n              if (element != null) {\n                long parsedValue = Long.parseLong(element, 10);\n                output.writePackedUInt64(parsedValue);\n                continue;\n              }\n\n              ProtoUtils.throwNotSupportNullElement(protoField);\n            }\n          });\n    }\n  }\n\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    return RepeatedPrimitiveWriteSchemas.create(protoField, propertyDescriptor, new UInt64PackedWriters(protoField));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/BoolWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.BoolGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BoolWriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (boolean.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new BooleanPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Boolean.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new BooleanSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new BooleanSchema<>(protoField, propertyDescriptor);\n  }\n\n  private static class BooleanDynamicSchema<T> extends FieldSchema<T> {\n    public BooleanDynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Boolean) {\n        output.writeScalarBool(tag, tagSize, (boolean) value);\n        return;\n      }\n\n      if (value instanceof Number) {\n        output.writeScalarBool(tag, tagSize, ((Number) value).longValue() == 1);\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        boolean parsedValue = Boolean.parseBoolean(((String[]) value)[0]);\n        output.writeScalarBool(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        boolean parsedValue = Boolean.parseBoolean((String) value);\n        output.writeScalarBool(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class BooleanSchema<T> extends BooleanDynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public BooleanSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class BooleanPrimitiveSchema<T> extends BooleanDynamicSchema<T> {\n    private final BoolGetter<T> primitiveGetter;\n\n    public BooleanPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      boolean value = primitiveGetter.get(message);\n      output.writeScalarBool(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/BytesWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class BytesWriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (byte[].class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new BytesSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new BytesSchema<>(protoField, propertyDescriptor);\n  }\n\n  private static class BytesDynamicSchema<T> extends FieldSchema<T> {\n    public BytesDynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof byte[]) {\n        output.writeByteArray(tag, tagSize, (byte[]) value);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class BytesSchema<T> extends BytesDynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public BytesSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/DoubleWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.DoubleGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class DoubleWriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (double.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new DoublePrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Double.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new DoubleSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new DoubleSchema<>(protoField, propertyDescriptor);\n  }\n\n  private static class DoubleDynamicSchema<T> extends FieldSchema<T> {\n    public DoubleDynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarDouble(tag, tagSize, ((Number) value).doubleValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        double parsedValue = Double.parseDouble(((String[]) value)[0]);\n        output.writeScalarDouble(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        double parsedValue = Double.parseDouble((String) value);\n        output.writeScalarDouble(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class DoubleSchema<T> extends DoubleDynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public DoubleSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class DoublePrimitiveSchema<T> extends DoubleDynamicSchema<T> {\n    private final DoubleGetter<T> primitiveGetter;\n\n    public DoublePrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      double value = primitiveGetter.get(message);\n      output.writeScalarDouble(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/EnumWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.base.DynamicEnum;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\nimport org.apache.servicecomb.foundation.protobuf.internal.schema.EnumMeta;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class EnumWriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (propertyDescriptor.getJavaType().isEnumType()) {\n      return new EnumSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new EnumSchema<>(protoField, propertyDescriptor);\n  }\n\n  private static class EnumDynamicSchema<T> extends FieldSchema<T> {\n    private final EnumMeta enumMeta;\n\n    public EnumDynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n      this.enumMeta = new EnumMeta(protoField, javaType);\n    }\n\n    protected final void numberWrite(OutputEx output, Number value) throws IOException {\n      int enumValue = value.intValue();\n      if (!enumMeta.containsValue(enumValue)) {\n        throw new IllegalStateException(\n            String.format(\"invalid enum value %d for proto %s, field=%s:%s\",\n                enumValue,\n                protoField.getTypeName(),\n                ((Type) protoField.getParent()).getCanonicalName(),\n                protoField.getName()));\n      }\n\n      output.writeScalarInt32(tag, tagSize, enumValue);\n    }\n\n    protected final void stringWrite(OutputEx output, String enumName) throws IOException {\n      Integer enumValue = enumMeta.getValueByName(enumName);\n      if (enumValue == null) {\n        throw new IllegalStateException(\n            String.format(\"invalid enum name %s for proto %s, field=%s:%s\",\n                enumName,\n                protoField.getTypeName(),\n                ((Type) protoField.getParent()).getCanonicalName(),\n                protoField.getName()));\n      }\n\n      output.writeScalarInt32(tag, tagSize, enumValue);\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Enum) {\n        stringWrite(output, ((Enum<?>) value).name());\n        return;\n      }\n\n      if (value instanceof DynamicEnum) {\n        // protobuf can not support unknown enum, because protobuf encode enum as tag value\n        writeTo(output, ((DynamicEnum<?>) value).getValue());\n        return;\n      }\n\n      if (value instanceof Number) {\n        // need to check if it is a valid number\n        // because maybe come from http request\n        numberWrite(output, ((Number) value).intValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n\n        stringWrite(output, ((String[]) value)[0]);\n        return;\n      }\n\n      if (value instanceof String) {\n        stringWrite(output, (String) value);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class EnumSchema<T> extends EnumDynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public EnumSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Fixed32WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed32WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (int.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new Fixed32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new Fixed32Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new Fixed32Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class Fixed32DynamicSchema<T> extends FieldSchema<T> {\n    public Fixed32DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarFixed32(tag, tagSize, ((Number) value).intValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        int parsedValue = Integer.parseInt(((String[]) value)[0], 10);\n        output.writeScalarFixed32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        int parsedValue = Integer.parseInt((String) value, 10);\n        output.writeScalarFixed32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class Fixed32Schema<T> extends Fixed32DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public Fixed32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class Fixed32PrimitiveSchema<T> extends Fixed32DynamicSchema<T> {\n    private final IntGetter<T> primitiveGetter;\n\n    public Fixed32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      int value = primitiveGetter.get(message);\n      output.writeScalarFixed32(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Fixed64WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Fixed64WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new Fixed64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new Fixed64Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new Fixed64Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class Fixed64DynamicSchema<T> extends FieldSchema<T> {\n    public Fixed64DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarFixed64(tag, tagSize, ((Number) value).longValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        long parsedValue = Long.parseLong(((String[]) value)[0], 10);\n        output.writeScalarFixed64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        long parsedValue = Long.parseLong((String) value, 10);\n        output.writeScalarFixed64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class Fixed64Schema<T> extends Fixed64DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public Fixed64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class Fixed64PrimitiveSchema<T> extends Fixed64DynamicSchema<T> {\n    private final LongGetter<T> primitiveGetter;\n\n    public Fixed64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      long value = primitiveGetter.get(message);\n      output.writeScalarFixed64(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/FloatWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.FloatGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class FloatWriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (float.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new FloatPrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Float.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new FloatSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new FloatSchema<>(protoField, propertyDescriptor);\n  }\n\n  private static class FloatDynamicSchema<T> extends FieldSchema<T> {\n    public FloatDynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarFloat(tag, tagSize, ((Number) value).floatValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        float parsedValue = Float.parseFloat(((String[]) value)[0]);\n        output.writeScalarFloat(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        float parsedValue = Float.parseFloat((String) value);\n        output.writeScalarFloat(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class FloatSchema<T> extends FloatDynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public FloatSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = javaType.isPrimitive() ? null : propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class FloatPrimitiveSchema<T> extends FloatDynamicSchema<T> {\n    private final FloatGetter<T> primitiveGetter;\n\n    public FloatPrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      float value = primitiveGetter.get(message);\n      output.writeScalarFloat(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Int32WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.ByteGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.ShortGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic final class Int32WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (int.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new IntFieldInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (short.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new ShortFieldInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (byte.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new ByteFieldInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new Int32Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class Int32DynamicSchema<T> extends FieldSchema<T> {\n    public Int32DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarInt32(tag, tagSize, ((Number) value).intValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        int parsedValue = Integer.parseInt(((String[]) value)[0], 10);\n        output.writeScalarInt32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        if (((String) value).isEmpty()) {\n          return;\n        }\n        int parsedValue = Integer.parseInt((String) value, 10);\n        output.writeScalarInt32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class Int32Schema<T> extends Int32DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public Int32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static final class IntFieldInt32PrimitiveSchema<T> extends Int32DynamicSchema<T> {\n    private final IntGetter<T> primitiveGetter;\n\n    public IntFieldInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public void getAndWriteTo(OutputEx output, T message) throws IOException {\n      int value = primitiveGetter.get(message);\n      output.writeScalarInt32(tag, tagSize, value);\n    }\n  }\n\n  private static final class ShortFieldInt32PrimitiveSchema<T> extends Int32DynamicSchema<T> {\n    private final ShortGetter<T> primitiveGetter;\n\n    public ShortFieldInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public void getAndWriteTo(OutputEx output, T message) throws IOException {\n      short value = primitiveGetter.get(message);\n      output.writeScalarInt32(tag, tagSize, value);\n    }\n  }\n\n  private static final class ByteFieldInt32PrimitiveSchema<T> extends Int32DynamicSchema<T> {\n    private final ByteGetter<T> primitiveGetter;\n\n    public ByteFieldInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public void getAndWriteTo(OutputEx output, T message) throws IOException {\n      byte value = primitiveGetter.get(message);\n      output.writeScalarInt32(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Int64WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.time.OffsetDateTime;\nimport java.time.ZoneOffset;\nimport java.time.temporal.ChronoField;\nimport java.util.Date;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class Int64WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new Int64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new Int64Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class Int64DynamicSchema<T> extends FieldSchema<T> {\n    public Int64DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarInt64(tag, tagSize, ((Number) value).longValue());\n        return;\n      }\n\n      if (value instanceof Date) {\n        long parsedValue = ((Date) value).getTime();\n        output.writeScalarInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof LocalDate) {\n        long parsedValue = ((LocalDate) value).getLong(ChronoField.EPOCH_DAY);\n        output.writeScalarInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof LocalDateTime) {\n        long parsedValue = ((LocalDateTime) value).toInstant(ZoneOffset.UTC).toEpochMilli();\n        output.writeScalarInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        long parsedValue;\n        if (((String) value).contains(\":\")) {\n          // from edge, ISO8601 date time, e.g. 2022-05-31T09:16:38.941Z\n          OffsetDateTime offsetDateTime = OffsetDateTime.parse((String) value);\n          parsedValue = offsetDateTime.toInstant().toEpochMilli();\n        } else {\n          parsedValue = Long.parseLong((String) value, 10);\n        }\n        output.writeScalarInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        long parsedValue = Long.parseLong(((String[]) value)[0], 10);\n        output.writeScalarInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class Int64Schema<T> extends Int64DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public Int64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        this.writeTo(output, value);\n      }\n    }\n  }\n\n  private static final class Int64PrimitiveSchema<T> extends Int64DynamicSchema<T> {\n    private final LongGetter<T> primitiveGetter;\n\n    public Int64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public void getAndWriteTo(OutputEx output, T message) throws IOException {\n      long value = primitiveGetter.get(message);\n      output.writeScalarInt64(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/SFixed32WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed32WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (int.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SFixed32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SFixed32Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new SFixed32Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class SFixed32DynamicSchema<T> extends FieldSchema<T> {\n    public SFixed32DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarSFixed32(tag, tagSize, ((Number) value).intValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        int parsedValue = Integer.parseInt(((String[]) value)[0], 10);\n        output.writeScalarSFixed32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        int parsedValue = Integer.parseInt((String) value, 10);\n        output.writeScalarSFixed32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class SFixed32Schema<T> extends SFixed32DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public SFixed32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class SFixed32PrimitiveSchema<T> extends SFixed32DynamicSchema<T> {\n    private final IntGetter<T> primitiveGetter;\n\n    public SFixed32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      int value = primitiveGetter.get(message);\n      output.writeScalarSFixed32(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/SFixed64WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SFixed64WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SFixed64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SFixed64Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new SFixed64Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class SFixed64DynamicSchema<T> extends FieldSchema<T> {\n    public SFixed64DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarSFixed64(tag, tagSize, ((Number) value).longValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        long parsedValue = Long.parseLong(((String[]) value)[0], 10);\n        output.writeScalarSFixed64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        long parsedValue = Long.parseLong((String) value, 10);\n        output.writeScalarSFixed64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class SFixed64Schema<T> extends SFixed64DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public SFixed64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class SFixed64PrimitiveSchema<T> extends SFixed64DynamicSchema<T> {\n    private final LongGetter<T> primitiveGetter;\n\n    public SFixed64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      long value = primitiveGetter.get(message);\n      output.writeScalarSFixed64(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/SInt32WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt32WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (int.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SInt32Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new SInt32Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class SInt32DynamicSchema<T> extends FieldSchema<T> {\n    public SInt32DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarSInt32(tag, tagSize, ((Number) value).intValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        int parsedValue = Integer.parseInt(((String[]) value)[0], 10);\n        output.writeScalarSInt32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        int parsedValue = Integer.parseInt((String) value, 10);\n        output.writeScalarSInt32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class SInt32Schema<T> extends SInt32DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public SInt32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class SInt32PrimitiveSchema<T> extends SInt32DynamicSchema<T> {\n    private final IntGetter<T> primitiveGetter;\n\n    public SInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      int value = primitiveGetter.get(message);\n      output.writeScalarSInt32(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/SInt64WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class SInt64WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SInt64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new SInt64Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new SInt64Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class SInt64DynamicSchema<T> extends FieldSchema<T> {\n    public SInt64DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarSInt64(tag, tagSize, ((Number) value).longValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        long parsedValue = Long.parseLong(((String[]) value)[0], 10);\n        output.writeScalarSInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        long parsedValue = Long.parseLong((String) value, 10);\n        output.writeScalarSInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class SInt64Schema<T> extends SInt64DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public SInt64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class SInt64PrimitiveSchema<T> extends SInt64DynamicSchema<T> {\n    private final LongGetter<T> primitiveGetter;\n\n    public SInt64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      long value = primitiveGetter.get(message);\n      output.writeScalarSInt64(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/StringWriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.CharGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class StringWriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (char.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new CharFieldStringSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (String.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new StringSchema<>(protoField, propertyDescriptor);\n    }\n\n    return new StringSchema<>(protoField, propertyDescriptor);\n  }\n\n  private static class StringDynamicSchema<T> extends FieldSchema<T> {\n    public StringDynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof String) {\n        output.writeScalarString(tag, tagSize, (String) value);\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        output.writeScalarString(tag, tagSize, ((String[]) value)[0]);\n        return;\n      }\n\n      if (value instanceof Character) {\n        output.writeScalarString(tag, tagSize, String.valueOf((char) value));\n        return;\n      }\n\n      if (value instanceof BigDecimal || value instanceof BigInteger) {\n        output.writeScalarString(tag, tagSize, value.toString());\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class StringSchema<T> extends StringDynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public StringSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class CharFieldStringSchema<T> extends StringDynamicSchema<T> {\n    protected final CharGetter<T> getter;\n\n    public CharFieldStringSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      char value = getter.get(message);\n      writeTo(output, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/UInt32WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt32WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (int.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new UInt32PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Integer.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new UInt32Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new UInt32Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class UInt32DynamicSchema<T> extends FieldSchema<T> {\n    public UInt32DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarUInt32(tag, tagSize, ((Number) value).intValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        int parsedValue = Integer.parseInt(((String[]) value)[0], 10);\n        output.writeScalarUInt32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        int parsedValue = Integer.parseInt((String) value, 10);\n        output.writeScalarUInt32(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class UInt32Schema<T> extends UInt32DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public UInt32Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class UInt32PrimitiveSchema<T> extends UInt32DynamicSchema<T> {\n    private final IntGetter<T> primitiveGetter;\n\n    public UInt32PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      int value = primitiveGetter.get(message);\n      output.writeScalarUInt32(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/UInt64WriteSchemas.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.LongGetter;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;\n\nimport io.protostuff.OutputEx;\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.runtime.FieldSchema;\n\npublic class UInt64WriteSchemas {\n  public static <T> FieldSchema<T> create(Field protoField, PropertyDescriptor propertyDescriptor) {\n    if (long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new UInt64PrimitiveSchema<>(protoField, propertyDescriptor);\n    }\n\n    if (Long.class.equals(propertyDescriptor.getJavaType().getRawClass())) {\n      return new UInt64Schema<>(protoField, propertyDescriptor);\n    }\n\n    return new UInt64Schema<>(protoField, propertyDescriptor);\n  }\n\n  private static class UInt64DynamicSchema<T> extends FieldSchema<T> {\n    public UInt64DynamicSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor.getJavaType());\n    }\n\n    @Override\n    public final void writeTo(OutputEx output, Object value) throws IOException {\n      if (value instanceof Number) {\n        output.writeScalarUInt64(tag, tagSize, ((Number) value).longValue());\n        return;\n      }\n\n      if (value instanceof String[]) {\n        if (((String[]) value).length == 0) {\n          return;\n        }\n        long parsedValue = Long.parseLong(((String[]) value)[0], 10);\n        output.writeScalarUInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      if (value instanceof String) {\n        long parsedValue = Long.parseLong((String) value, 10);\n        output.writeScalarUInt64(tag, tagSize, parsedValue);\n        return;\n      }\n\n      ProtoUtils.throwNotSupportWrite(protoField, value);\n    }\n  }\n\n  private static class UInt64Schema<T> extends UInt64DynamicSchema<T> {\n    protected final Getter<T, Object> getter;\n\n    public UInt64Schema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      this.getter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      Object value = getter.get(message);\n      if (value != null) {\n        writeTo(output, value);\n      }\n    }\n  }\n\n  private static class UInt64PrimitiveSchema<T> extends UInt64DynamicSchema<T> {\n    private final LongGetter<T> primitiveGetter;\n\n    public UInt64PrimitiveSchema(Field protoField, PropertyDescriptor propertyDescriptor) {\n      super(protoField, propertyDescriptor);\n\n      primitiveGetter = propertyDescriptor.getGetter();\n    }\n\n    @Override\n    public final void getAndWriteTo(OutputEx output, T message) throws IOException {\n      long value = primitiveGetter.get(message);\n      output.writeScalarUInt64(tag, tagSize, value);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/notice.txt",
    "content": "1.List<List>或List<Map>这种结构是PB不支持的\n  类似的场景，只要PB文件解析出错，说明本schema不支持PB相关的传输：highway/grpc等等\n2.反序列化，支持java类型为数组，不一定要求是Collection\n3.原子类型的序列化/反序列化,(主要是原子数组？)\n\n\n3.应该只有文件相关的场景，才是真正的不支持\n\n-------------\n优化：\n  1.支持用户泛型\n  2.\n\n不兼容：\n  1.数组编码规则从protoStuff变成标准的protobuf\n\n不确定：\n  1.List<List>/List<Map>/Map<String, List<>>/Map<String, Map>规则应该也有变化，是否有变化，从protoStuff变成标准protobuf\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/resources/google/protobuf/any.proto",
    "content": "// Protocol Buffers - Google's data interchange format\n// Copyright 2008 Google Inc.  All rights reserved.\n// https://developers.google.com/protocol-buffers/\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nsyntax = \"proto3\";\n\npackage google.protobuf;\n\noption go_package = \"google.golang.org/protobuf/types/known/anypb\";\noption java_package = \"com.google.protobuf\";\noption java_outer_classname = \"AnyProto\";\noption java_multiple_files = true;\noption objc_class_prefix = \"GPB\";\noption csharp_namespace = \"Google.Protobuf.WellKnownTypes\";\n\n// `Any` contains an arbitrary serialized protocol buffer message along with a\n// URL that describes the type of the serialized message.\n//\n// Protobuf library provides support to pack/unpack Any values in the form\n// of utility functions or additional generated methods of the Any type.\n//\n// Example 1: Pack and unpack a message in C++.\n//\n//     Foo foo = ...;\n//     Any any;\n//     any.PackFrom(foo);\n//     ...\n//     if (any.UnpackTo(&foo)) {\n//       ...\n//     }\n//\n// Example 2: Pack and unpack a message in Java.\n//\n//     Foo foo = ...;\n//     Any any = Any.pack(foo);\n//     ...\n//     if (any.is(Foo.class)) {\n//       foo = any.unpack(Foo.class);\n//     }\n//     // or ...\n//     if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n//       foo = any.unpack(Foo.getDefaultInstance());\n//     }\n//\n//  Example 3: Pack and unpack a message in Python.\n//\n//     foo = Foo(...)\n//     any = Any()\n//     any.Pack(foo)\n//     ...\n//     if any.Is(Foo.DESCRIPTOR):\n//       any.Unpack(foo)\n//       ...\n//\n//  Example 4: Pack and unpack a message in Go\n//\n//      foo := &pb.Foo{...}\n//      any, err := anypb.New(foo)\n//      if err != nil {\n//        ...\n//      }\n//      ...\n//      foo := &pb.Foo{}\n//      if err := any.UnmarshalTo(foo); err != nil {\n//        ...\n//      }\n//\n// The pack methods provided by protobuf library will by default use\n// 'type.googleapis.com/full.type.name' as the type URL and the unpack\n// methods only use the fully qualified type name after the last '/'\n// in the type URL, for example \"foo.bar.com/x/y.z\" will yield type\n// name \"y.z\".\n//\n// JSON\n// ====\n// The JSON representation of an `Any` value uses the regular\n// representation of the deserialized, embedded message, with an\n// additional field `@type` which contains the type URL. Example:\n//\n//     package google.profile;\n//     message Person {\n//       string first_name = 1;\n//       string last_name = 2;\n//     }\n//\n//     {\n//       \"@type\": \"type.googleapis.com/google.profile.Person\",\n//       \"firstName\": <string>,\n//       \"lastName\": <string>\n//     }\n//\n// If the embedded message type is well-known and has a custom JSON\n// representation, that representation will be embedded adding a field\n// `value` which holds the custom JSON in addition to the `@type`\n// field. Example (for message [google.protobuf.Duration][]):\n//\n//     {\n//       \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n//       \"value\": \"1.212s\"\n//     }\n//\nmessage Any {\n  // A URL/resource name that uniquely identifies the type of the serialized\n  // protocol buffer message. This string must contain at least\n  // one \"/\" character. The last segment of the URL's path must represent\n  // the fully qualified name of the type (as in\n  // `path/google.protobuf.Duration`). The name should be in a canonical form\n  // (e.g., leading \".\" is not accepted).\n  //\n  // In practice, teams usually precompile into the binary all types that they\n  // expect it to use in the context of Any. However, for URLs which use the\n  // scheme `http`, `https`, or no scheme, one can optionally set up a type\n  // server that maps type URLs to message definitions as follows:\n  //\n  // * If no scheme is provided, `https` is assumed.\n  // * An HTTP GET on the URL must yield a [google.protobuf.Type][]\n  //   value in binary format, or produce an error.\n  // * Applications are allowed to cache lookup results based on the\n  //   URL, or have them precompiled into a binary to avoid any\n  //   lookup. Therefore, binary compatibility needs to be preserved\n  //   on changes to types. (Use versioned type names to manage\n  //   breaking changes.)\n  //\n  // Note: this functionality is not currently available in the official\n  // protobuf release, and it is not used for type URLs beginning with\n  // type.googleapis.com.\n  //\n  // Schemes other than `http`, `https` (or the empty scheme) might be\n  // used with implementation specific semantics.\n  //\n  string type_url = 1;\n\n  // Must be a valid serialized protocol buffer of the above specified type.\n  bytes value = 2;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/main/resources/google/protobuf/empty.proto",
    "content": "// Protocol Buffers - Google's data interchange format\n// Copyright 2008 Google Inc.  All rights reserved.\n// https://developers.google.com/protocol-buffers/\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nsyntax = \"proto3\";\n\npackage google.protobuf;\n\noption go_package = \"google.golang.org/protobuf/types/known/emptypb\";\noption java_package = \"com.google.protobuf\";\noption java_outer_classname = \"EmptyProto\";\noption java_multiple_files = true;\noption objc_class_prefix = \"GPB\";\noption csharp_namespace = \"Google.Protobuf.WellKnownTypes\";\noption cc_enable_arenas = true;\n\n// A generic empty message that you can re-use to avoid defining duplicated\n// empty messages in your APIs. A typical example is to use it as the request\n// or the response type of an API method. For instance:\n//\n//     service Foo {\n//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);\n//     }\n//\nmessage Empty {}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/TestISODateTimeParsing.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf;\n\nimport java.text.SimpleDateFormat;\nimport java.time.OffsetDateTime;\nimport java.util.Date;\nimport java.util.TimeZone;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestISODateTimeParsing {\n  @Test\n  public void testParseStringToDate() {\n    SimpleDateFormat sdf = new SimpleDateFormat(\"YYYY-MM-DD'T'hh:mm:ssZ\");\n    sdf.setTimeZone(TimeZone.getTimeZone(\"EST\"));\n\n    OffsetDateTime offsetDateTime = OffsetDateTime.parse(\"2022-05-31T09:16:38.941Z\");\n    Date d = Date.from(offsetDateTime.toInstant());\n    String date = sdf.format(d);\n    Assertions.assertEquals(\"2022-05-151T04:16:38-0500\", date);\n\n    offsetDateTime = OffsetDateTime.parse(\"2022-05-31T09:16:38.941+00:00\");\n    d = Date.from(offsetDateTime.toInstant());\n    date = sdf.format(d);\n    Assertions.assertEquals(\"2022-05-151T04:16:38-0500\", date);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/compatibility/TestCompatibilityOfImplementations.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.protobuf.compatibility;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\nimport org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.Protobuf;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.ScbWeak;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestCompatibilityOfImplementations {\n  static final ProtubufCodecEngine scbWeak = new ScbWeak();\n\n  static final ProtubufCodecEngine protobuf = new Protobuf();\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void testEmptyCollection() throws Exception {\n    ProtobufRoot.Root.Builder builder = ProtobufRoot.Root.newBuilder();\n    byte[] values = protobuf.serialize(builder);\n    Assertions.assertEquals(values.length, 0);\n    ProtobufRoot.Root.Builder o = (ProtobufRoot.Root.Builder) protobuf.deserialize(values);\n    Assertions.assertTrue(o.getFixed32SNotPackedList().isEmpty());\n\n    builder = ProtobufRoot.Root.newBuilder().addFixed32SNotPacked(30);\n    values = protobuf.serialize(builder);\n    Assertions.assertArrayEquals(new byte[] {(byte) -123, (byte) 6, (byte) 30, (byte) 0, (byte) 0, (byte) 0}, values);\n    o = (ProtobufRoot.Root.Builder) protobuf.deserialize(values);\n    Assertions.assertEquals(30, (int) o.getFixed32SNotPackedList().get(0));\n\n    Root root = new Root();\n    root.setFixed32sNotPacked(new ArrayList<>());\n    values = scbWeak.serialize(root);\n    Assertions.assertEquals(values.length, 0);\n    Map<String, Object> newRootMap = (Map<String, Object>) scbWeak.deserialize(values);\n    Assertions.assertNull(newRootMap.get(\"fixed32sNotPacked\")); // This is different , because depends on default model initializer\n\n    List<Integer> iValues = new ArrayList<>();\n    iValues.add(30);\n    root.setFixed32sNotPacked(iValues);\n    values = scbWeak.serialize(root);\n    Assertions.assertArrayEquals(new byte[] {(byte) -123, (byte) 6, (byte) 30, (byte) 0, (byte) 0, (byte) 0}, values);\n    newRootMap = (Map<String, Object>) scbWeak.deserialize(values);\n    Assertions.assertEquals(30, (int) ((List<Integer>) newRootMap.get(\"fixed32sNotPacked\")).get(0));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestModelWrap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal;\n\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\nimport io.vertx.core.json.Json;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestModelWrap {\n  protected static ProtoMapperFactory factory = new ProtoMapperFactory();\n\n  protected static ProtoMapper modelProtoMapper = factory.createFromName(\"model.proto\");\n\n  public static class User {\n    public String name;\n\n    public User(String name) {\n      this.name = name;\n    }\n  }\n\n  static User user = new User(\"uName\");\n\n  public static class PojoModel {\n    public List<List<User>> listListUser;\n\n    public List<Map<String, User>> listMapUser;\n\n    public Map<String, List<User>> mapListUser;\n\n    public Map<String, Map<String, User>> mapMapUser;\n\n    public List<List<List<User>>> listListListUser;\n\n    public List<List<Map<String, User>>> listListMapUser;\n\n    public List<Map<String, List<User>>> listMapListUser;\n\n    public List<Map<String, Map<String, User>>> listMapMapUser;\n\n    public Map<String, List<List<User>>> mapListListUser;\n\n    public Map<String, List<Map<String, User>>> mapListMapUser;\n\n    public Map<String, Map<String, List<User>>> mapMapListUser;\n\n    public Map<String, Map<String, Map<String, User>>> mapMapMapUser;\n\n    public void init() {\n      List<User> listUser = Arrays.asList(user, user);\n\n      Map<String, User> mapUser = new LinkedHashMap<>();\n      mapUser.put(\"k1\", user);\n      mapUser.put(\"k2\", user);\n\n      listListUser = Arrays.asList(listUser, listUser);\n      listMapUser = Arrays.asList(mapUser, mapUser);\n\n      mapListUser = new LinkedHashMap<>();\n      mapListUser.put(\"k1\", listUser);\n      mapListUser.put(\"k2\", listUser);\n\n      mapMapUser = new LinkedHashMap<>();\n      mapMapUser.put(\"k1\", mapUser);\n      mapMapUser.put(\"k2\", mapUser);\n\n      listListListUser = Arrays.asList(listListUser, listListUser);\n      listListMapUser = Arrays.asList(listMapUser, listMapUser);\n      listMapListUser = Arrays.asList(mapListUser, mapListUser);\n      listMapMapUser = Arrays.asList(mapMapUser, mapMapUser);\n\n      mapListListUser = new LinkedHashMap<>();\n      mapListListUser.put(\"k1\", listListUser);\n      mapListListUser.put(\"k2\", listListUser);\n\n      mapListMapUser = new LinkedHashMap<>();\n      mapListMapUser.put(\"k1\", listMapUser);\n      mapListMapUser.put(\"k2\", listMapUser);\n\n      mapMapListUser = new LinkedHashMap<>();\n      mapMapListUser.put(\"k1\", mapListUser);\n      mapMapListUser.put(\"k2\", mapListUser);\n\n      mapMapMapUser = new LinkedHashMap<>();\n      mapMapMapUser.put(\"k1\", mapMapUser);\n      mapMapMapUser.put(\"k2\", mapMapUser);\n    }\n  }\n\n  public static class ProtoModel {\n    public List<ProtoListUser> listListUser;\n\n    public List<ProtoMapUser> listMapUser;\n\n    public Map<String, ProtoListUser> mapListUser;\n\n    public Map<String, ProtoMapUser> mapMapUser;\n\n    public List<ProtoListListUser> listListListUser;\n\n    public List<ProtoListMapUser> listListMapUser;\n\n    public List<ProtoMapListUser> listMapListUser;\n\n    public List<ProtoMapMapUser> listMapMapUser;\n\n    public Map<String, ProtoListListUser> mapListListUser;\n\n    public Map<String, ProtoListMapUser> mapListMapUser;\n\n    public Map<String, ProtoMapListUser> mapMapListUser;\n\n    public Map<String, ProtoMapMapUser> mapMapMapUser;\n\n    public void init() {\n      ProtoListUser protoListUser = new ProtoListUser();\n      protoListUser.init();\n\n      ProtoMapUser protoMapUser = new ProtoMapUser();\n      protoMapUser.init();\n\n      ProtoListListUser protoListListUser = new ProtoListListUser();\n      protoListListUser.init();\n\n      ProtoListMapUser protoListMapUser = new ProtoListMapUser();\n      protoListMapUser.init();\n\n      ProtoMapListUser protoMapListUser = new ProtoMapListUser();\n      protoMapListUser.init();\n\n      ProtoMapMapUser protoMapMapUser = new ProtoMapMapUser();\n      protoMapMapUser.init();\n\n      listListUser = Arrays.asList(protoListUser, protoListUser);\n      listMapUser = Arrays.asList(protoMapUser, protoMapUser);\n      mapListUser = new LinkedHashMap<>();\n      mapListUser.put(\"k1\", protoListUser);\n      mapListUser.put(\"k2\", protoListUser);\n\n      mapMapUser = new LinkedHashMap<>();\n      mapMapUser.put(\"k1\", protoMapUser);\n      mapMapUser.put(\"k2\", protoMapUser);\n\n      listListListUser = Arrays.asList(protoListListUser, protoListListUser);\n      listListMapUser = Arrays.asList(protoListMapUser, protoListMapUser);\n      listMapListUser = Arrays.asList(protoMapListUser, protoMapListUser);\n      listMapMapUser = Arrays.asList(protoMapMapUser, protoMapMapUser);\n\n      mapListListUser = new LinkedHashMap<>();\n      mapListListUser.put(\"k1\", protoListListUser);\n      mapListListUser.put(\"k2\", protoListListUser);\n\n      mapListMapUser = new LinkedHashMap<>();\n      mapListMapUser.put(\"k1\", protoListMapUser);\n      mapListMapUser.put(\"k2\", protoListMapUser);\n\n      mapMapListUser = new LinkedHashMap<>();\n      mapMapListUser.put(\"k1\", protoMapListUser);\n      mapMapListUser.put(\"k2\", protoMapListUser);\n\n      mapMapMapUser = new LinkedHashMap<>();\n      mapMapMapUser.put(\"k1\", protoMapMapUser);\n      mapMapMapUser.put(\"k2\", protoMapMapUser);\n    }\n  }\n\n  public static class ProtoListListUser {\n    public List<ProtoListUser> value;\n\n    public void init() {\n      ProtoListUser protoListUser = new ProtoListUser();\n      protoListUser.init();\n      value = Arrays.asList(protoListUser, protoListUser);\n    }\n  }\n\n  public static class ProtoListMapUser {\n    public List<ProtoMapUser> value;\n\n    public void init() {\n      ProtoMapUser protoMapUser = new ProtoMapUser();\n      protoMapUser.init();\n      value = Arrays.asList(protoMapUser, protoMapUser);\n    }\n  }\n\n  public static class ProtoMapListUser {\n    public Map<String, ProtoListUser> value;\n\n    public void init() {\n      ProtoListUser protoListUser = new ProtoListUser();\n      protoListUser.init();\n      value = new LinkedHashMap<>();\n      value.put(\"k1\", protoListUser);\n      value.put(\"k2\", protoListUser);\n    }\n  }\n\n  public static class ProtoMapMapUser {\n    public Map<String, ProtoMapUser> value;\n\n    public void init() {\n      ProtoMapUser protoMapUser = new ProtoMapUser();\n      protoMapUser.init();\n      value = new LinkedHashMap<>();\n      value.put(\"k1\", protoMapUser);\n      value.put(\"k2\", protoMapUser);\n    }\n  }\n\n  public static class ProtoListUser {\n    public List<User> value;\n\n    public void init() {\n      value = Arrays.asList(user, user);\n    }\n  }\n\n  public static class ProtoMapUser {\n    public Map<String, User> value;\n\n    public void init() {\n      value = new LinkedHashMap<>();\n      value.put(\"k1\", user);\n      value.put(\"k2\", user);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void pojoModel() throws IOException {\n    RootSerializer pojoSerializer = modelProtoMapper.createRootSerializer(\"PojoModel\", PojoModel.class);\n    RootDeserializer<Map<String, Object>> pojoMapDeserializer = modelProtoMapper\n        .createRootDeserializer(\"PojoModel\", Map.class);\n    RootDeserializer<PojoModel> pojoModelDeserializer = modelProtoMapper\n        .createRootDeserializer(\"PojoModel\", PojoModel.class);\n\n    RootSerializer protoSerializer = modelProtoMapper.createRootSerializer(\"ProtoModel\", ProtoModel.class);\n    RootDeserializer<Map<String, Object>> protoMapDeserializer = modelProtoMapper\n        .createRootDeserializer(\"ProtoModel\", Map.class);\n    RootDeserializer<ProtoModel> protoModelDeserializer = modelProtoMapper\n        .createRootDeserializer(\"ProtoModel\", ProtoModel.class);\n\n    PojoModel pojoModel = new PojoModel();\n    pojoModel.init();\n    String jsonPojoModel = Json.encode(pojoModel);\n    Map<String, Object> mapFromPojoModel = (Map<String, Object>) Json.decodeValue(jsonPojoModel, Map.class);\n\n    ProtoModel protoModel = new ProtoModel();\n    protoModel.init();\n    String jsonProtoModel = Json.encode(protoModel);\n    Map<String, Object> mapFromProtoModel = (Map<String, Object>) Json.decodeValue(jsonProtoModel, Map.class);\n\n    // serialize\n    byte[] bytes = protoSerializer.serialize(protoModel);\n    Assertions.assertArrayEquals(bytes, protoSerializer.serialize(mapFromProtoModel));\n    Assertions.assertArrayEquals(bytes, pojoSerializer.serialize(pojoModel));\n    Assertions.assertArrayEquals(bytes, pojoSerializer.serialize(mapFromPojoModel));\n\n    // deserialize pojoModel\n    PojoModel newPojoModel = pojoModelDeserializer.deserialize(bytes);\n    Assertions.assertEquals(jsonPojoModel, Json.encode(newPojoModel));\n    Map<String, Object> mapFromNewPojoModel = pojoMapDeserializer.deserialize(bytes);\n    Assertions.assertEquals(jsonPojoModel, Json.encode(mapFromNewPojoModel));\n\n    // deserialize protoModel\n    ProtoModel newProtoModel = protoModelDeserializer.deserialize(bytes);\n    Assertions.assertEquals(jsonProtoModel, Json.encode(newProtoModel));\n    Map<String, Object> mapFromNewProtoModel = protoMapDeserializer.deserialize(bytes);\n    Assertions.assertEquals(jsonProtoModel, Json.encode(mapFromNewProtoModel));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestSchemaBase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal;\n\nimport java.io.IOException;\nimport java.util.Map;\n\nimport org.apache.commons.codec.binary.Hex;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.PrimitiveArrays;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.PrimitiveWrapperArrays;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\n\nimport io.protostuff.compiler.model.Field;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestSchemaBase {\n  protected static ProtoMapperFactory factory = new ProtoMapperFactory();\n\n  protected static ProtoMapper protoMapper = factory.createFromName(\"protobufRoot.proto\");\n\n  protected static RootSerializer rootSerializer = protoMapper.createRootSerializer(\"Root\", Root.class);\n\n  protected static RootDeserializer<Root> rootDeserializer = protoMapper.createRootDeserializer(\"Root\", Root.class);\n\n  protected static RootSerializer primitiveArraysSerializer = protoMapper\n      .createRootSerializer(\"Root\", PrimitiveArrays.class);\n\n  protected static RootDeserializer<Root> primitiveArraysDeserializer = protoMapper\n      .createRootDeserializer(\"Root\", PrimitiveArrays.class);\n\n  protected static RootSerializer primitiveWrapperArraysSerializer = protoMapper\n      .createRootSerializer(\"Root\", PrimitiveWrapperArrays.class);\n\n  protected static RootDeserializer<Root> primitiveWrapperArraysDeserializer = protoMapper\n      .createRootDeserializer(\"Root\", PrimitiveWrapperArrays.class);\n\n  protected static RootDeserializer<Map<String, Object>> mapRootDeserializer = protoMapper\n      .createRootDeserializer(\"Root\", Map.class);\n\n  protected Object scbRoot;\n\n  protected byte[] scbRootBytes;\n\n  protected Map<String, Object> scbMap;\n\n  protected byte[] scbMapBytes;\n\n  protected ProtobufRoot.Root.Builder builder = ProtobufRoot.Root.newBuilder();\n\n  protected byte[] protobufBytes;\n\n  protected String primitiveFieldName;\n\n  protected Field primitiveProtoField;\n\n  protected String fieldName;\n\n  protected Field protoField;\n\n  protected void initFields(String primitiveFieldName, String fieldName) {\n    this.primitiveFieldName = primitiveFieldName;\n    if (primitiveFieldName != null) {\n      primitiveProtoField = protoMapper.getProto().getMessage(\"Root\").getField(primitiveFieldName);\n    }\n\n    initField(fieldName);\n  }\n\n  protected void initField(String fieldName) {\n    this.fieldName = fieldName;\n    if (fieldName != null) {\n      protoField = protoMapper.getProto().getMessage(\"Root\").getField(fieldName);\n    }\n  }\n\n  protected void checkRepeatedWithPrimitive() throws Exception {\n    check();\n\n    check(primitiveArraysDeserializer, mapRootDeserializer, primitiveArraysSerializer, false);\n    String primitiveFieldName = scbMap.keySet().iterator().next();\n    java.lang.reflect.Field primitiveField = PrimitiveArrays.class.getDeclaredField(primitiveFieldName);\n    primitiveField.setAccessible(true);\n    Object primitiveArray = primitiveField.get(scbRoot);\n\n    check(primitiveWrapperArraysDeserializer, mapRootDeserializer, primitiveWrapperArraysSerializer, false);\n    String wrapperFieldName = scbMap.keySet().iterator().next();\n    java.lang.reflect.Field wrapperField = PrimitiveWrapperArrays.class.getDeclaredField(wrapperFieldName);\n    wrapperField.setAccessible(true);\n    Object[] array = (Object[]) wrapperField.get(scbRoot);\n\n    // dynamic strings\n    String[] strings = new String[array.length];\n    for (int idx = 0; idx < array.length; idx++) {\n      strings[idx] = array[idx].toString();\n    }\n    scbMap.clear();\n    scbMap.put(primitiveFieldName, strings);\n    scbMapBytes = primitiveArraysSerializer.serialize(scbMap);\n    Assertions.assertArrayEquals(protobufBytes, scbMapBytes);\n\n    // dynamic primitive array\n    scbMap.clear();\n    scbMap.put(primitiveFieldName, primitiveArray);\n    scbMapBytes = primitiveArraysSerializer.serialize(scbMap);\n    Assertions.assertArrayEquals(protobufBytes, scbMapBytes);\n\n    // dynamic array\n    scbMap.clear();\n    scbMap.put(primitiveFieldName, array);\n    scbMapBytes = primitiveArraysSerializer.serialize(scbMap);\n    Assertions.assertArrayEquals(protobufBytes, scbMapBytes);\n  }\n\n  protected void check() throws IOException {\n    check(rootDeserializer, mapRootDeserializer, rootSerializer, false);\n  }\n\n  protected void check(boolean print) throws IOException {\n    check(rootDeserializer, mapRootDeserializer, rootSerializer, print);\n  }\n\n  protected <T> void check(RootDeserializer<T> deserializer, RootDeserializer<Map<String, Object>> mapDeserializer,\n      RootSerializer serializer,\n      boolean print) throws IOException {\n    // 1.standard protobuf serialize to bytes\n    protobufBytes = builder.build().toByteArray();\n    // 2.weak type deserialize\n    scbMap = mapDeserializer.deserialize(protobufBytes);\n    // 3.weak type serialize\n    scbMapBytes = serializer.serialize(scbMap);\n    // 4.strong type deserialize\n    scbRoot = deserializer.deserialize(scbMapBytes);\n    // 5.strong type serialize\n    scbRootBytes = serializer.serialize(scbRoot);\n\n    if (print) {\n      System.out.println(\"scbRoot bytes:\" + Hex.encodeHexString(scbRootBytes));\n      System.out.println(\"scbRoot len  :\" + scbRootBytes.length);\n      System.out.println(\"scbMap bytes :\" + Hex.encodeHexString(scbMapBytes));\n      System.out.println(\"scbMap len   :\" + scbMapBytes.length);\n      System.out.println(\"protobuf     :\" + Hex.encodeHexString(protobufBytes));\n      System.out.println(\"protobuf len :\" + protobufBytes.length);\n    }\n    Assertions.assertArrayEquals(protobufBytes, scbMapBytes);\n    Assertions.assertArrayEquals(protobufBytes, scbRootBytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/bean/TestBeanDescriptorManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.bean;\n\nimport java.lang.reflect.Method;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntGetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.IntSetter;\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestBeanDescriptorManager {\n  public static class Model {\n    private int both;\n\n    private int onlyGet;\n\n    private int onlySet;\n\n    public int direct;\n\n    public int getBoth() {\n      return both;\n    }\n\n    public void setBoth(int both) {\n      this.both = both;\n    }\n\n    public int getOnlyGet() {\n      return onlyGet;\n    }\n\n    public void onlyGet(int value) {\n      this.onlyGet = value;\n    }\n\n    public void setOnlySet(int onlySet) {\n      this.onlySet = onlySet;\n    }\n\n    public int onlySet() {\n      return onlySet;\n    }\n  }\n\n  public static class CustomGeneric<T> {\n    private T value;\n\n    public T getValue() {\n      return value;\n    }\n\n    public void setValue(T value) {\n      this.value = value;\n    }\n  }\n\n  public static class GenericSchema {\n    public CustomGeneric<Model> genericMethod(CustomGeneric<String> input) {\n      return null;\n    }\n  }\n\n  static ObjectMapper mapper = new ObjectMapper();\n\n  static BeanDescriptorManager beanDescriptorManager = new BeanDescriptorManager(mapper.getSerializationConfig());\n\n  static BeanDescriptor beanDescriptor = beanDescriptorManager.getOrCreateBeanDescriptor(Model.class);\n\n  Model model = new Model();\n\n  @Test\n  public void generic() {\n    Method method = ReflectUtils.findMethod(GenericSchema.class, \"genericMethod\");\n    BeanDescriptor beanDescriptor = beanDescriptorManager\n        .getOrCreateBeanDescriptor(method.getGenericParameterTypes()[0]);\n\n    Assertions.assertEquals(String.class, beanDescriptor.getPropertyDescriptors().get(\"value\").getJavaType().getRawClass());\n  }\n\n  @Test\n  public void getOrCreate() {\n    Assertions.assertSame(beanDescriptor, beanDescriptorManager.getOrCreateBeanDescriptor(Model.class));\n    Assertions.assertSame(Model.class, beanDescriptor.getJavaType().getRawClass());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void both() {\n    PropertyDescriptor propertyDescriptor = beanDescriptor.getPropertyDescriptors().get(\"both\");\n    ((IntSetter<Model>) propertyDescriptor.getSetter()).set(model, 1);\n    Assertions.assertEquals(1, ((IntGetter<Model>) propertyDescriptor.getGetter()).get(model));\n    Assertions.assertEquals(1, model.getBoth());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void onlyGet() {\n    PropertyDescriptor propertyDescriptor = beanDescriptor.getPropertyDescriptors().get(\"onlyGet\");\n    Assertions.assertNull(propertyDescriptor.getSetter());\n\n    model.onlyGet(1);\n    Assertions.assertEquals(1, ((IntGetter<Model>) propertyDescriptor.getGetter()).get(model));\n    Assertions.assertEquals(1, model.getOnlyGet());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void onlySet() {\n    PropertyDescriptor propertyDescriptor = beanDescriptor.getPropertyDescriptors().get(\"onlySet\");\n    Assertions.assertNull(propertyDescriptor.getGetter());\n\n    ((IntSetter<Model>) propertyDescriptor.getSetter()).set(model, 1);\n    Assertions.assertEquals(1, model.onlySet());\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void direct() {\n    PropertyDescriptor propertyDescriptor = beanDescriptor.getPropertyDescriptors().get(\"direct\");\n    ((Setter<Model, Integer>) propertyDescriptor.getSetter()).set(model, 1);\n    Assertions.assertEquals(1, (int) ((Getter<Model, Integer>) propertyDescriptor.getGetter()).get(model));\n    Assertions.assertEquals(1, model.direct);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/model/CustomGeneric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\npublic class CustomGeneric<T> {\n  public T user;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/model/PrimitiveArrays.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\")Packed; you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\n\npublic class PrimitiveArrays {\n  private int[] int32sPacked;\n\n  private long[] int64sPacked;\n\n  private int[] uint32sPacked;\n\n  private long[] uint64sPacked;\n\n  private int[] sint32sPacked;\n\n  private long[] sint64sPacked;\n\n  private int[] fixed32sPacked;\n\n  private long[] fixed64sPacked;\n\n  private int[] sfixed32sPacked;\n\n  private long[] sfixed64sPacked;\n\n  private float[] floatsPacked;\n\n  private double[] doublesPacked;\n\n  private boolean[] boolsPacked;\n\n  private Color[] colorsPacked;\n\n  private int[] int32sNotPacked;\n\n  private long[] int64sNotPacked;\n\n  private int[] uint32sNotPacked;\n\n  private long[] uint64sNotPacked;\n\n  private int[] sint32sNotPacked;\n\n  private long[] sint64sNotPacked;\n\n  private int[] fixed32sNotPacked;\n\n  private long[] fixed64sNotPacked;\n\n  private int[] sfixed32sNotPacked;\n\n  private long[] sfixed64sNotPacked;\n\n  private float[] floatsNotPacked;\n\n  private double[] doublesNotPacked;\n\n  private boolean[] boolsNotPacked;\n\n  private Color[] colorsNotPacked;\n\n  public int[] getInt32sPacked() {\n    return int32sPacked;\n  }\n\n  public void setInt32sPacked(int[] int32sPacked) {\n    this.int32sPacked = int32sPacked;\n  }\n\n  public long[] getInt64sPacked() {\n    return int64sPacked;\n  }\n\n  public void setInt64sPacked(long[] int64sPacked) {\n    this.int64sPacked = int64sPacked;\n  }\n\n  public int[] getUint32sPacked() {\n    return uint32sPacked;\n  }\n\n  public void setUint32sPacked(int[] uint32sPacked) {\n    this.uint32sPacked = uint32sPacked;\n  }\n\n  public long[] getUint64sPacked() {\n    return uint64sPacked;\n  }\n\n  public void setUint64sPacked(long[] uint64sPacked) {\n    this.uint64sPacked = uint64sPacked;\n  }\n\n  public int[] getSint32sPacked() {\n    return sint32sPacked;\n  }\n\n  public void setSint32sPacked(int[] sint32sPacked) {\n    this.sint32sPacked = sint32sPacked;\n  }\n\n  public long[] getSint64sPacked() {\n    return sint64sPacked;\n  }\n\n  public void setSint64sPacked(long[] sint64sPacked) {\n    this.sint64sPacked = sint64sPacked;\n  }\n\n  public int[] getFixed32sPacked() {\n    return fixed32sPacked;\n  }\n\n  public void setFixed32sPacked(int[] fixed32sPacked) {\n    this.fixed32sPacked = fixed32sPacked;\n  }\n\n  public long[] getFixed64sPacked() {\n    return fixed64sPacked;\n  }\n\n  public void setFixed64sPacked(long[] fixed64sPacked) {\n    this.fixed64sPacked = fixed64sPacked;\n  }\n\n  public int[] getSfixed32sPacked() {\n    return sfixed32sPacked;\n  }\n\n  public void setSfixed32sPacked(int[] sfixed32sPacked) {\n    this.sfixed32sPacked = sfixed32sPacked;\n  }\n\n  public long[] getSfixed64sPacked() {\n    return sfixed64sPacked;\n  }\n\n  public void setSfixed64sPacked(long[] sfixed64sPacked) {\n    this.sfixed64sPacked = sfixed64sPacked;\n  }\n\n  public float[] getFloatsPacked() {\n    return floatsPacked;\n  }\n\n  public void setFloatsPacked(float[] floatsPacked) {\n    this.floatsPacked = floatsPacked;\n  }\n\n  public double[] getDoublesPacked() {\n    return doublesPacked;\n  }\n\n  public void setDoublesPacked(double[] doublesPacked) {\n    this.doublesPacked = doublesPacked;\n  }\n\n  public boolean[] getBoolsPacked() {\n    return boolsPacked;\n  }\n\n  public void setBoolsPacked(boolean[] boolsPacked) {\n    this.boolsPacked = boolsPacked;\n  }\n\n  public int[] getInt32sNotPacked() {\n    return int32sNotPacked;\n  }\n\n  public void setInt32sNotPacked(int[] int32sNotPacked) {\n    this.int32sNotPacked = int32sNotPacked;\n  }\n\n  public long[] getInt64sNotPacked() {\n    return int64sNotPacked;\n  }\n\n  public void setInt64sNotPacked(long[] int64sNotPacked) {\n    this.int64sNotPacked = int64sNotPacked;\n  }\n\n  public int[] getUint32sNotPacked() {\n    return uint32sNotPacked;\n  }\n\n  public void setUint32sNotPacked(int[] uint32sNotPacked) {\n    this.uint32sNotPacked = uint32sNotPacked;\n  }\n\n  public long[] getUint64sNotPacked() {\n    return uint64sNotPacked;\n  }\n\n  public void setUint64sNotPacked(long[] uint64sNotPacked) {\n    this.uint64sNotPacked = uint64sNotPacked;\n  }\n\n  public int[] getSint32sNotPacked() {\n    return sint32sNotPacked;\n  }\n\n  public void setSint32sNotPacked(int[] sint32sNotPacked) {\n    this.sint32sNotPacked = sint32sNotPacked;\n  }\n\n  public long[] getSint64sNotPacked() {\n    return sint64sNotPacked;\n  }\n\n  public void setSint64sNotPacked(long[] sint64sNotPacked) {\n    this.sint64sNotPacked = sint64sNotPacked;\n  }\n\n  public int[] getFixed32sNotPacked() {\n    return fixed32sNotPacked;\n  }\n\n  public void setFixed32sNotPacked(int[] fixed32sNotPacked) {\n    this.fixed32sNotPacked = fixed32sNotPacked;\n  }\n\n  public long[] getFixed64sNotPacked() {\n    return fixed64sNotPacked;\n  }\n\n  public void setFixed64sNotPacked(long[] fixed64sNotPacked) {\n    this.fixed64sNotPacked = fixed64sNotPacked;\n  }\n\n  public int[] getSfixed32sNotPacked() {\n    return sfixed32sNotPacked;\n  }\n\n  public void setSfixed32sNotPacked(int[] sfixed32sNotPacked) {\n    this.sfixed32sNotPacked = sfixed32sNotPacked;\n  }\n\n  public long[] getSfixed64sNotPacked() {\n    return sfixed64sNotPacked;\n  }\n\n  public void setSfixed64sNotPacked(long[] sfixed64sNotPacked) {\n    this.sfixed64sNotPacked = sfixed64sNotPacked;\n  }\n\n  public float[] getFloatsNotPacked() {\n    return floatsNotPacked;\n  }\n\n  public void setFloatsNotPacked(float[] floatsNotPacked) {\n    this.floatsNotPacked = floatsNotPacked;\n  }\n\n  public double[] getDoublesNotPacked() {\n    return doublesNotPacked;\n  }\n\n  public void setDoublesNotPacked(double[] doublesNotPacked) {\n    this.doublesNotPacked = doublesNotPacked;\n  }\n\n  public boolean[] getBoolsNotPacked() {\n    return boolsNotPacked;\n  }\n\n  public void setBoolsNotPacked(boolean[] boolsNotPacked) {\n    this.boolsNotPacked = boolsNotPacked;\n  }\n\n  public Color[] getColorsPacked() {\n    return colorsPacked;\n  }\n\n  public void setColorsPacked(Color[] colorsPacked) {\n    this.colorsPacked = colorsPacked;\n  }\n\n  public Color[] getColorsNotPacked() {\n    return colorsNotPacked;\n  }\n\n  public void setColorsNotPacked(Color[] colorsNotPacked) {\n    this.colorsNotPacked = colorsNotPacked;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/model/PrimitiveWrapperArrays.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\")Packed; you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\n\npublic class PrimitiveWrapperArrays {\n  private Integer[] int32sPacked;\n\n  private Long[] int64sPacked;\n\n  private Integer[] uint32sPacked;\n\n  private Long[] uint64sPacked;\n\n  private Integer[] sint32sPacked;\n\n  private Long[] sint64sPacked;\n\n  private Integer[] fixed32sPacked;\n\n  private Long[] fixed64sPacked;\n\n  private Integer[] sfixed32sPacked;\n\n  private Long[] sfixed64sPacked;\n\n  private Float[] floatsPacked;\n\n  private Double[] doublesPacked;\n\n  private Boolean[] boolsPacked;\n\n  private Color[] colorsPacked;\n\n  private Integer[] int32sNotPacked;\n\n  private Long[] int64sNotPacked;\n\n  private Integer[] uint32sNotPacked;\n\n  private Long[] uint64sNotPacked;\n\n  private Integer[] sint32sNotPacked;\n\n  private Long[] sint64sNotPacked;\n\n  private Integer[] fixed32sNotPacked;\n\n  private Long[] fixed64sNotPacked;\n\n  private Integer[] sfixed32sNotPacked;\n\n  private Long[] sfixed64sNotPacked;\n\n  private Float[] floatsNotPacked;\n\n  private Double[] doublesNotPacked;\n\n  private Boolean[] boolsNotPacked;\n\n  private Color[] colorsNotPacked;\n\n  public Integer[] getInt32sPacked() {\n    return int32sPacked;\n  }\n\n  public void setInt32sPacked(Integer[] int32sPacked) {\n    this.int32sPacked = int32sPacked;\n  }\n\n  public Long[] getInt64sPacked() {\n    return int64sPacked;\n  }\n\n  public void setInt64sPacked(Long[] int64sPacked) {\n    this.int64sPacked = int64sPacked;\n  }\n\n  public Integer[] getUint32sPacked() {\n    return uint32sPacked;\n  }\n\n  public void setUint32sPacked(Integer[] uint32sPacked) {\n    this.uint32sPacked = uint32sPacked;\n  }\n\n  public Long[] getUint64sPacked() {\n    return uint64sPacked;\n  }\n\n  public void setUint64sPacked(Long[] uint64sPacked) {\n    this.uint64sPacked = uint64sPacked;\n  }\n\n  public Integer[] getSint32sPacked() {\n    return sint32sPacked;\n  }\n\n  public void setSint32sPacked(Integer[] sint32sPacked) {\n    this.sint32sPacked = sint32sPacked;\n  }\n\n  public Long[] getSint64sPacked() {\n    return sint64sPacked;\n  }\n\n  public void setSint64sPacked(Long[] sint64sPacked) {\n    this.sint64sPacked = sint64sPacked;\n  }\n\n  public Integer[] getFixed32sPacked() {\n    return fixed32sPacked;\n  }\n\n  public void setFixed32sPacked(Integer[] fixed32sPacked) {\n    this.fixed32sPacked = fixed32sPacked;\n  }\n\n  public Long[] getFixed64sPacked() {\n    return fixed64sPacked;\n  }\n\n  public void setFixed64sPacked(Long[] fixed64sPacked) {\n    this.fixed64sPacked = fixed64sPacked;\n  }\n\n  public Integer[] getSfixed32sPacked() {\n    return sfixed32sPacked;\n  }\n\n  public void setSfixed32sPacked(Integer[] sfixed32sPacked) {\n    this.sfixed32sPacked = sfixed32sPacked;\n  }\n\n  public Long[] getSfixed64sPacked() {\n    return sfixed64sPacked;\n  }\n\n  public void setSfixed64sPacked(Long[] sfixed64sPacked) {\n    this.sfixed64sPacked = sfixed64sPacked;\n  }\n\n  public Float[] getFloatsPacked() {\n    return floatsPacked;\n  }\n\n  public void setFloatsPacked(Float[] floatsPacked) {\n    this.floatsPacked = floatsPacked;\n  }\n\n  public Double[] getDoublesPacked() {\n    return doublesPacked;\n  }\n\n  public void setDoublesPacked(Double[] doublesPacked) {\n    this.doublesPacked = doublesPacked;\n  }\n\n  public Boolean[] getBoolsPacked() {\n    return boolsPacked;\n  }\n\n  public void setBoolsPacked(Boolean[] boolsPacked) {\n    this.boolsPacked = boolsPacked;\n  }\n\n  public Integer[] getInt32sNotPacked() {\n    return int32sNotPacked;\n  }\n\n  public void setInt32sNotPacked(Integer[] int32sNotPacked) {\n    this.int32sNotPacked = int32sNotPacked;\n  }\n\n  public Long[] getInt64sNotPacked() {\n    return int64sNotPacked;\n  }\n\n  public void setInt64sNotPacked(Long[] int64sNotPacked) {\n    this.int64sNotPacked = int64sNotPacked;\n  }\n\n  public Integer[] getUint32sNotPacked() {\n    return uint32sNotPacked;\n  }\n\n  public void setUint32sNotPacked(Integer[] uint32sNotPacked) {\n    this.uint32sNotPacked = uint32sNotPacked;\n  }\n\n  public Long[] getUint64sNotPacked() {\n    return uint64sNotPacked;\n  }\n\n  public void setUint64sNotPacked(Long[] uint64sNotPacked) {\n    this.uint64sNotPacked = uint64sNotPacked;\n  }\n\n  public Integer[] getSint32sNotPacked() {\n    return sint32sNotPacked;\n  }\n\n  public void setSint32sNotPacked(Integer[] sint32sNotPacked) {\n    this.sint32sNotPacked = sint32sNotPacked;\n  }\n\n  public Long[] getSint64sNotPacked() {\n    return sint64sNotPacked;\n  }\n\n  public void setSint64sNotPacked(Long[] sint64sNotPacked) {\n    this.sint64sNotPacked = sint64sNotPacked;\n  }\n\n  public Integer[] getFixed32sNotPacked() {\n    return fixed32sNotPacked;\n  }\n\n  public void setFixed32sNotPacked(Integer[] fixed32sNotPacked) {\n    this.fixed32sNotPacked = fixed32sNotPacked;\n  }\n\n  public Long[] getFixed64sNotPacked() {\n    return fixed64sNotPacked;\n  }\n\n  public void setFixed64sNotPacked(Long[] fixed64sNotPacked) {\n    this.fixed64sNotPacked = fixed64sNotPacked;\n  }\n\n  public Integer[] getSfixed32sNotPacked() {\n    return sfixed32sNotPacked;\n  }\n\n  public void setSfixed32sNotPacked(Integer[] sfixed32sNotPacked) {\n    this.sfixed32sNotPacked = sfixed32sNotPacked;\n  }\n\n  public Long[] getSfixed64sNotPacked() {\n    return sfixed64sNotPacked;\n  }\n\n  public void setSfixed64sNotPacked(Long[] sfixed64sNotPacked) {\n    this.sfixed64sNotPacked = sfixed64sNotPacked;\n  }\n\n  public Float[] getFloatsNotPacked() {\n    return floatsNotPacked;\n  }\n\n  public void setFloatsNotPacked(Float[] floatsNotPacked) {\n    this.floatsNotPacked = floatsNotPacked;\n  }\n\n  public Double[] getDoublesNotPacked() {\n    return doublesNotPacked;\n  }\n\n  public void setDoublesNotPacked(Double[] doublesNotPacked) {\n    this.doublesNotPacked = doublesNotPacked;\n  }\n\n  public Boolean[] getBoolsNotPacked() {\n    return boolsNotPacked;\n  }\n\n  public void setBoolsNotPacked(Boolean[] boolsNotPacked) {\n    this.boolsNotPacked = boolsNotPacked;\n  }\n\n  public Color[] getColorsPacked() {\n    return colorsPacked;\n  }\n\n  public void setColorsPacked(Color[] colorsPacked) {\n    this.colorsPacked = colorsPacked;\n  }\n\n  public Color[] getColorsNotPacked() {\n    return colorsNotPacked;\n  }\n\n  public void setColorsNotPacked(Color[] colorsNotPacked) {\n    this.colorsNotPacked = colorsNotPacked;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/model/Root.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\n\nimport io.protostuff.Tag;\n\n/**\n * Tag annotation is only for protoStuff, not necessary for ServiceComb codec\n */\npublic class Root {\n  @Tag(1)\n  private int int32;\n\n  @Tag(2)\n  private long int64;\n\n  @Tag(3)\n  private int uint32;\n\n  @Tag(4)\n  private long uint64;\n\n  @Tag(5)\n  private int sint32;\n\n  @Tag(6)\n  private long sint64;\n\n  @Tag(7)\n  private int fixed32;\n\n  @Tag(8)\n  private long fixed64;\n\n  @Tag(9)\n  private int sfixed32;\n\n  @Tag(10)\n  private long sfixed64;\n\n  @Tag(11)\n  private float floatValue;\n\n  @Tag(12)\n  private double doubleValue;\n\n  @Tag(13)\n  private boolean bool;\n\n  @Tag(20)\n  private Integer objInt32;\n\n  @Tag(21)\n  private Long objInt64;\n\n  @Tag(22)\n  private Integer objUint32;\n\n  @Tag(23)\n  private Long objUint64;\n\n  @Tag(24)\n  private Integer objSint32;\n\n  @Tag(25)\n  private Long objSint64;\n\n  @Tag(26)\n  private Integer objFixed32;\n\n  @Tag(27)\n  private Long objFixed64;\n\n  @Tag(28)\n  private Integer objSfixed32;\n\n  @Tag(29)\n  private Long objSfixed64;\n\n  @Tag(30)\n  private Float objFloatValue;\n\n  @Tag(31)\n  private Double objDoubleValue;\n\n  @Tag(32)\n  private Boolean objBool;\n\n  @Tag(40)\n  private String string;\n\n  @Tag(41)\n  private byte[] bytes;\n\n  @Tag(42)\n  private Color color;\n\n  @Tag(43)\n  private User user;\n\n  @Tag(44)\n  private Root typeRecursive;\n\n  @Tag(50)\n  private Object any;\n\n  @Tag(51)\n  private List<Object> anys;\n\n  @Tag(60)\n  private Map<String, String> ssMap;\n\n  @Tag(61)\n  private Map<String, Integer> sint32Map;\n\n  @Tag(62)\n  private Map<String, User> spMap;\n\n  // repeated packed\n  @Tag(70)\n  private List<Integer> int32sPacked;\n\n  @Tag(71)\n  private List<Long> int64sPacked;\n\n  @Tag(72)\n  private List<Integer> uint32sPacked;\n\n  @Tag(73)\n  private List<Long> uint64sPacked;\n\n  @Tag(74)\n  private List<Integer> sint32sPacked;\n\n  @Tag(75)\n  private List<Long> sint64sPacked;\n\n  @Tag(76)\n  private List<Integer> fixed32sPacked;\n\n  @Tag(77)\n  private List<Long> fixed64sPacked;\n\n  @Tag(78)\n  private List<Integer> sfixed32sPacked;\n\n  @Tag(79)\n  private List<Long> sfixed64sPacked;\n\n  @Tag(80)\n  private List<Float> floatsPacked;\n\n  @Tag(81)\n  private List<Double> doublesPacked;\n\n  @Tag(82)\n  private List<Boolean> boolsPacked;\n\n  @Tag(83)\n  private List<Color> colorsPacked;\n\n  // repeated not packed\n  @Tag(90)\n  private List<Integer> int32sNotPacked;\n\n  @Tag(91)\n  private List<Long> int64sNotPacked;\n\n  @Tag(92)\n  private List<Integer> uint32sNotPacked;\n\n  @Tag(93)\n  private List<Long> uint64sNotPacked;\n\n  @Tag(94)\n  private List<Integer> sint32sNotPacked;\n\n  @Tag(95)\n  private List<Long> sint64sNotPacked;\n\n  @Tag(96)\n  private List<Integer> fixed32sNotPacked;\n\n  @Tag(97)\n  private List<Long> fixed64sNotPacked;\n\n  @Tag(98)\n  private List<Integer> sfixed32sNotPacked;\n\n  @Tag(99)\n  private List<Long> sfixed64sNotPacked;\n\n  @Tag(100)\n  private List<Float> floatsNotPacked;\n\n  @Tag(101)\n  private List<Double> doublesNotPacked;\n\n  @Tag(102)\n  private List<Boolean> boolsNotPacked;\n\n  @Tag(103)\n  private List<Color> colorsNotPacked;\n\n  @Tag(110)\n  private List<String> strings;\n\n  @Tag(111)\n  private List<byte[]> bytess;\n\n  @Tag(112)\n  private List<User> users;\n\n  public int getInt32() {\n    return int32;\n  }\n\n  public void setInt32(int int32) {\n    this.int32 = int32;\n  }\n\n  public long getInt64() {\n    return int64;\n  }\n\n  public void setInt64(long int64) {\n    this.int64 = int64;\n  }\n\n  public int getUint32() {\n    return uint32;\n  }\n\n  public void setUint32(int uint32) {\n    this.uint32 = uint32;\n  }\n\n  public long getUint64() {\n    return uint64;\n  }\n\n  public void setUint64(long uint64) {\n    this.uint64 = uint64;\n  }\n\n  public int getSint32() {\n    return sint32;\n  }\n\n  public void setSint32(int sint32) {\n    this.sint32 = sint32;\n  }\n\n  public long getSint64() {\n    return sint64;\n  }\n\n  public void setSint64(long sint64) {\n    this.sint64 = sint64;\n  }\n\n  public int getFixed32() {\n    return fixed32;\n  }\n\n  public void setFixed32(int fixed32) {\n    this.fixed32 = fixed32;\n  }\n\n  public long getFixed64() {\n    return fixed64;\n  }\n\n  public void setFixed64(long fixed64) {\n    this.fixed64 = fixed64;\n  }\n\n  public int getSfixed32() {\n    return sfixed32;\n  }\n\n  public void setSfixed32(int sfixed32) {\n    this.sfixed32 = sfixed32;\n  }\n\n  public long getSfixed64() {\n    return sfixed64;\n  }\n\n  public void setSfixed64(long sfixed64) {\n    this.sfixed64 = sfixed64;\n  }\n\n  public float getFloatValue() {\n    return floatValue;\n  }\n\n  public void setFloatValue(float floatValue) {\n    this.floatValue = floatValue;\n  }\n\n  public double getDoubleValue() {\n    return doubleValue;\n  }\n\n  public void setDoubleValue(double doubleValue) {\n    this.doubleValue = doubleValue;\n  }\n\n  public boolean isBool() {\n    return bool;\n  }\n\n  public void setBool(boolean bool) {\n    this.bool = bool;\n  }\n\n  public String getString() {\n    return string;\n  }\n\n  public void setString(String string) {\n    this.string = string;\n  }\n\n  public byte[] getBytes() {\n    return bytes;\n  }\n\n  public void setBytes(byte[] bytes) {\n    this.bytes = bytes;\n  }\n\n  public Color getColor() {\n    return color;\n  }\n\n  public void setColor(Color color) {\n    this.color = color;\n  }\n\n  public User getUser() {\n    return user;\n  }\n\n  public void setUser(User user) {\n    this.user = user;\n  }\n\n  public Map<String, String> getSsMap() {\n    return ssMap;\n  }\n\n  public void setSsMap(Map<String, String> ssMap) {\n    this.ssMap = ssMap;\n  }\n\n  public Map<String, User> getSpMap() {\n    return spMap;\n  }\n\n  public void setSpMap(Map<String, User> spMap) {\n    this.spMap = spMap;\n  }\n\n  public Object getAny() {\n    return any;\n  }\n\n  public void setAny(Object any) {\n    this.any = any;\n  }\n\n  public List<Object> getAnys() {\n    return anys;\n  }\n\n  public void setAnys(List<Object> anys) {\n    this.anys = anys;\n  }\n\n  public Root getTypeRecursive() {\n    return typeRecursive;\n  }\n\n  public void setTypeRecursive(Root typeRecursive) {\n    this.typeRecursive = typeRecursive;\n  }\n\n  public List<Integer> getInt32sPacked() {\n    return int32sPacked;\n  }\n\n  public void setInt32sPacked(List<Integer> int32sPacked) {\n    this.int32sPacked = int32sPacked;\n  }\n\n  public List<Long> getInt64sPacked() {\n    return int64sPacked;\n  }\n\n  public void setInt64sPacked(List<Long> int64sPacked) {\n    this.int64sPacked = int64sPacked;\n  }\n\n  public List<Integer> getUint32sPacked() {\n    return uint32sPacked;\n  }\n\n  public void setUint32sPacked(List<Integer> uint32sPacked) {\n    this.uint32sPacked = uint32sPacked;\n  }\n\n  public List<Long> getUint64sPacked() {\n    return uint64sPacked;\n  }\n\n  public void setUint64sPacked(List<Long> uint64sPacked) {\n    this.uint64sPacked = uint64sPacked;\n  }\n\n  public List<Integer> getSint32sPacked() {\n    return sint32sPacked;\n  }\n\n  public void setSint32sPacked(List<Integer> sint32sPacked) {\n    this.sint32sPacked = sint32sPacked;\n  }\n\n  public List<Long> getSint64sPacked() {\n    return sint64sPacked;\n  }\n\n  public void setSint64sPacked(List<Long> sint64sPacked) {\n    this.sint64sPacked = sint64sPacked;\n  }\n\n  public List<Integer> getFixed32sPacked() {\n    return fixed32sPacked;\n  }\n\n  public void setFixed32sPacked(List<Integer> fixed32sPacked) {\n    this.fixed32sPacked = fixed32sPacked;\n  }\n\n  public List<Long> getFixed64sPacked() {\n    return fixed64sPacked;\n  }\n\n  public void setFixed64sPacked(List<Long> fixed64sPacked) {\n    this.fixed64sPacked = fixed64sPacked;\n  }\n\n  public List<Integer> getSfixed32sPacked() {\n    return sfixed32sPacked;\n  }\n\n  public void setSfixed32sPacked(List<Integer> sfixed32sPacked) {\n    this.sfixed32sPacked = sfixed32sPacked;\n  }\n\n  public List<Long> getSfixed64sPacked() {\n    return sfixed64sPacked;\n  }\n\n  public void setSfixed64sPacked(List<Long> sfixed64sPacked) {\n    this.sfixed64sPacked = sfixed64sPacked;\n  }\n\n  public List<Float> getFloatsPacked() {\n    return floatsPacked;\n  }\n\n  public void setFloatsPacked(List<Float> floatsPacked) {\n    this.floatsPacked = floatsPacked;\n  }\n\n  public List<Double> getDoublesPacked() {\n    return doublesPacked;\n  }\n\n  public void setDoublesPacked(List<Double> doublesPacked) {\n    this.doublesPacked = doublesPacked;\n  }\n\n  public List<Boolean> getBoolsPacked() {\n    return boolsPacked;\n  }\n\n  public void setBoolsPacked(List<Boolean> boolsPacked) {\n    this.boolsPacked = boolsPacked;\n  }\n\n  public List<Color> getColorsPacked() {\n    return colorsPacked;\n  }\n\n  public void setColorsPacked(List<Color> colorsPacked) {\n    this.colorsPacked = colorsPacked;\n  }\n\n  public List<Integer> getInt32sNotPacked() {\n    return int32sNotPacked;\n  }\n\n  public void setInt32sNotPacked(List<Integer> int32sNotPacked) {\n    this.int32sNotPacked = int32sNotPacked;\n  }\n\n  public List<Long> getInt64sNotPacked() {\n    return int64sNotPacked;\n  }\n\n  public void setInt64sNotPacked(List<Long> int64sNotPacked) {\n    this.int64sNotPacked = int64sNotPacked;\n  }\n\n  public List<Integer> getUint32sNotPacked() {\n    return uint32sNotPacked;\n  }\n\n  public void setUint32sNotPacked(List<Integer> uint32sNotPacked) {\n    this.uint32sNotPacked = uint32sNotPacked;\n  }\n\n  public List<Long> getUint64sNotPacked() {\n    return uint64sNotPacked;\n  }\n\n  public void setUint64sNotPacked(List<Long> uint64sNotPacked) {\n    this.uint64sNotPacked = uint64sNotPacked;\n  }\n\n  public List<Integer> getSint32sNotPacked() {\n    return sint32sNotPacked;\n  }\n\n  public void setSint32sNotPacked(List<Integer> sint32sNotPacked) {\n    this.sint32sNotPacked = sint32sNotPacked;\n  }\n\n  public List<Long> getSint64sNotPacked() {\n    return sint64sNotPacked;\n  }\n\n  public void setSint64sNotPacked(List<Long> sint64sNotPacked) {\n    this.sint64sNotPacked = sint64sNotPacked;\n  }\n\n  public List<Integer> getFixed32sNotPacked() {\n    return fixed32sNotPacked;\n  }\n\n  public void setFixed32sNotPacked(List<Integer> fixed32sNotPacked) {\n    this.fixed32sNotPacked = fixed32sNotPacked;\n  }\n\n  public List<Long> getFixed64sNotPacked() {\n    return fixed64sNotPacked;\n  }\n\n  public void setFixed64sNotPacked(List<Long> fixed64sNotPacked) {\n    this.fixed64sNotPacked = fixed64sNotPacked;\n  }\n\n  public List<Integer> getSfixed32sNotPacked() {\n    return sfixed32sNotPacked;\n  }\n\n  public void setSfixed32sNotPacked(List<Integer> sfixed32sNotPacked) {\n    this.sfixed32sNotPacked = sfixed32sNotPacked;\n  }\n\n  public List<Long> getSfixed64sNotPacked() {\n    return sfixed64sNotPacked;\n  }\n\n  public void setSfixed64sNotPacked(List<Long> sfixed64sNotPacked) {\n    this.sfixed64sNotPacked = sfixed64sNotPacked;\n  }\n\n  public List<Float> getFloatsNotPacked() {\n    return floatsNotPacked;\n  }\n\n  public void setFloatsNotPacked(List<Float> floatsNotPacked) {\n    this.floatsNotPacked = floatsNotPacked;\n  }\n\n  public List<Double> getDoublesNotPacked() {\n    return doublesNotPacked;\n  }\n\n  public void setDoublesNotPacked(List<Double> doublesNotPacked) {\n    this.doublesNotPacked = doublesNotPacked;\n  }\n\n  public List<Boolean> getBoolsNotPacked() {\n    return boolsNotPacked;\n  }\n\n  public void setBoolsNotPacked(List<Boolean> boolsNotPacked) {\n    this.boolsNotPacked = boolsNotPacked;\n  }\n\n  public List<Color> getColorsNotPacked() {\n    return colorsNotPacked;\n  }\n\n  public void setColorsNotPacked(\n      List<Color> colorsNotPacked) {\n    this.colorsNotPacked = colorsNotPacked;\n  }\n\n  public List<String> getStrings() {\n    return strings;\n  }\n\n  public void setStrings(List<String> strings) {\n    this.strings = strings;\n  }\n\n  public List<byte[]> getBytess() {\n    return bytess;\n  }\n\n  public void setBytess(List<byte[]> bytess) {\n    this.bytess = bytess;\n  }\n\n  public List<User> getUsers() {\n    return users;\n  }\n\n  public void setUsers(List<User> users) {\n    this.users = users;\n  }\n\n  public Integer getObjInt32() {\n    return objInt32;\n  }\n\n  public void setObjInt32(Integer objInt32) {\n    this.objInt32 = objInt32;\n  }\n\n  public Long getObjInt64() {\n    return objInt64;\n  }\n\n  public void setObjInt64(Long objInt64) {\n    this.objInt64 = objInt64;\n  }\n\n  public Integer getObjUint32() {\n    return objUint32;\n  }\n\n  public void setObjUint32(Integer objUint32) {\n    this.objUint32 = objUint32;\n  }\n\n  public Long getObjUint64() {\n    return objUint64;\n  }\n\n  public void setObjUint64(Long objUint64) {\n    this.objUint64 = objUint64;\n  }\n\n  public Integer getObjSint32() {\n    return objSint32;\n  }\n\n  public void setObjSint32(Integer objSint32) {\n    this.objSint32 = objSint32;\n  }\n\n  public Long getObjSint64() {\n    return objSint64;\n  }\n\n  public void setObjSint64(Long objSint64) {\n    this.objSint64 = objSint64;\n  }\n\n  public Integer getObjFixed32() {\n    return objFixed32;\n  }\n\n  public void setObjFixed32(Integer objFixed32) {\n    this.objFixed32 = objFixed32;\n  }\n\n  public Long getObjFixed64() {\n    return objFixed64;\n  }\n\n  public void setObjFixed64(Long objFixed64) {\n    this.objFixed64 = objFixed64;\n  }\n\n  public Integer getObjSfixed32() {\n    return objSfixed32;\n  }\n\n  public void setObjSfixed32(Integer objSfixed32) {\n    this.objSfixed32 = objSfixed32;\n  }\n\n  public Long getObjSfixed64() {\n    return objSfixed64;\n  }\n\n  public void setObjSfixed64(Long objSfixed64) {\n    this.objSfixed64 = objSfixed64;\n  }\n\n  public Float getObjFloatValue() {\n    return objFloatValue;\n  }\n\n  public void setObjFloatValue(Float objFloatValue) {\n    this.objFloatValue = objFloatValue;\n  }\n\n  public Double getObjDoubleValue() {\n    return objDoubleValue;\n  }\n\n  public void setObjDoubleValue(Double objDoubleValue) {\n    this.objDoubleValue = objDoubleValue;\n  }\n\n  public Boolean isObjBool() {\n    return objBool;\n  }\n\n  public void setObjBool(Boolean objBool) {\n    this.objBool = objBool;\n  }\n\n  public Map<String, Integer> getSint32Map() {\n    return sint32Map;\n  }\n\n  public void setSint32Map(Map<String, Integer> sint32Map) {\n    this.sint32Map = sint32Map;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/model/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\npublic class User {\n  private String name;\n\n  private Root typeRecursive;\n\n  public User() {\n  }\n\n  public User(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public User name(String name) {\n    this.name = name;\n    return this;\n  }\n\n  public Root getTypeRecursive() {\n    return typeRecursive;\n  }\n\n  public void setTypeRecursive(Root typeRecursive) {\n    this.typeRecursive = typeRecursive;\n  }\n\n  @Override\n  public String toString() {\n    return \"User{\" +\n        \"name='\" + name + '\\'' +\n        '}';\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/parser/TestProtoParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.parser;\n\nimport com.google.common.base.MoreObjects;\nimport io.protostuff.compiler.model.Proto;\nimport org.apache.commons.io.IOUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport java.io.IOException;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\n\npublic class TestProtoParser {\n  @Test\n  public void parse() throws IOException {\n    URL url = Thread.currentThread().getContextClassLoader().getResource(\"protobufRoot.proto\");\n    String content = IOUtils.toString(url, StandardCharsets.UTF_8);\n\n    ProtoParser parser = new ProtoParser();\n    Proto protoFromContent = parser.parseFromContent(content);\n    Proto protoFromName = parser.parse(\"protobufRoot.proto\");\n\n    Assertions.assertNotNull(protoFromContent.getMessage(\"Root\"));\n    Assertions.assertNotNull(protoFromContent.getMessage(\"User\"));\n\n    Assertions.assertEquals(MoreObjects.toStringHelper(protoFromContent)\n            .omitNullValues()\n            .add(\"messages\", protoFromContent.getMessages())\n            .toString(),\n        MoreObjects.toStringHelper(protoFromName)\n            .omitNullValues()\n            .add(\"messages\", protoFromName.getMessages())\n            .toString());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/TestAnySchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport com.google.protobuf.Any;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestAnySchema extends TestSchemaBase {\n  @Test\n  public void empty() throws Throwable {\n    scbMap = new HashMap<>();\n    scbMap.put(\"any\", null);\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n  }\n\n  @Test\n  public void anys_pack() throws IOException {\n    builder\n        .addAnys(Any.pack(ProtobufRoot.User.newBuilder().setName(\"n1\").build()))\n        .addAnys(Any.pack(ProtobufRoot.User.newBuilder().setName(\"n2\").build()));\n    check();\n  }\n\n  @Test\n  public void anys_json() throws IOException {\n    Root root = new Root();\n    root.setAnys(Arrays.asList(\"abc\", \"123\"));\n\n    scbRootBytes = rootSerializer.serialize(root);\n    root = rootDeserializer.deserialize(scbRootBytes);\n    MatcherAssert.assertThat(root.getAnys(), Matchers.contains(\"abc\", \"123\"));\n  }\n\n  @Test\n  public void pack() throws Throwable {\n    builder.setAny(Any.pack(ProtobufRoot.User.newBuilder().setName(\"n1\").build()));\n    check();\n\n    Map<String, Object> map = new HashMap<>();\n    map.put(ProtoConst.JSON_ID_NAME, \"User\");\n    map.put(\"name\", \"n1\");\n    Root root = new Root();\n    root.setAny(map);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(root));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void json_fromMapWithoutType() throws Throwable {\n    Map<String, Object> map = new HashMap<>();\n    map.put(\"name\", \"n1\");\n    Root root = new Root();\n    root.setAny(map);\n\n    scbRootBytes = rootSerializer.serialize(root);\n    root = rootDeserializer.deserialize(scbRootBytes);\n    MatcherAssert.assertThat(root.getAny(), Matchers.instanceOf(Map.class));\n    MatcherAssert.assertThat((Map<? extends String, ? extends String>) root.getAny(), Matchers.hasEntry(\"name\", \"n1\"));\n\n    RootDeserializer<Map<String, Object>> deserializer = protoMapper.createRootDeserializer(\"Root\", Map.class);\n    map = deserializer.deserialize(scbRootBytes);\n    MatcherAssert.assertThat((Map<? extends String, ? extends String>) map.get(\"any\"), Matchers.hasEntry(\"name\", \"n1\"));\n  }\n\n  @Test\n  public void json() throws Throwable {\n    Root root = new Root();\n    root.setAny(\"abc\");\n\n    scbRootBytes = rootSerializer.serialize(root);\n    root = rootDeserializer.deserialize(scbRootBytes);\n    Assertions.assertEquals(\"abc\", root.getAny());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/TestMapSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMapSchema extends TestSchemaBase {\n  @Test\n  public void ssMap() throws Throwable {\n    Map<String, String> ssMap = new HashMap<>();\n    ssMap.put(\"k1\", \"v1\");\n    ssMap.put(\"k2\", \"v2\");\n    builder.putAllSsMap(ssMap);\n\n    check();\n  }\n\n  @Test\n  public void spMap() throws Throwable {\n    builder.putSpMap(\"k1\", ProtobufRoot.User.newBuilder().setName(\"n1\").build());\n    builder.putSpMap(\"k2\", ProtobufRoot.User.newBuilder().setName(\"n2\").build());\n\n    check();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/TestMessageSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.CustomGeneric;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMessageSchema extends TestSchemaBase {\n  @Test\n  public void empty() throws Throwable {\n    check();\n\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(null));\n  }\n\n  @Test\n  public void generic() throws Throwable {\n    JavaType javaType = TypeFactory.defaultInstance().constructParametricType(CustomGeneric.class, User.class);\n    RootDeserializer<CustomGeneric<User>> genericDeserializer = protoMapper.createRootDeserializer(\"Root\", javaType);\n\n    builder.setUser(ProtobufRoot.User.newBuilder().setName(\"name1\").build());\n    check(genericDeserializer, mapRootDeserializer, rootSerializer, false);\n\n    @SuppressWarnings(\"unchecked\")\n    CustomGeneric<User> generic = (CustomGeneric<User>) scbRoot;\n    Assertions.assertNotNull(generic.user);\n  }\n\n  @Test\n  public void normal() throws Throwable {\n    builder.setString(\"abc\");\n    builder.setInt64(1L);\n    builder.setUser(ProtobufRoot.User.newBuilder().setName(\"name\").build());\n\n    check();\n\n    // map\n    Map<String, Object> map = new LinkedHashMap<>();\n    map.put(\"int64\", 1);\n    map.put(\"string\", \"abc\");\n\n    Map<String, Object> userMap = new LinkedHashMap<>();\n    userMap.put(\"name\", \"name\");\n    map.put(\"user\", userMap);\n\n    map.put(\"notExist\", null);\n\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(map));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/TestRepeatedSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.Color;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\n\nimport com.google.protobuf.ByteString;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestRepeatedSchema extends TestSchemaBase {\n  public static class RootWithArray {\n    public byte[][] bytess;\n\n    public String[] strings;\n\n    public User[] users;\n  }\n\n  @Test\n  public void fixed32s() throws Exception {\n    builder.addAllFixed32SPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void fixed32sNotPacked() throws Exception {\n    builder.addAllFixed32SNotPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sfixed32s() throws Exception {\n    builder.addAllSfixed32SPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sfixed32sNotPacked() throws Exception {\n    builder.addAllSfixed32SNotPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void int32s() throws Exception {\n    builder.addAllInt32SPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void int32sNotPacked() throws Exception {\n    builder.addAllInt32SNotPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sint32s() throws Exception {\n    builder.addAllSint32SPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sint32sNotPacked() throws Exception {\n    builder.addAllSint32SNotPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void uint32s() throws Exception {\n    builder.addAllUint32SPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void uint32sNotPacked() throws Exception {\n    builder.addAllUint32SNotPacked(Arrays.asList(Integer.MIN_VALUE, 0, Integer.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void fixed64s() throws Exception {\n    builder.addAllFixed64SPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void fixed64sNotPacked() throws Exception {\n    builder.addAllFixed64SNotPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sfixed64s() throws Exception {\n    builder.addAllSfixed64SPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sfixed64sNotPacked() throws Exception {\n    builder.addAllSfixed64SNotPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void int64s() throws Exception {\n    builder.addAllInt64SPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void int64sNotPacked() throws Exception {\n    builder.addAllInt64SNotPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sint64s() throws Exception {\n    builder.addAllSint64SPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void sint64sNotPacked() throws Exception {\n    builder.addAllSint64SNotPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void uint64s() throws Exception {\n    builder.addAllUint64SPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void uint64sNotPacked() throws Exception {\n    builder.addAllUint64SNotPacked(Arrays.asList(Long.MIN_VALUE, 0L, Long.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void floats() throws Exception {\n    builder.addAllFloatsPacked(Arrays.asList(Float.MIN_VALUE, (float) 0.0, Float.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void floatsNotPacked() throws Exception {\n    builder.addAllFloatsNotPacked(Arrays.asList(Float.MIN_VALUE, (float) 0.0, Float.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void doubles() throws Exception {\n    builder.addAllDoublesPacked(Arrays.asList(Double.MIN_VALUE, 0.0, Double.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void doublesNotPacked() throws Exception {\n    builder.addAllDoublesNotPacked(Arrays.asList(Double.MIN_VALUE, 0.0, Double.MAX_VALUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void bools() throws Exception {\n    builder.addAllBoolsPacked(Arrays.asList(Boolean.FALSE, Boolean.TRUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void boolsNotPacked() throws Exception {\n    builder.addAllBoolsNotPacked(Arrays.asList(Boolean.FALSE, Boolean.TRUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void enums() throws Exception {\n    builder.addAllColorsPacked(Arrays.asList(Color.RED, Color.BLUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void enumsNotPacked() throws Exception {\n    builder.addAllColorsNotPacked(Arrays.asList(Color.RED, Color.BLUE));\n    checkRepeatedWithPrimitive();\n  }\n\n  @Test\n  public void bytess() throws Throwable {\n    List<byte[]> sList = Arrays.asList(\"v1\".getBytes(StandardCharsets.UTF_8), \"v2\".getBytes(StandardCharsets.UTF_8));\n    builder.addAllBytess(Arrays.asList(ByteString.copyFromUtf8(\"v1\"), ByteString.copyFromUtf8(\"v2\")));\n    check();\n\n    RootWithArray rootWithArray = new RootWithArray();\n    rootWithArray.bytess = sList.toArray(new byte[0][]);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(rootWithArray));\n  }\n\n  @Test\n  public void strings() throws Throwable {\n    List<String> sList = Arrays.asList(\"v1\", \"v2\");\n    builder.addAllStrings(sList);\n    check();\n\n    RootWithArray rootWithArray = new RootWithArray();\n    rootWithArray.strings = sList.toArray(new String[0]);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(rootWithArray));\n  }\n\n  @Test\n  public void users() throws Throwable {\n    builder.addUsers(ProtobufRoot.User.newBuilder().setName(\"name1\").build());\n    builder.addUsers(ProtobufRoot.User.newBuilder().setName(\"name2\").build());\n\n    check();\n\n    RootWithArray rootWithArray = new RootWithArray();\n    rootWithArray.users = new User[] {new User(\"name1\"), new User(\"name2\")};\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(rootWithArray));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestBoolSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestBoolSchema extends TestSchemaBase {\n  public TestBoolSchema() {\n    initFields(\"bool\", \"objBool\");\n  }\n\n  @Test\n  public void testTrue() throws Throwable {\n    // normal\n    builder.setBool(true);\n    check();\n\n    // equalsIgnoreCase\n    doTestFromString(\"true\");\n    doTestFromString(\"true\");\n  }\n\n  @Test\n  public void testFalse() throws Throwable {\n    // normal\n    builder.setBool(false);\n    check();\n\n    // all not true is false\n    doTestFromString(\"false\");\n    doTestFromString(\"abcd\");\n  }\n\n  protected void doTestFromString(String value) throws Throwable {\n    // string[]\n    scbMap = new HashMap<>();\n    scbMap.put(\"bool\", new String[] {value});\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(scbMap));\n\n    // string\n    scbMap.put(\"bool\", value);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(scbMap));\n  }\n\n  @Test\n  public void nullOrEmpty() throws Throwable {\n    // null\n    scbMap = new HashMap<>();\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n\n    // empty string[]\n    scbMap.put(\"bool\", new String[] {});\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n  }\n\n  @Test\n  public void type_invalid() throws Throwable {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(\"bool\", new User());\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"not support serialize from org.apache.servicecomb.foundation.protobuf.internal.model.User to proto bool, field=org.apache.servicecomb.foundation.protobuf.internal.model.Root:bool\",\n            exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestBytesSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\n\nimport com.google.protobuf.ByteString;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestBytesSchema extends TestSchemaBase {\n  public TestBytesSchema() {\n    initField(\"bytes\");\n  }\n\n  @Test\n  public void normal() throws Throwable {\n    byte[] value = \"abc\".getBytes();\n    builder.setBytes(ByteString.copyFrom(value));\n    check();\n  }\n\n  @Test\n  public void type_invalid() {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(\"bytes\", new User());\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"not support serialize from org.apache.servicecomb.foundation.protobuf.internal.model.User to proto bytes, field=org.apache.servicecomb.foundation.protobuf.internal.model.Root:bytes\",\n            exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestDoubleSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestDoubleSchema extends TestNumberBaseSchema {\n  public TestDoubleSchema() {\n    minValue = Double.MIN_VALUE;\n    maxValue = Double.MAX_VALUE;\n    initFields(\"doubleValue\", \"objDoubleValue\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestEnumSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestEnumSchema extends TestSchemaBase {\n  @Test\n  public void empty() throws Throwable {\n    // null\n    scbMap = new HashMap<>();\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n\n    // empty string[]\n    scbMap.put(\"color\", new String[] {});\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n  }\n\n  public static class EnumRoot {\n    private int color;\n\n    public int getColor() {\n      return color;\n    }\n\n    public void setColor(int color) {\n      this.color = color;\n    }\n  }\n\n  @Test\n  public void normal() throws Throwable {\n    builder.setColorValue(2);\n    check();\n\n    Map<String, Object> map = new HashMap<>();\n    map.put(\"color\", Color.BLUE);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(map));\n\n    map.put(\"color\", 2);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(map));\n\n    map.put(\"color\", new String[] {\"BLUE\"});\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(map));\n\n    map.put(\"color\", \"BLUE\");\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(map));\n\n    EnumRoot enumRoot = protoMapper.<EnumRoot>createRootDeserializer(\"Root\", EnumRoot.class).deserialize(protobufBytes);\n    Assertions.assertEquals(2, enumRoot.color);\n  }\n\n  enum Sharp {\n    ROUND\n  }\n\n  @Test\n  public void fromInvalidEnum() throws Throwable {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(\"color\", Sharp.ROUND);\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"invalid enum name ROUND for proto Color, field=org.apache.servicecomb.foundation.protobuf.internal.model.Root:color\", exception.getMessage());\n  }\n\n  @Test\n  public void fromInvalidNumber() {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(\"color\", 3);\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"invalid enum value 3 for proto Color, field=org.apache.servicecomb.foundation.protobuf.internal.model.Root:color\", exception.getMessage());\n  }\n\n  @Test\n  public void type_invalid() {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(\"color\", new User());\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"not support serialize from org.apache.servicecomb.foundation.protobuf.internal.model.User to proto Color, field=org.apache.servicecomb.foundation.protobuf.internal.model.Root:color\",\n            exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestFixed32Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestFixed32Schema extends TestNumberBaseSchema {\n  public TestFixed32Schema() {\n    minValue = Integer.MIN_VALUE;\n    maxValue = Integer.MAX_VALUE;\n    initFields(\"fixed32\", \"objFixed32\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestFixed64Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestFixed64Schema extends TestNumberBaseSchema {\n  public TestFixed64Schema() {\n    minValue = Long.MIN_VALUE;\n    maxValue = Long.MAX_VALUE;\n    initFields(\"fixed64\", \"objFixed64\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestFloatSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestFloatSchema extends TestNumberBaseSchema {\n  public TestFloatSchema() {\n    minValue = Float.MIN_VALUE;\n    maxValue = Float.MAX_VALUE;\n    initFields(\"floatValue\", \"objFloatValue\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestInt32Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestInt32Schema extends TestNumberBaseSchema {\n  public TestInt32Schema() {\n    minValue = Integer.MIN_VALUE;\n    maxValue = Integer.MAX_VALUE;\n    initFields(\"int32\", \"objInt32\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestInt64Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestInt64Schema extends TestNumberBaseSchema {\n  public TestInt64Schema() {\n    minValue = Long.MIN_VALUE;\n    maxValue = Long.MAX_VALUE;\n    initFields(\"int64\", \"objInt64\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestNumberBaseSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\nimport java.io.IOException;\nimport java.lang.reflect.Method;\nimport java.util.HashMap;\nimport java.util.Locale;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\nimport io.protostuff.compiler.model.Field;\nimport io.protostuff.compiler.model.Type;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Disabled;\nimport org.junit.jupiter.api.Test;\n\n@Disabled\npublic abstract class TestNumberBaseSchema extends TestSchemaBase {\n  protected Object minValue;\n\n  protected Object maxValue;\n\n  @Test\n  public void normal() throws Throwable {\n    byte[] primitiveBytes = doTestPojoNormal(primitiveFieldName);\n    byte[] bytes = doTestPojoNormal(fieldName);\n\n    doTestMapNormal(primitiveFieldName, maxValue, primitiveBytes);\n    doTestMapNormal(fieldName, maxValue, bytes);\n  }\n\n  private void doTestMapNormal(String field, Object value, byte[] expectBytes) throws IOException {\n    // null\n    scbMap = new HashMap<>();\n    scbMap.put(field, null);\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n\n    // empty string[]\n    scbMap.put(field, new String[] {});\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n\n    // string[]\n    scbMap.put(field, new String[] {String.valueOf(value)});\n    Assertions.assertArrayEquals(expectBytes, rootSerializer.serialize(scbMap));\n\n    // string\n    scbMap.put(field, String.valueOf(value));\n    Assertions.assertArrayEquals(expectBytes, rootSerializer.serialize(scbMap));\n  }\n\n  private byte[] doTestPojoNormal(String name) throws Throwable {\n    builder = ProtobufRoot.Root.newBuilder();\n    String setName = \"set\" + name.substring(0, 1).toUpperCase(Locale.US) + name.substring(1);\n    Method builderSetter = ReflectUtils.findMethod(builder.getClass(), setName);\n\n    builderSetter.invoke(builder, minValue);\n    check();\n\n    builderSetter.invoke(builder, maxValue);\n    check();\n\n    return protobufBytes;\n  }\n\n  @Test\n  public void primitiveStrings_invalid() throws Throwable {\n    strings_invalid(primitiveProtoField);\n  }\n\n  @Test\n  public void strings_invalid() throws Throwable {\n    strings_invalid(protoField);\n  }\n\n  private void strings_invalid(Field field) {\n    NumberFormatException exception = Assertions.assertThrows(NumberFormatException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(field.getName(), new String[] {\"a\"});\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"For input string: \\\"a\\\"\", exception.getMessage());\n  }\n\n  @Test\n  public void primitiveString_invalid() throws Throwable {\n    string_invalid(primitiveProtoField);\n  }\n\n  @Test\n  public void string_invalid() throws Throwable {\n    string_invalid(protoField);\n  }\n\n  private void string_invalid(Field field) {\n    NumberFormatException exception = Assertions.assertThrows(NumberFormatException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(field.getName(), \"a\");\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"For input string: \\\"a\\\"\", exception.getMessage());\n  }\n\n  @Test\n  public void primitiveType_invalid() {\n    type_invalid(primitiveProtoField);\n  }\n\n  @Test\n  public void type_invalid() throws Throwable {\n    type_invalid(protoField);\n  }\n\n  private void type_invalid(Field field) {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(field.getName(), new User());\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(String.format(\"not support serialize from %s to proto %s, field=%s:%s\",\n            User.class.getName(),\n            field.getTypeName(),\n            ((Type) field.getParent()).getCanonicalName(),\n            field.getName()), exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestSFixed32Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestSFixed32Schema extends TestNumberBaseSchema {\n  public TestSFixed32Schema() {\n    minValue = Integer.MIN_VALUE;\n    maxValue = Integer.MAX_VALUE;\n    initFields(\"sfixed32\", \"objSfixed32\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestSFixed64Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestSFixed64Schema extends TestNumberBaseSchema {\n  public TestSFixed64Schema() {\n    minValue = Long.MIN_VALUE;\n    maxValue = Long.MAX_VALUE;\n    initFields(\"sfixed64\", \"objSfixed64\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestSInt32Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestSInt32Schema extends TestNumberBaseSchema {\n  public TestSInt32Schema() {\n    minValue = Integer.MIN_VALUE;\n    maxValue = Integer.MAX_VALUE;\n    initFields(\"sint32\", \"objSint32\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestSInt64Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestSInt64Schema extends TestNumberBaseSchema {\n  public TestSInt64Schema() {\n    minValue = Long.MIN_VALUE;\n    maxValue = Long.MAX_VALUE;\n    initFields(\"sint64\", \"objSint64\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestStringSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.TestSchemaBase;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestStringSchema extends TestSchemaBase {\n  @Test\n  public void normal() throws Throwable {\n    String value = \"abc\";\n    builder.setString(value);\n    check();\n\n    // string[]\n    scbMap = new HashMap<>();\n    scbMap.put(\"string\", new String[] {value});\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(scbMap));\n\n    // string\n    scbMap.put(\"string\", value);\n    Assertions.assertArrayEquals(protobufBytes, rootSerializer.serialize(scbMap));\n  }\n\n  @Test\n  public void nullOrEmpty() throws Throwable {\n    // null\n    scbMap = new HashMap<>();\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n\n    // empty string[]\n    scbMap.put(\"string\", new String[] {});\n    Assertions.assertEquals(0, rootSerializer.serialize(scbMap).length);\n  }\n\n  @Test\n  public void type_invalid() throws Throwable {\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class, () -> {\n      scbMap = new HashMap<>();\n      scbMap.put(\"string\", new User());\n      rootSerializer.serialize(scbMap);\n    });\n    Assertions.assertEquals(\"not support serialize from org.apache.servicecomb.foundation.protobuf.internal.model.User to proto string, field=org.apache.servicecomb.foundation.protobuf.internal.model.Root:string\",\n            exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestUInt32Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestUInt32Schema extends TestNumberBaseSchema {\n  public TestUInt32Schema() {\n    minValue = Integer.MIN_VALUE;\n    maxValue = Integer.MAX_VALUE;\n    initFields(\"uint32\", \"objUint32\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/schema/scalar/TestUInt64Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.internal.schema.scalar;\n\npublic class TestUInt64Schema extends TestNumberBaseSchema {\n  public TestUInt64Schema() {\n    minValue = Long.MIN_VALUE;\n    maxValue = Long.MAX_VALUE;\n    initFields(\"uint64\", \"objUint64\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/ProtubufCodecEngine.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance;\n\nimport java.io.IOException;\n\npublic interface ProtubufCodecEngine {\n  byte[] serialize(Object model) throws IOException;\n\n  Object deserialize(byte[] bytes) throws IOException;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/TestBase.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance;\n\nimport java.io.IOException;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.Jackson;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.Protobuf;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.Protostuff;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.ScbStrong;\nimport org.apache.servicecomb.foundation.protobuf.performance.engine.ScbWeak;\n\npublic abstract class TestBase {\n  public interface Case {\n    TestEngineResult run();\n  }\n\n  static ProtubufCodecEngine scbStrong = new ScbStrong();\n\n  static ProtubufCodecEngine scbWeak = new ScbWeak();\n\n  static ProtubufCodecEngine protoStuff = new Protostuff();\n\n  static ProtubufCodecEngine protobuf = new Protobuf();\n\n  static ProtubufCodecEngine jackson = new Jackson();\n\n  protected Root pojoRoot = new Root();\n\n  protected Map<String, Object> pojoRootMap;\n\n  protected ProtobufRoot.Root.Builder builder = ProtobufRoot.Root.newBuilder();\n\n  @SuppressWarnings(\"unchecked\")\n  public TestResult run(int count) throws IOException {\n    pojoRootMap = (Map<String, Object>) Jackson.jsonMapper.convertValue(pojoRoot, Map.class);\n    // warm\n    doRun(10_000);\n\n    // real test\n    return doRun(count);\n  }\n\n  private TestResult doRun(int count) throws IOException {\n    TestResult testResult = new TestResult();\n    testResult.name = this.getClass().getSimpleName();\n\n    testResult.addTestEngineResult(runOneEngine(protoStuff, pojoRoot, count));\n    testResult.addTestEngineResult(runOneEngine(scbStrong, pojoRoot, count));\n    testResult.addTestEngineResult(runOneEngine(scbWeak, pojoRootMap, count));\n    testResult.addTestEngineResult(runOneEngine(protobuf, builder, count));\n    testResult.addTestEngineResult(runOneEngine(jackson, pojoRoot, count));\n    return testResult;\n  }\n\n  private TestEngineResult runOneEngine(ProtubufCodecEngine engine, Object model, int count)\n      throws IOException {\n    TestEngineResult engineResult = new TestEngineResult();\n    engineResult.engineName = engine.getClass().getSimpleName();\n\n    // serialize\n    {\n      long msStart = System.currentTimeMillis();\n      for (int idx = 0; idx < count; idx++) {\n        engineResult.serializeBytes = engine.serialize(model);\n      }\n      long msEnd = System.currentTimeMillis();\n\n      engineResult.msSerializeTime = msEnd - msStart;\n    }\n\n    // deserialize\n    {\n      long msStart = System.currentTimeMillis();\n      for (int idx = 0; idx < count; idx++) {\n        engineResult.deserializeResult = engine.deserialize(engineResult.serializeBytes);\n      }\n      long msEnd = System.currentTimeMillis();\n\n      engineResult.msDeserializeTime = msEnd - msStart;\n    }\n\n    engineResult.deserializeResultBytes = engine.serialize(engineResult.deserializeResult);\n    return engineResult;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/TestEngineResult.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance;\n\npublic class TestEngineResult {\n  public String engineName;\n\n  // serialize\n  public long msSerializeTime;\n\n  public byte[] serializeBytes;\n\n  // deserialize\n  public long msDeserializeTime;\n\n  public Object deserializeResult;\n\n  public byte[] deserializeResultBytes;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/TestProtoPerformance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.Empty;\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.Map;\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.Mixed;\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.Pojo;\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.PojoList;\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.Scalars;\nimport org.apache.servicecomb.foundation.protobuf.performance.cases.SimpleList;\n\nimport com.google.common.base.Strings;\n\npublic class TestProtoPerformance {\n  public static void main(String[] args) throws IOException {\n    System.out.println(\"1.protobuf\\n\"\n        + \"  in our real scenes\\n\"\n        + \"  business model never bind to transport, and can switch between different transports dynamically\\n\"\n        + \"  that means if we choose standard protobuf, must build protobuf models from business models each time\\n\"\n        + \"  so should be much slower than the test results\");\n    System.out.println(\"2.protoStuff\\n\"\n        + \"  some scenes, there is no field but have getter or setter, so we can not use unsafe to access field\\n\"\n        + \"  so we disable protoStuff unsafe feature\\n\\n\"\n        + \"  for repeated fields, protoStuff have better performance, but not compatible to protobuf\\n\");\n    System.out.println(\"3.jackson\\n\"\n        + \"  not support map/any/recursive, ignore related fields\");\n    System.out.println(\"4.serialize result size\\n\"\n        + \"  ScbStrong/ScbWeak/Protobuf have the same and smaller size, because skip all default/null value\");\n\n    System.setProperty(\"protostuff.runtime.use_sun_misc_unsafe\", \"false\");\n\n    int count = 50_0000;\n\n    printResult(new Empty().run(count));\n    printResult(new Scalars().run(count));\n    printResult(new Pojo().run(count));\n    printResult(new SimpleList().run(count));\n    printResult(new PojoList().run(count));\n    printResult(new Map().run(count));\n    printResult(new Mixed().run(count));\n  }\n\n  private static void printResult(TestResult result) {\n    String strFmt = Strings.repeat(\"%-11s\", result.engineResults.size());\n    String numberFmt = Strings.repeat(\"%-11d\", result.engineResults.size());\n\n    System.out.println(result.name + \": \");\n    System.out.printf(\"                \" + strFmt + \"\\n\",\n        result.engineResults.stream().map(r -> r.engineName).toArray());\n\n    System.out.printf(\"serialize time(ms)  : \" + numberFmt + \"\\n\",\n        result.engineResults.stream().map(r -> r.msSerializeTime).toArray());\n    System.out.printf(\"serialize len       : \" + numberFmt + \"\\n\",\n        result.engineResults.stream().map(r -> r.serializeBytes.length).toArray());\n\n    System.out.printf(\"deserialize time(ms): \" + numberFmt + \"\\n\",\n        result.engineResults.stream().map(r -> r.msDeserializeTime).toArray());\n    System.out.printf(\"deserialize->serialize len: \" + numberFmt + \"\\n\",\n        result.engineResults.stream().map(r -> r.deserializeResultBytes.length).toArray());\n\n    System.out.printf(\"serialize+deserialize(ms) : \" + numberFmt + \"\\n\\n\",\n        result.engineResults.stream().map(r -> r.msSerializeTime + r.msDeserializeTime).toArray());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/TestResult.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class TestResult {\n  public String name;\n\n  public List<TestEngineResult> engineResults = new ArrayList<>();\n\n  public void addTestEngineResult(TestEngineResult engineResult) {\n    engineResults.add(engineResult);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/Empty.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\n\npublic class Empty extends TestBase {\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/Map.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.User;\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\n\npublic class Map extends TestBase {\n  public Map() {\n    pojoRoot.setSsMap(new HashMap<>());\n    pojoRoot.getSsMap().put(\"k1\", \"v1\");\n    pojoRoot.getSsMap().put(\"k2\", \"v2\");\n    pojoRoot.setSpMap(new HashMap<>());\n    pojoRoot.getSpMap().put(\"u1\", new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name1\"));\n    pojoRoot.getSpMap().put(\"u2\", new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name2\"));\n\n    builder.putSsMap(\"k1\", \"v1\")\n        .putSsMap(\"k2\", \"v2\")\n        .putSpMap(\"u1\", User.newBuilder().setName(\"name1\").build())\n        .putSpMap(\"u2\", User.newBuilder().setName(\"name2\").build());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/Mixed.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport java.util.Arrays;\nimport java.util.LinkedHashMap;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.User;\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\n\npublic class Mixed extends TestBase {\n  public Mixed() {\n    pojoRoot.setInt32(10000);\n    pojoRoot.setInt64(20000L);\n    pojoRoot.setUint32(30000);\n    pojoRoot.setUint64(40000L);\n    pojoRoot.setSint32(50000);\n    pojoRoot.setSint64(60000L);\n    pojoRoot.setFixed32(70000);\n    pojoRoot.setFixed64(80000L);\n    pojoRoot.setSfixed32(90000);\n    pojoRoot.setSfixed64(100000L);\n    pojoRoot.setFloatValue((float) 10000);\n    pojoRoot.setDoubleValue(20000.0);\n    pojoRoot.setBool(true);\n\n    pojoRoot.setObjInt32(10000);\n    pojoRoot.setObjInt64(20000L);\n    pojoRoot.setObjUint32(30000);\n    pojoRoot.setObjUint64(40000L);\n    pojoRoot.setObjSint32(50000);\n    pojoRoot.setObjSint64(60000L);\n    pojoRoot.setObjFixed32(70000);\n    pojoRoot.setObjFixed64(80000L);\n    pojoRoot.setObjSfixed32(90000);\n    pojoRoot.setObjSfixed64(100000L);\n    pojoRoot.setObjFloatValue((float) 10000);\n    pojoRoot.setObjDoubleValue(20000.0);\n    pojoRoot.setObjBool(true);\n\n    pojoRoot.setString(\"string value\");\n    pojoRoot.setColor(Color.BLUE);\n    pojoRoot.setUser(new org.apache.servicecomb.foundation.protobuf.internal.model.User(\"name1\"));\n\n    pojoRoot.setSsMap(new LinkedHashMap<>());\n    pojoRoot.getSsMap().put(\"k1\", \"v1\");\n    pojoRoot.getSsMap().put(\"k2\", \"v2\");\n    pojoRoot.setSpMap(new LinkedHashMap<>());\n    pojoRoot.getSpMap().put(\"u1\", new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name1\"));\n    pojoRoot.getSpMap().put(\"u2\", new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name2\"));\n\n    pojoRoot.setInt32sPacked(Arrays.asList(10000, 20000, 30000));\n    pojoRoot.setInt64sPacked(Arrays.asList(10000L, 20000L, 30000L));\n    pojoRoot.setUint32sPacked(Arrays.asList(10000, 20000, 30000));\n    pojoRoot.setUint64sPacked(Arrays.asList(10000L, 20000L, 30000L));\n    pojoRoot.setSint32sPacked(Arrays.asList(10000, 20000, 30000));\n    pojoRoot.setSint64sPacked(Arrays.asList(10000L, 20000L, 30000L));\n    pojoRoot.setFixed32sPacked(Arrays.asList(10000, 20000, 30000));\n    pojoRoot.setFixed64sPacked(Arrays.asList(10000L, 20000L, 30000L));\n    pojoRoot.setSfixed32sPacked(Arrays.asList(10000, 20000, 30000));\n    pojoRoot.setSfixed64sPacked(Arrays.asList(10000L, 20000L, 30000L));\n    pojoRoot.setFloatsPacked(Arrays.asList((float) 10000, (float) 20000, (float) 30000));\n    pojoRoot.setDoublesPacked(Arrays.asList(10000.0, 20000.0, 30000.0));\n    pojoRoot.setBoolsPacked(Arrays.asList(true, false));\n    pojoRoot.setColorsPacked(Arrays.asList(Color.RED, Color.BLUE));\n\n    pojoRoot.setStrings(Arrays.asList(\"string value1\", \"string value2\"));\n    pojoRoot.setUsers(Arrays.asList(\n        new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name1\"),\n        new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name2\"),\n        new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name3\"),\n        new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name4\")));\n\n    builder.setInt32(10000)\n        .setInt64(20000L)\n        .setUint32(30000)\n        .setUint64(40000L)\n        .setSint32(50000)\n        .setSint64(60000L)\n        .setFixed32(70000)\n        .setFixed64(80000L)\n        .setSfixed32(90000)\n        .setSfixed64(100000L)\n        .setFloatValue((float) 10000)\n        .setDoubleValue(20000.0)\n        .setBool(true)\n\n        .setObjInt32(10000)\n        .setObjInt64(20000L)\n        .setObjUint32(30000)\n        .setObjUint64(40000L)\n        .setObjSint32(50000)\n        .setObjSint64(60000L)\n        .setObjFixed32(70000)\n        .setObjFixed64(80000L)\n        .setObjSfixed32(90000)\n        .setObjSfixed64(100000L)\n        .setObjFloatValue((float) 10000)\n        .setObjDoubleValue(20000.0)\n        .setObjBool(true)\n\n        .setString(\"string value\")\n        .setColorValue(2)\n        .setUser(User.newBuilder().setName(\"name1\").build())\n\n        .putSsMap(\"k1\", \"v1\")\n        .putSsMap(\"k2\", \"v2\")\n        .putSpMap(\"u1\", User.newBuilder().setName(\"name1\").build())\n        .putSpMap(\"u2\", User.newBuilder().setName(\"name2\").build())\n\n        .addAllInt32SPacked(Arrays.asList(10000, 20000, 30000))\n        .addAllInt64SPacked(Arrays.asList(10000L, 20000L, 30000L))\n        .addAllUint32SPacked(Arrays.asList(10000, 20000, 30000))\n        .addAllUint64SPacked(Arrays.asList(10000L, 20000L, 30000L))\n        .addAllSint32SPacked(Arrays.asList(10000, 20000, 30000))\n        .addAllSint64SPacked(Arrays.asList(10000L, 20000L, 30000L))\n        .addAllFixed32SPacked(Arrays.asList(10000, 20000, 30000))\n        .addAllFixed64SPacked(Arrays.asList(10000L, 20000L, 30000L))\n        .addAllSfixed32SPacked(Arrays.asList(10000, 20000, 30000))\n        .addAllSfixed64SPacked(Arrays.asList(10000L, 20000L, 30000L))\n        .addAllFloatsPacked(Arrays.asList((float) 10000, (float) 20000, (float) 30000))\n        .addAllDoublesPacked(Arrays.asList(10000.0, 20000.0, 30000.0))\n        .addAllBoolsPacked(Arrays.asList(true, false))\n        .addAllColorsPacked(Arrays.asList(ProtobufRoot.Color.RED, ProtobufRoot.Color.BLUE))\n\n        .addStrings(\"string value1\")\n        .addStrings(\"string value2\")\n        .addUsers(User.newBuilder().setName(\"name1\").build())\n        .addUsers(User.newBuilder().setName(\"name2\").build())\n        .addUsers(User.newBuilder().setName(\"name3\").build())\n        .addUsers(User.newBuilder().setName(\"name4\").build());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/Pojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.User;\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\n\npublic class Pojo extends TestBase {\n  public Pojo() {\n    pojoRoot.setUser(new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name1\"));\n\n    builder.setUser(User.newBuilder().setName(\"name1\").build());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/PojoList.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.User;\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\n\npublic class PojoList extends TestBase {\n  public PojoList() {\n    pojoRoot.setUsers(Arrays.asList(\n        new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name1\"),\n        new org.apache.servicecomb.foundation.protobuf.internal.model.User().name(\"name2\")));\n\n    builder.addUsers(User.newBuilder().setName(\"name1\").build())\n        .addUsers(User.newBuilder().setName(\"name2\").build());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/Scalars.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\n\npublic class Scalars extends TestBase {\n  public Scalars() {\n    pojoRoot.setInt32(10000);\n    pojoRoot.setInt64(10000L);\n    pojoRoot.setString(\"string value\");\n    pojoRoot.setColor(Color.BLUE);\n\n    builder.setInt32(10000)\n        .setInt64(10000L)\n        .setString(\"string value\")\n        .setColorValue(2);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/cases/SimpleList.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.cases;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.foundation.protobuf.performance.TestBase;\n\npublic class SimpleList extends TestBase {\n  public SimpleList() {\n    pojoRoot.setStrings(Arrays.asList(\"string value1\", \"string value2\"));\n\n    builder.addStrings(\"string value1\")\n        .addStrings(\"string value2\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/engine/Jackson.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.engine;\n\nimport java.io.IOException;\nimport java.net.URL;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.User;\nimport org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.ObjectReader;\nimport com.fasterxml.jackson.databind.ObjectWriter;\nimport com.fasterxml.jackson.dataformat.protobuf.ProtobufMapper;\nimport com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchema;\nimport com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchemaLoader;\n\npublic class Jackson implements ProtubufCodecEngine {\n  @JsonIgnoreProperties({\"ssMap\", \"spMap\", \"sint32Map\", \"any\", \"anys\", \"typeRecursive\"})\n  interface RootMixin {\n  }\n\n  @JsonIgnoreProperties({\"typeRecursive\"})\n  interface UserMixin {\n  }\n\n  public static ObjectMapper jsonMapper = new ObjectMapper();\n\n  static ProtobufMapper protobufMapper = new ProtobufMapper();\n\n  static URL url = Jackson.class.getClassLoader().getResource(\"jacksonRoot.proto\");\n\n  static ProtobufSchema protobufSchema;\n\n  static {\n    protobufMapper.addMixIn(Root.class, RootMixin.class);\n    protobufMapper.addMixIn(User.class, UserMixin.class);\n    try {\n      protobufSchema = ProtobufSchemaLoader.std.load(url);\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  static ObjectWriter writer = protobufMapper.writer(protobufSchema);\n\n  static ObjectReader reader = protobufMapper.reader(protobufSchema).forType(Root.class);\n\n  @Override\n  public byte[] serialize(Object model) throws IOException {\n    return writer.writeValueAsBytes(model);\n  }\n\n  @Override\n  public Object deserialize(byte[] bytes) throws IOException {\n    return reader.readValue(bytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/engine/Protobuf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.engine;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.Root;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot.Root.Builder;\nimport org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;\n\npublic class Protobuf implements ProtubufCodecEngine {\n  @Override\n  public byte[] serialize(Object builder) {\n    return ((Builder) builder).build().toByteArray();\n  }\n\n  @Override\n  public Object deserialize(byte[] bytes) throws IOException {\n    Root.Builder builder = ProtobufRoot.Root.newBuilder().mergeFrom(bytes);\n    builder.build();\n    return builder;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/engine/Protostuff.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.engine;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\nimport org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;\n\nimport io.protostuff.ByteArrayInput;\nimport io.protostuff.Input;\nimport io.protostuff.LinkedBuffer;\nimport io.protostuff.ProtobufOutput;\nimport io.protostuff.Schema;\nimport io.protostuff.runtime.RuntimeSchema;\n\npublic class Protostuff implements ProtubufCodecEngine {\n  static Schema<Root> rootSchema = RuntimeSchema.createFrom(Root.class);\n\n  @Override\n  public byte[] serialize(Object model) throws IOException {\n    LinkedBuffer linkedBuffer = LinkedBuffer.allocate();\n    ProtobufOutput output = new ProtobufOutput(linkedBuffer);\n    if (model != null) {\n      rootSchema.writeTo(output, (Root) model);\n    }\n    return output.toByteArray();\n  }\n\n  @Override\n  public Object deserialize(byte[] bytes) throws IOException {\n    Input input = new ByteArrayInput(bytes, false);\n    Root result = new Root();\n    rootSchema.mergeFrom(input, result);\n    return result;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/engine/SCB.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.engine;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapper;\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.internal.model.Root;\n\npublic class SCB {\n  static ProtoMapperFactory factory = new ProtoMapperFactory();\n\n  static ProtoMapper protoMapper = factory.createFromName(\"protobufRoot.proto\");\n\n  static RootSerializer serializer = protoMapper.createRootSerializer(\"Root\", Root.class);\n\n  static RootDeserializer<Root> deserializer = protoMapper.createRootDeserializer(\"Root\", Root.class);\n\n  static RootDeserializer<Map<String, Object>> mapDeserializer = protoMapper.createRootDeserializer(\"Root\", Map.class);\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/engine/ScbStrong.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.engine;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;\n\npublic class ScbStrong implements ProtubufCodecEngine {\n  @Override\n  public byte[] serialize(Object model) throws IOException {\n    return SCB.serializer.serialize(model);\n  }\n\n  @Override\n  public Object deserialize(byte[] bytes) throws IOException {\n    return SCB.deserializer.deserialize(bytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/performance/engine/ScbWeak.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.protobuf.performance.engine;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;\n\npublic class ScbWeak implements ProtubufCodecEngine {\n  @Override\n  public byte[] serialize(Object model) throws IOException {\n    return SCB.serializer.serialize(model);\n  }\n\n  @Override\n  public Object deserialize(byte[] bytes) throws IOException {\n    return SCB.mapDeserializer.deserialize(bytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/resources/jacksonRoot.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto2\";\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\nmessage Root {\n  optional int32 int32 = 1;\n  optional int64 int64 = 2;\n  optional uint32 uint32 = 3;\n  optional uint64 uint64 = 4;\n  optional sint32 sint32 = 5;\n  optional sint64 sint64 = 6;\n  optional fixed32 fixed32 = 7;\n  optional fixed64 fixed64 = 8;\n  optional sfixed32 sfixed32 = 9;\n  optional sfixed64 sfixed64 = 10;\n  optional float floatValue = 11;\n  optional double doubleValue = 12;\n  optional bool bool = 13;\n\n  optional int32 objInt32 = 20;\n  optional int64 objInt64 = 21;\n  optional uint32 objUint32 = 22;\n  optional uint64 objUint64 = 23;\n  optional sint32 objSint32 = 24;\n  optional sint64 objSint64 = 25;\n  optional fixed32 objFixed32 = 26;\n  optional fixed64 objFixed64 = 27;\n  optional sfixed32 objSfixed32 = 28;\n  optional sfixed64 objSfixed64 = 29;\n  optional float objFloatValue = 30;\n  optional double objDoubleValue = 31;\n  optional bool objBool = 32;\n\n  optional string string = 40;\n  optional bytes bytes = 41;\n  optional Color color = 42;\n  optional User user = 43;\n\n  repeated int32 int32sPacked = 70;\n  repeated int64 int64sPacked = 71;\n  repeated uint32 uint32sPacked = 72;\n  repeated uint64 uint64sPacked = 73;\n  repeated sint32 sint32sPacked = 74;\n  repeated sint64 sint64sPacked = 75;\n  repeated fixed32 fixed32sPacked = 76;\n  repeated fixed64 fixed64sPacked = 77;\n  repeated sfixed32 sfixed32sPacked = 78;\n  repeated sfixed64 sfixed64sPacked = 79;\n  repeated float floatsPacked = 80;\n  repeated double doublesPacked = 81;\n  repeated bool boolsPacked = 82;\n  repeated Color colorsPacked = 83;\n\n  repeated int32 int32sNotPacked = 90 [packed = false];\n  repeated int64 int64sNotPacked = 91 [packed = false];\n  repeated uint32 uint32sNotPacked = 92 [packed = false];\n  repeated uint64 uint64sNotPacked = 93 [packed = false];\n  repeated sint32 sint32sNotPacked = 94 [packed = false];\n  repeated sint64 sint64sNotPacked = 95 [packed = false];\n  repeated fixed32 fixed32sNotPacked = 96 [packed = false];\n  repeated fixed64 fixed64sNotPacked = 97 [packed = false];\n  repeated sfixed32 sfixed32sNotPacked = 98 [packed = false];\n  repeated sfixed64 sfixed64sNotPacked = 99 [packed = false];\n  repeated float floatsNotPacked = 100 [packed = false];\n  repeated double doublesNotPacked = 101 [packed = false];\n  repeated bool boolsNotPacked = 102 [packed = false];\n  repeated Color colorsNotPacked = 103 [packed = false];\n\n  repeated string strings = 110;\n  repeated bytes bytess = 111;\n  repeated User users = 112;\n}\n\nenum Color {\n  RED = 0;\n  YELLOW = 1;\n  BLUE = 2;\n}\n\nmessage User {\n  optional string name = 1;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/resources/method.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\n\n//@WrapArguments\nmessage RequestWrap {\n  bool boolValue = 1;\n  repeated int32 iArr = 2;\n  repeated User user = 3;\n}\n\nmessage Request {\n  bool boolValue = 1;\n  repeated int32 iArr = 2;\n  repeated User user = 3;\n}\n\n//@WrapProperty\nmessage ResponseWrap {\n  repeated int32 value = 1;\n}\n\nmessage Response {\n  repeated int32 value = 1;\n}\n\nmessage User {\n  string name = 1;\n  repeated User friends = 2;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/resources/model.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\n\nmessage PojoModel {\n  repeated PojoListUser listListUser = 1;\n  repeated PojoMapUser listMapUser = 2;\n  map<string, PojoListUser> mapListUser = 3;\n  map<string, PojoMapUser> mapMapUser = 4;\n\n  repeated PojoListListUser listListListUser = 5;\n  repeated PojoListMapUser listListMapUser = 6;\n  repeated PojoMapListUser listMapListUser = 7;\n  repeated PojoMapMapUser listMapMapUser = 8;\n  map<string, PojoListListUser> mapListListUser = 9;\n  map<string, PojoListMapUser> mapListMapUser = 10;\n  map<string, PojoMapListUser> mapMapListUser = 11;\n  map<string, PojoMapMapUser> mapMapMapUser = 12;\n}\n\nmessage ProtoModel {\n  repeated ProtoListUser listListUser = 1;\n  repeated ProtoMapUser listMapUser = 2;\n  map<string, ProtoListUser> mapListUser = 3;\n  map<string, ProtoMapUser> mapMapUser = 4;\n\n  repeated ProtoListListUser listListListUser = 5;\n  repeated ProtoListMapUser listListMapUser = 6;\n  repeated ProtoMapListUser listMapListUser = 7;\n  repeated ProtoMapMapUser listMapMapUser = 8;\n  map<string, ProtoListListUser> mapListListUser = 9;\n  map<string, ProtoListMapUser> mapListMapUser = 10;\n  map<string, ProtoMapListUser> mapMapListUser = 11;\n  map<string, ProtoMapMapUser> mapMapMapUser = 12;\n}\n\n//@WrapProperty\nmessage PojoListListUser {\n  repeated PojoListUser value = 1;\n}\n\n//@WrapProperty\nmessage PojoListMapUser {\n  repeated PojoMapUser value = 1;\n}\n\n//@WrapProperty\nmessage PojoMapListUser {\n  map<string, PojoListUser> value = 1;\n}\n\n//@WrapProperty\nmessage PojoMapMapUser {\n  map<string, PojoMapUser> value = 1;\n}\n\n//@WrapProperty\nmessage PojoListUser {\n  repeated User value = 1;\n}\n\n//@WrapProperty\nmessage PojoMapUser {\n  map<string, User> value = 1;\n}\n\nmessage User {\n  string name = 1;\n}\n\nmessage ProtoListListUser {\n  repeated ProtoListUser value = 1;\n}\n\nmessage ProtoListMapUser {\n  repeated ProtoMapUser value = 1;\n}\n\nmessage ProtoMapListUser {\n  map<string, ProtoListUser> value = 1;\n}\n\nmessage ProtoMapMapUser {\n  map<string, ProtoMapUser> value = 1;\n}\n\nmessage ProtoListUser {\n  repeated User value = 1;\n}\n\nmessage ProtoMapUser {\n  map<string, User> value = 1;\n}\n"
  },
  {
    "path": "foundations/foundation-protobuf/src/test/resources/protobufRoot.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\nimport \"google/protobuf/any.proto\";\npackage org.apache.servicecomb.foundation.protobuf.internal.model;\n\noption java_package = \"org.apache.servicecomb.foundation.protobuf.internal.model\";\noption java_outer_classname = \"ProtobufRoot\";\n\nmessage Root {\n  int32 int32 = 1;\n  int64 int64 = 2;\n  uint32 uint32 = 3;\n  uint64 uint64 = 4;\n  sint32 sint32 = 5;\n  sint64 sint64 = 6;\n  fixed32 fixed32 = 7;\n  fixed64 fixed64 = 8;\n  sfixed32 sfixed32 = 9;\n  sfixed64 sfixed64 = 10;\n  float floatValue = 11;\n  double doubleValue = 12;\n  bool bool = 13;\n\n  int32 objInt32 = 20;\n  int64 objInt64 = 21;\n  uint32 objUint32 = 22;\n  uint64 objUint64 = 23;\n  sint32 objSint32 = 24;\n  sint64 objSint64 = 25;\n  fixed32 objFixed32 = 26;\n  fixed64 objFixed64 = 27;\n  sfixed32 objSfixed32 = 28;\n  sfixed64 objSfixed64 = 29;\n  float objFloatValue = 30;\n  double objDoubleValue = 31;\n  bool objBool = 32;\n\n  string string = 40;\n  bytes bytes = 41;\n  Color color = 42;\n  User user = 43;\n  Root typeRecursive = 44;\n\n  google.protobuf.Any any = 50;\n  repeated google.protobuf.Any anys = 51;\n\n  map<string, string> ssMap = 60;\n  map<string, int32> sint32Map = 61;\n  map<string, User> spMap = 62;\n\n  repeated int32 int32sPacked = 70;\n  repeated int64 int64sPacked = 71;\n  repeated uint32 uint32sPacked = 72;\n  repeated uint64 uint64sPacked = 73;\n  repeated sint32 sint32sPacked = 74;\n  repeated sint64 sint64sPacked = 75;\n  repeated fixed32 fixed32sPacked = 76;\n  repeated fixed64 fixed64sPacked = 77;\n  repeated sfixed32 sfixed32sPacked = 78;\n  repeated sfixed64 sfixed64sPacked = 79;\n  repeated float floatsPacked = 80;\n  repeated double doublesPacked = 81;\n  repeated bool boolsPacked = 82;\n  repeated Color colorsPacked = 83;\n\n  repeated int32 int32sNotPacked = 90 [packed = false];\n  repeated int64 int64sNotPacked = 91 [packed = false];\n  repeated uint32 uint32sNotPacked = 92 [packed = false];\n  repeated uint64 uint64sNotPacked = 93 [packed = false];\n  repeated sint32 sint32sNotPacked = 94 [packed = false];\n  repeated sint64 sint64sNotPacked = 95 [packed = false];\n  repeated fixed32 fixed32sNotPacked = 96 [packed = false];\n  repeated fixed64 fixed64sNotPacked = 97 [packed = false];\n  repeated sfixed32 sfixed32sNotPacked = 98 [packed = false];\n  repeated sfixed64 sfixed64sNotPacked = 99 [packed = false];\n  repeated float floatsNotPacked = 100 [packed = false];\n  repeated double doublesNotPacked = 101 [packed = false];\n  repeated bool boolsNotPacked = 102 [packed = false];\n  repeated Color colorsNotPacked = 103 [packed = false];\n\n  repeated string strings = 110;\n  repeated bytes bytess = 111;\n  repeated User users = 112;\n}\n\nenum Color {\n  RED = 0;\n  YELLOW = 1;\n  BLUE = 2;\n}\n\nmessage User {\n  string name = 1;\n\n  Root typeRecursive = 2;\n}\n"
  },
  {
    "path": "foundations/foundation-registry/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>foundations</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <properties>\n  </properties>\n\n  <artifactId>foundation-registry</artifactId>\n  <name>Java Chassis::Foundations::Registry</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.foundation.common.NamedThreadFactory;\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.LambdaUtils;\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.api.LifeCycle;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.discovery.InstancePing;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.HistoryStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.IsolationStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.PingStatus;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\npublic class DiscoveryManager implements LifeCycle {\n  public interface InstanceChangeListener {\n    void onInstancesChanged(String registryName, String application, String serviceName,\n        List<? extends DiscoveryInstance> instances);\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(DiscoveryManager.class);\n\n  private final ScheduledExecutorService task;\n\n  private final List<Discovery<? extends DiscoveryInstance>> discoveryList;\n\n  private final InstancePing ping;\n\n  private final HealthCheckTask healthCheckTask = new HealthCheckTask();\n\n  // application:serviceName:instanceId\n  private final Map<String, Map<String, Map<String, StatefulDiscoveryInstance>>>\n      allInstances = new ConcurrentHashMapEx<>();\n\n  // application:serviceName\n  private final Map<String, Map<String, VersionedCache>>\n      versionedCache = new ConcurrentHashMapEx<>();\n\n  private final Object cacheLock = new Object();\n\n  private final List<InstanceChangeListener> instanceChangeListeners = new ArrayList<>();\n\n  public DiscoveryManager(List<Discovery<? extends DiscoveryInstance>> discoveryList,\n      List<InstancePing> pings) {\n    this.discoveryList = discoveryList;\n    for (Discovery<? extends DiscoveryInstance> discovery : this.discoveryList) {\n      discovery.setInstanceChangedListener(this::onInstancesChanged);\n    }\n    this.ping = pings.get(0);\n    task = Executors.newScheduledThreadPool(1, new NamedThreadFactory(\"discovery-manager-task\"));\n  }\n\n  public Discovery<? extends DiscoveryInstance> getPrimaryDiscovery() {\n    return this.discoveryList.get(0);\n  }\n\n  private void onInstancesChanged(String application, String serviceName,\n      List<? extends DiscoveryInstance> instances) {\n    onInstancesChanged(null, application, serviceName, instances);\n  }\n\n  private void onInstancesChanged(String registryName, String application, String serviceName,\n      List<? extends DiscoveryInstance> instances) {\n    Map<String, StatefulDiscoveryInstance> statefulInstances = allInstances.computeIfAbsent(application, key ->\n        new ConcurrentHashMapEx<>()).computeIfAbsent(serviceName, key -> new ConcurrentHashMapEx<>());\n\n    for (StatefulDiscoveryInstance statefulInstance : statefulInstances.values()) {\n      if (registryName == null || registryName.equals(statefulInstance.getRegistryName())) {\n        if (!instances.contains(statefulInstance)) {\n          statefulInstance.setPingTime(0);\n          statefulInstance.setHistoryStatus(HistoryStatus.HISTORY);\n        }\n      }\n    }\n\n    for (DiscoveryInstance instance : instances) {\n      StatefulDiscoveryInstance target = new StatefulDiscoveryInstance(instance);\n      StatefulDiscoveryInstance origin = statefulInstances.get(instance.getInstanceId());\n      if (origin == null) {\n        statefulInstances.put(instance.getInstanceId(), target);\n        continue;\n      }\n      target.setPingTime(origin.getPingTime());\n      target.setPingStatus(origin.getPingStatus());\n      target.setIsolateDuration(origin.getIsolateDuration());\n      target.setIsolationStatus(origin.getIsolationStatus());\n      statefulInstances.put(instance.getInstanceId(), target);\n    }\n\n    StringBuilder instanceInfo = new StringBuilder();\n    for (DiscoveryInstance instance : instances) {\n      instanceInfo.append(\"{\")\n          .append(instance.getInstanceId()).append(\",\")\n          .append(instance.getStatus()).append(\",\")\n          .append(instance.getEndpoints()).append(\",\")\n          .append(instance.getRegistryName())\n          .append(\"}\");\n    }\n    LOGGER.info(\"Applying new instance list for {}/{}/{}. Endpoints {}\",\n        application, serviceName, instances.size(), instanceInfo);\n\n    rebuildVersionCache(application, serviceName);\n\n    for (InstanceChangeListener listener : this.instanceChangeListeners) {\n      listener.onInstancesChanged(registryName, application, serviceName, instances);\n    }\n  }\n\n  public void addInstanceChangeListener(InstanceChangeListener instanceChangeListener) {\n    this.instanceChangeListeners.add(instanceChangeListener);\n  }\n\n  public void onInstanceIsolated(DiscoveryInstance instance, long isolateDuration) {\n    Map<String, StatefulDiscoveryInstance> statefulInstances = allInstances.computeIfAbsent(\n        instance.getApplication(), key ->\n            new ConcurrentHashMapEx<>()).computeIfAbsent(instance.getServiceName(), key\n        -> new ConcurrentHashMapEx<>());\n    StatefulDiscoveryInstance target = statefulInstances.get(instance.getInstanceId());\n    if (target == null) {\n      return;\n    }\n\n    target.setIsolatedTime(System.currentTimeMillis());\n    target.setIsolateDuration(isolateDuration);\n\n    if (target.getIsolationStatus() != IsolationStatus.ISOLATED) {\n      target.setIsolationStatus(IsolationStatus.ISOLATED);\n      rebuildVersionCache(instance.getApplication(), instance.getServiceName());\n    }\n\n    LOGGER.warn(\"Isolated instance {}/{}/{}, time {}/{}\",\n        instance.getApplication(), instance.getServiceName(), instance.getInstanceId(),\n        target.getIsolatedTime(), target.getIsolateDuration());\n  }\n\n  private void rebuildVersionCache(String application, String serviceName) {\n    Map<String, VersionedCache> caches = versionedCache.computeIfAbsent(application, key ->\n        new ConcurrentHashMapEx<>());\n    caches.put(serviceName, calcAvailableInstance(application, serviceName));\n  }\n\n  private VersionedCache calcAvailableInstance(String application, String serviceName) {\n    Map<String, StatefulDiscoveryInstance> statefulInstances = allInstances.computeIfAbsent(\n        application, key ->\n            new ConcurrentHashMapEx<>()).computeIfAbsent(serviceName, key\n        -> new ConcurrentHashMapEx<>());\n    List<StatefulDiscoveryInstance> result = new ArrayList<>();\n    for (StatefulDiscoveryInstance instance : statefulInstances.values()) {\n      if (instance.getHistoryStatus() == HistoryStatus.CURRENT) {\n        result.add(instance);\n        continue;\n      }\n      if (instance.getHistoryStatus() == HistoryStatus.HISTORY\n          && instance.getStatus() == MicroserviceInstanceStatus.UP\n          && instance.getPingStatus() == PingStatus.OK\n          && instance.getIsolationStatus() == IsolationStatus.NORMAL) {\n        result.add(instance);\n      }\n    }\n    StringBuilder instanceInfo = new StringBuilder();\n    for (StatefulDiscoveryInstance instance : result) {\n      instanceInfo.append(\"{\")\n          .append(instance.getInstanceId()).append(\",\")\n          .append(instance.getHistoryStatus()).append(\",\")\n          .append(instance.getStatus()).append(\",\")\n          .append(instance.getPingStatus()).append(\",\")\n          .append(instance.getIsolationStatus()).append(\",\")\n          .append(instance.getEndpoints()).append(\",\")\n          .append(instance.getRegistryName())\n          .append(\"}\");\n    }\n    LOGGER.info(\"Rebuild cached instance list for {}/{}/{}. Endpoints {}\",\n        application, serviceName, result.size(), instanceInfo);\n    return new VersionedCache()\n        .name(application + \":\" + serviceName)\n        .autoCacheVersion()\n        .data(result);\n  }\n\n  public VersionedCache getOrCreateVersionedCache(String application, String serviceName) {\n    Map<String, VersionedCache> caches = versionedCache.computeIfAbsent(application, key ->\n        new ConcurrentHashMapEx<>());\n    VersionedCache cache = caches.get(serviceName);\n    if (cache == null) {\n      synchronized (cacheLock) {\n        cache = caches.get(serviceName);\n        if (cache != null) {\n          return cache;\n        }\n        List<? extends DiscoveryInstance> instances = findServiceInstances(application, serviceName);\n        onInstancesChanged(application, serviceName, instances);\n        return versionedCache.get(application).get(serviceName);\n      }\n    }\n    return cache;\n  }\n\n  public List<? extends DiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    List<DiscoveryInstance> result = new ArrayList<>();\n    for (Discovery<? extends DiscoveryInstance> discovery : discoveryList) {\n      if (!discovery.enabled() || !discovery.enabled(application, serviceName)) {\n        continue;\n      }\n      List<? extends DiscoveryInstance> temp = discovery.findServiceInstances(application, serviceName);\n      if (CollectionUtils.isEmpty(temp)) {\n        continue;\n      }\n      result.addAll(temp);\n    }\n    return result;\n  }\n\n  @Override\n  public void destroy() {\n    discoveryList.forEach(LambdaUtils.ignoreException(LifeCycle::destroy));\n    task.shutdownNow();\n  }\n\n  @Override\n  public void run() {\n    discoveryList.forEach(LifeCycle::run);\n    task.schedule(healthCheckTask, 3, TimeUnit.SECONDS);\n  }\n\n  @Override\n  public void init() {\n    discoveryList.forEach(LifeCycle::init);\n  }\n\n  public String info() {\n    StringBuilder result = new StringBuilder();\n    AtomicBoolean first = new AtomicBoolean(true);\n    discoveryList.forEach(discovery -> {\n      if (first.getAndSet(false)) {\n        result.append(\"Discovery implementations:\\n\");\n      }\n      result.append(\"  name:\").append(discovery.name()).append(\"\\n\");\n    });\n    return result.toString();\n  }\n\n  class HealthCheckTask implements Runnable {\n\n    @Override\n    public void run() {\n      try {\n        Map<String, Map<String, List<String>>> removed = new HashMap<>();\n        for (Entry<String, Map<String, Map<String, StatefulDiscoveryInstance>>> apps : DiscoveryManager.this.allInstances.entrySet()) {\n          for (Entry<String, Map<String, StatefulDiscoveryInstance>> services : apps.getValue().entrySet()) {\n            boolean changed = false;\n            for (StatefulDiscoveryInstance instance : services.getValue().values()) {\n              // check isolated time\n              if (instance.getIsolationStatus() == IsolationStatus.ISOLATED &&\n                  instance.getIsolatedTime() + instance.getIsolateDuration() < System.currentTimeMillis()) {\n                instance.setIsolationStatus(IsolationStatus.NORMAL);\n                changed = true;\n              }\n              // check ping status\n              if (System.currentTimeMillis() - instance.getPingTime() > 60_000L) {\n                boolean pingResult = DiscoveryManager.this.ping.ping(instance);\n                if (pingResult && instance.getPingStatus() != PingStatus.OK) {\n                  instance.setPingStatus(PingStatus.OK);\n                  changed = true;\n                } else if (!pingResult && instance.getPingStatus() != PingStatus.FAIL) {\n                  instance.setPingStatus(PingStatus.FAIL);\n                  changed = true;\n                }\n                instance.setPingTime(System.currentTimeMillis());\n              }\n              // check unused\n              if (instance.getHistoryStatus() == HistoryStatus.HISTORY) {\n                if (instance.getStatus() != MicroserviceInstanceStatus.UP ||\n                    instance.getPingStatus() == PingStatus.FAIL ||\n                    instance.getIsolationStatus() == IsolationStatus.ISOLATED) {\n                  removed.computeIfAbsent(apps.getKey(), k -> new HashMap<>())\n                      .computeIfAbsent(services.getKey(), k -> new ArrayList<>()).add(instance.getInstanceId());\n                  LOGGER.info(\"Remove instance {}/{}/{}/{}/{}/{}/{}/{}\",\n                      apps.getKey(), services.getKey(), instance.getRegistryName(),\n                      instance.getInstanceId(), instance.getHistoryStatus(),\n                      instance.getStatus(), instance.getPingStatus(), instance.getIsolationStatus());\n                  changed = true;\n                }\n              }\n            }\n            if (changed) {\n              rebuildVersionCache(apps.getKey(), services.getKey());\n            }\n          }\n        }\n        // remove unused\n        for (Entry<String, Map<String, List<String>>> apps : removed.entrySet()) {\n          for (Entry<String, List<String>> services : apps.getValue().entrySet()) {\n            for (String instance : services.getValue()) {\n              DiscoveryManager.this.allInstances.get(apps.getKey()).get(services.getKey()).remove(instance);\n            }\n          }\n        }\n      } catch (Throwable e) {\n        LOGGER.error(\"discovery manager task error. \", e);\n      } finally {\n        DiscoveryManager.this.task.schedule(this, 3, TimeUnit.SECONDS);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistrationId.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry;\n\nimport java.util.UUID;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class RegistrationId {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationId.class);\n\n  private final String instanceId;\n\n  public RegistrationId() {\n    this.instanceId = buildInstanceId();\n    LOGGER.info(\"initialized global registration id {}\", this.instanceId);\n  }\n\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  private static String buildInstanceId() {\n    return UUID.randomUUID().toString();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistrationManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.foundation.common.utils.LambdaUtils;\nimport org.apache.servicecomb.foundation.common.utils.SPIEnabled;\nimport org.apache.servicecomb.registry.api.LifeCycle;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\nimport org.springframework.util.CollectionUtils;\n\nimport io.vertx.core.json.jackson.JacksonFactory;\n\npublic class RegistrationManager {\n  private final List<Registration<? extends RegistrationInstance>> registrationList;\n\n  public RegistrationManager(List<Registration<? extends RegistrationInstance>> registrationList) {\n    if (registrationList == null) {\n      this.registrationList = Collections.emptyList();\n      return;\n    }\n    this.registrationList = registrationList.stream().filter(SPIEnabled::enabled).collect(Collectors.toList());\n  }\n\n  /**\n   * For internal use. Get instance id from registry name. If not exists, return empty.\n   */\n  public String getInstanceId(String registryName) {\n    if (CollectionUtils.isEmpty(registrationList)) {\n      return \"\";\n    }\n    Optional<Registration<? extends RegistrationInstance>> registration =\n        registrationList.stream().filter(r -> registryName.equals(r.name())).collect(Collectors.toList())\n            .stream().findFirst();\n    if (!registration.isPresent()) {\n      return \"\";\n    }\n    return registration.get().getMicroserviceInstance().getInstanceId();\n  }\n\n  /**\n   * For internal use.  Get service id from registry name. If not exists, return empty.\n   */\n  public String getServiceId(String registryName) {\n    if (CollectionUtils.isEmpty(registrationList)) {\n      return \"\";\n    }\n    Optional<Registration<? extends RegistrationInstance>> registration =\n        registrationList.stream().filter(r -> registryName.equals(r.name())).collect(Collectors.toList())\n            .stream().findFirst();\n    if (!registration.isPresent()) {\n      return \"\";\n    }\n    return registration.get().getMicroserviceInstance().getServiceId();\n  }\n\n  public Registration<? extends RegistrationInstance> getPrimaryRegistration() {\n    return registrationList.get(0);\n  }\n\n  public void updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    registrationList\n        .forEach(registration -> registration.updateMicroserviceInstanceStatus(status));\n  }\n\n  public void addProperty(String key, String value) {\n    registrationList\n        .forEach(registration -> registration.addProperty(key, value));\n  }\n\n  public void addSchema(String schemaId, String content) {\n    registrationList\n        .forEach(registration -> registration.addSchema(schemaId, content));\n  }\n\n  public void addEndpoint(String endpoint) {\n    registrationList\n        .forEach(registration -> registration.addEndpoint(endpoint));\n  }\n\n  public void destroy() {\n    registrationList.forEach(LambdaUtils.ignoreException(LifeCycle::destroy));\n  }\n\n  public void run() {\n    registrationList.forEach(LifeCycle::run);\n  }\n\n  public void init() {\n    registrationList.forEach(LifeCycle::init);\n  }\n\n  public String info() {\n    StringBuilder result = new StringBuilder();\n    AtomicBoolean first = new AtomicBoolean(true);\n    registrationList.forEach(registration -> {\n      if (first.getAndSet(false)) {\n        result.append(\"App ID: \").append(registration.getMicroserviceInstance().getApplication()).append(\"\\n\");\n        result.append(\"Service Name: \").append(registration.getMicroserviceInstance().getServiceName()).append(\"\\n\");\n        result.append(\"Version: \").append(registration.getMicroserviceInstance().getVersion()).append(\"\\n\");\n        result.append(\"Environment: \").append(registration.getMicroserviceInstance().getEnvironment()).append(\"\\n\");\n        result.append(\"Endpoints: \").append(getEndpoints(registration.getMicroserviceInstance().getEndpoints()))\n            .append(\"\\n\");\n        result.append(\"Registration implementations:\\n\");\n      }\n\n      result.append(\"  name:\").append(registration.name()).append(\"\\n\");\n      result.append(\"    Instance ID: \").append(registration.getMicroserviceInstance().getInstanceId()).append(\"\\n\");\n    });\n    return result.toString();\n  }\n\n  private String getEndpoints(List<String> endpoints) {\n    return JacksonFactory.CODEC.toString(endpoints);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistryConfiguration.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry;\r\n\r\nimport java.util.List;\r\n\r\nimport org.apache.servicecomb.registry.api.Discovery;\r\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\r\nimport org.apache.servicecomb.registry.api.Registration;\r\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\r\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\r\nimport org.apache.servicecomb.registry.discovery.InstancePing;\r\nimport org.apache.servicecomb.registry.discovery.InstanceStatusDiscoveryFilter;\r\nimport org.apache.servicecomb.registry.discovery.MicroserviceInstanceCache;\r\nimport org.apache.servicecomb.registry.discovery.TelnetInstancePing;\r\nimport org.springframework.context.annotation.Bean;\r\nimport org.springframework.context.annotation.Configuration;\r\n\r\n@Configuration\r\n@SuppressWarnings(\"unused\")\r\npublic class RegistryConfiguration {\r\n  @Bean\r\n  public RegistrationManager scbRegistrationManager(\r\n      List<Registration<? extends RegistrationInstance>> registrationList) {\r\n    return new RegistrationManager(registrationList);\r\n  }\r\n\r\n  @Bean\r\n  public TelnetInstancePing scbTelnetInstancePing() {\r\n    return new TelnetInstancePing();\r\n  }\r\n\r\n  @Bean\r\n  public DiscoveryManager scbDiscoveryManager(\r\n      List<Discovery<? extends DiscoveryInstance>> discoveryList,\r\n      List<InstancePing> pingList) {\r\n    return new DiscoveryManager(discoveryList, pingList);\r\n  }\r\n\r\n  @Bean\r\n  public DiscoveryTree scbDiscoveryTree(DiscoveryManager discoveryManager) {\r\n    return new DiscoveryTree(discoveryManager);\r\n  }\r\n\r\n  @Bean\r\n  public InstanceStatusDiscoveryFilter scbInstanceStatusDiscoveryFilter() {\r\n    return new InstanceStatusDiscoveryFilter();\r\n  }\r\n\r\n  @Bean\r\n  public MicroserviceInstanceCache scbMicroserviceInstanceCache(DiscoveryManager discoveryManager) {\r\n    return new MicroserviceInstanceCache(discoveryManager);\r\n  }\r\n\r\n  @Bean\r\n  public RegistrationId scbRegistrationId() {\r\n    return new RegistrationId();\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/AbstractDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.api;\n\npublic abstract class AbstractDiscoveryInstance implements DiscoveryInstance {\n  @Override\n  public int hashCode() {\n    return getInstanceId().hashCode();\n  }\n\n  @Override\n  public boolean equals(Object obj) {\n    if (obj instanceof DiscoveryInstance) {\n      return getInstanceId().equals(((DiscoveryInstance) obj).getInstanceId());\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/DataCenterInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\npublic class DataCenterInfo {\n  private String name;\n\n  private String region;\n\n  private String availableZone;\n\n  public DataCenterInfo() {\n\n  }\n\n  public DataCenterInfo(String name, String region, String availableZone) {\n    this.name = name;\n    this.region = region;\n    this.availableZone = availableZone;\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getRegion() {\n    return region;\n  }\n\n  public void setRegion(String region) {\n    this.region = region;\n  }\n\n  public String getAvailableZone() {\n    return availableZone;\n  }\n\n  public void setAvailableZone(String availableZone) {\n    this.availableZone = availableZone;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/Discovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIEnabled;\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\n/**\n * This is the core service discovery interface. <br/>\n */\npublic interface Discovery<D extends DiscoveryInstance> extends SPIEnabled, SPIOrder, LifeCycle {\n  interface InstanceChangedListener<D extends DiscoveryInstance> {\n    /**\n     * Called by Discovery Implementations when instance list changed.\n     * @param registryName Name of the calling discovery implementation\n     * @param application Microservice application\n     * @param serviceName Microservice name\n     * @param updatedInstances The latest updated instances.\n     */\n    void onInstanceChanged(String registryName, String application, String serviceName, List<D> updatedInstances);\n  }\n\n  String name();\n\n  /**\n   * If this implementation enabled for this microservice.\n   */\n  boolean enabled(String application, String serviceName);\n\n  /**\n   * Find all instances.\n   *\n   * Life Cycle：This method is called anytime after <code>run</code>.\n   *\n   * @param application application\n   * @param serviceName microservice name\n   * @return all instances match the criteria.\n   */\n  List<D> findServiceInstances(String application, String serviceName);\n\n  /**\n   * Find all services of this application.\n   *\n   * @param application application\n   * @return all services match the criteria.\n   */\n  List<String> findServices(String application);\n\n  /**\n   * Discovery can call InstanceChangedListener when instance get changed.\n   */\n  void setInstanceChangedListener(InstanceChangedListener<D> instanceChangedListener);\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/DiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.api;\n\n/**\n * Microserivce instance discovery object.\n */\npublic interface DiscoveryInstance extends MicroserviceInstance {\n  /**\n   * Microservice instance status.\n   */\n  MicroserviceInstanceStatus getStatus();\n\n  /**\n   * This name of Discovery Implementation.\n   */\n  String getRegistryName();\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/LifeCycle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\npublic interface LifeCycle {\n  void init();\n\n  void run();\n\n  void destroy();\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.api;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Standard information used for microservice instance registration and discovery.\n */\npublic interface MicroserviceInstance {\n  /**\n   * Environment(Required): Used for logic separation of microservice instance. Only\n   * microservice instance with same environment can discovery each other.\n   */\n  String getEnvironment();\n\n  /**\n   * Application(Required): Used for logic separation of microservice instance. Only\n   * microservice instance with same application can discovery each other.\n   */\n  String getApplication();\n\n  /**\n   * Service Name(Required): Unique identifier for microservice.\n   */\n  String getServiceName();\n\n  /**\n   * Service Name Alias(Optional): Unique identifier for microservice.\n   *   This alias is used by registry implementation to support rename\n   *   of a microservice, e.g. old consumers use old service name can\n   *   find a renamed microservice service.\n   */\n  String getAlias();\n\n  /**\n   * Service Version(Required): version of this microservice.\n   */\n  String getVersion();\n\n  /**\n   * Data center info(Optional).\n   */\n  DataCenterInfo getDataCenterInfo();\n\n  /**\n   * Service Description(Optional)\n   */\n  String getDescription();\n\n  /**\n   * Service Properties(Optional)\n   */\n  Map<String, String> getProperties();\n\n  /**\n   * Service Schemas(Optional): Open API information.\n   */\n  Map<String, String> getSchemas();\n\n  /**\n   * Service endpoints(Optional).\n   */\n  List<String> getEndpoints();\n\n  /**\n   * Microservice instance id(Required). This id can be generated when microservice instance is starting\n   * or assigned by registry implementation.\n   *\n   * When microservice instance is restarted, this id should be changed.\n   */\n  String getInstanceId();\n\n  /**\n   * Microservice service id(Optional). This is used for service center, other implementations may not\n   * support service id.\n   */\n  default String getServiceId() {\n    return \"\";\n  }\n\n  /**\n   * Service status(Required): status of this microservice.\n   *\n   */\n  MicroserviceInstanceStatus getStatus();\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceInstanceStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\npublic enum MicroserviceInstanceStatus {\n  STARTING,\n  TESTING,\n  UP,\n  DOWN,\n  UNKNOWN\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceKey.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n/**\n * Created by   on 2017/1/9.\n */\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class MicroserviceKey {\n  private String tenant;\n\n  private String appId;\n\n  private String serviceName;\n\n  private String version;\n\n  private String stage;\n\n  public String getTenant() {\n    return tenant;\n  }\n\n  public void setTenant(String tenant) {\n    this.tenant = tenant;\n  }\n\n  public String getAppId() {\n    return appId;\n  }\n\n  public void setAppId(String appId) {\n    this.appId = appId;\n  }\n\n  public String getServiceName() {\n    return serviceName;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public String getStage() {\n    return stage;\n  }\n\n  public void setStage(String stage) {\n    this.stage = stage;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/PropertyExtended.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\nimport java.util.Map;\n\npublic interface PropertyExtended {\n  Map<String, String> getExtendedProperties();\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/Registration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.api;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIEnabled;\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\n\n/**\n * This is the core service registration interface.\n */\npublic interface Registration<R extends RegistrationInstance> extends SPIEnabled, SPIOrder, LifeCycle {\n  String name();\n\n  /**\n   * get MicroserviceInstance\n   * <p>\n   * Life Cycle：This method is called anytime after <code>run</code>.\n   */\n  R getMicroserviceInstance();\n\n  /**\n   * update MicroserviceInstance status\n   * <p>\n   * Life Cycle：This method is called anytime after <code>run</code>.\n   */\n  boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status);\n\n  /**\n   * adding schemas to Microservice\n   * <p>\n   * Life Cycle：This method is called after <code>init</code> and before <code>run</code>.\n   */\n  void addSchema(String schemaId, String content);\n\n  /**\n   * adding endpoints to MicroserviceInstance\n   * <p>\n   * Life Cycle：This method is called after <code>init</code> and before <code>run</code>.\n   */\n  void addEndpoint(String endpoint);\n\n  /**\n   * adding property to MicroserviceInstance\n   * <p>\n   * Life Cycle：This method is called after <code>init</code> and before <code>run</code>.\n   */\n  void addProperty(String key, String value);\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/RegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.api;\n\n/**\n * Microserivce instance registration object.\n */\npublic interface RegistrationInstance extends MicroserviceInstance {\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/definition/DefinitionConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.definition;\n\npublic interface DefinitionConst {\n  // Whether to allow cross-app calls to me\n  String CONFIG_ALLOW_CROSS_APP_KEY = \"allowCrossApp\";\n\n  String DEFAULT_STAGE = \"prod\";\n\n  String VERSION_RULE_LATEST = \"latest\";\n\n  String VERSION_RULE_ALL = \"0.0.0.0+\";\n\n  String APP_SERVICE_SEPARATOR = \":\";\n\n  String URL_PREFIX = \"urlPrefix\";\n\n  String INSTANCE_PUBKEY_PRO = \"publickey\";\n\n  String REGISTER_URL_PREFIX = \"servicecomb.registry.registerUrlPrefix\";\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/definition/MicroserviceNameParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.definition;\n\n/**\n * Parse application and microservice from join name.\n *\n * 1. microserviceName\n * 2. application:microserviceName\n */\npublic class MicroserviceNameParser {\n  private String appId;\n\n  private String microserviceName;\n\n  public MicroserviceNameParser(String defaultAppId, String microserviceName) {\n    parseMicroserviceName(defaultAppId, microserviceName);\n  }\n\n  private void parseMicroserviceName(String defaultAppId, String microserviceName) {\n    int idxAt = microserviceName.indexOf(DefinitionConst.APP_SERVICE_SEPARATOR);\n    if (idxAt == -1) {\n      this.appId = defaultAppId;\n      this.microserviceName = microserviceName;\n      return;\n    }\n\n    this.appId = microserviceName.substring(0, idxAt);\n    this.microserviceName = microserviceName.substring(idxAt + 1);\n  }\n\n  public String getAppId() {\n    return appId;\n  }\n\n  public String getMicroserviceName() {\n    return microserviceName;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.ArrayList;\n\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic abstract class AbstractDiscoveryFilter implements DiscoveryFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDiscoveryFilter.class);\n\n  protected Boolean enabled;\n\n  protected DynamicProperties dynamicProperties;\n\n  @Autowired\n  public void setDynamicProperties(DynamicProperties dynamicProperties) {\n    this.dynamicProperties = dynamicProperties;\n  }\n\n  @Override\n  public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n    if (!parent.childrenInited()) {\n      synchronized (parent) {\n        if (!parent.childrenInited()) {\n          init(context, parent);\n          parent.childrenInited(true);\n        }\n      }\n    }\n\n    String childName = findChildName(context, parent);\n    DiscoveryTreeNode node = parent.child(childName);\n    if (node == null) {\n      LOGGER.warn(\"discovery filter {}/{} return null.\", this.getClass().getSimpleName(), childName);\n      return new DiscoveryTreeNode().subName(parent, \"empty\").data(new ArrayList<>());\n    }\n    return node;\n  }\n\n  protected abstract void init(DiscoveryContext context, DiscoveryTreeNode parent);\n\n  protected abstract String findChildName(DiscoveryContext context, DiscoveryTreeNode parent);\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractEndpointDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic abstract class AbstractEndpointDiscoveryFilter implements DiscoveryFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractEndpointDiscoveryFilter.class);\n\n  private static final String ALL_TRANSPORT = \"\";\n\n  private static final String WEBSOCKET_TRANSPORT = \"websocket\";\n\n  private static final String REST_TRANSPORT = \"rest\";\n\n  @Override\n  public boolean isGroupingFilter() {\n    return true;\n  }\n\n  @Override\n  public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n    String expectTransportName = findTransportName(context, parent);\n    return parent.children()\n        .computeIfAbsent(expectTransportName, etn -> createDiscoveryTreeNode(expectTransportName, context, parent));\n  }\n\n  protected DiscoveryTreeNode createDiscoveryTreeNode(String expectTransportName, DiscoveryContext context,\n      DiscoveryTreeNode parent) {\n    List<Object> endpoints = new ArrayList<>();\n    List<StatefulDiscoveryInstance> instances = parent.data();\n    for (StatefulDiscoveryInstance instance : instances) {\n      for (String endpoint : instance.getEndpoints()) {\n        try {\n          URIEndpointObject endpointObject = new URIEndpointObject(endpoint);\n          String transPortName = endpointObject.getSchema();\n          if (endpointObject.isWebsocketEnabled() && WEBSOCKET_TRANSPORT.equals(expectTransportName)) {\n            transPortName = WEBSOCKET_TRANSPORT;\n          }\n          if (!isTransportNameMatch(transPortName, expectTransportName)) {\n            continue;\n          }\n\n          Object objEndpoint = createEndpoint(context, transPortName, endpoint, instance);\n          if (objEndpoint == null) {\n            continue;\n          }\n\n          endpoints.add(objEndpoint);\n        } catch (Exception e) {\n          LOGGER.warn(\"unrecognized address find, ignore {}.\", endpoint);\n        }\n      }\n    }\n\n    return new DiscoveryTreeNode()\n        .subName(parent, expectTransportName)\n        .data(endpoints);\n  }\n\n  protected boolean isTransportNameMatch(String transportName, String expectTransportName) {\n    if (ALL_TRANSPORT.equals(expectTransportName)) {\n      return true;\n    }\n    return transportName.equals(expectTransportName);\n  }\n\n  protected abstract String findTransportName(DiscoveryContext context, DiscoveryTreeNode parent);\n\n  protected abstract Object createEndpoint(DiscoveryContext context, String transportName, String endpoint,\n      StatefulDiscoveryInstance instance);\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractGroupDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\npublic abstract class AbstractGroupDiscoveryFilter extends AbstractDiscoveryFilter {\n  @Override\n  public boolean isGroupingFilter() {\n    return true;\n  }\n\n  protected abstract String groupsSizeParameter();\n\n  protected abstract String contextParameter();\n\n  protected abstract String groupPrefix();\n\n  @Override\n  protected String findChildName(DiscoveryContext context, DiscoveryTreeNode parent) {\n    Integer level = context.getContextParameter(contextParameter());\n    Integer groups = parent.attribute(groupsSizeParameter());\n\n    String group;\n    if (level == null) {\n      group = groupPrefix() + 1;\n      if (groups > 1) {\n        context.pushRerunFilter();\n        context.putContextParameter(contextParameter(), 1);\n      }\n      return group;\n    }\n\n    level = level + 1;\n    group = groupPrefix() + level;\n\n    if (level < groups) {\n      context.pushRerunFilter();\n      context.putContextParameter(contextParameter(), level);\n    }\n    return group;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Stack;\n\npublic class DiscoveryContext {\n  private Object inputParameters;\n\n  private final Map<String, Object> contextParameters = new HashMap<>();\n\n  // some filter support rerun logic, eg:ZoneAware\n  // instances grouping to self zone, other zone, and so on\n  // first try self zone, after other filter(Isolation Filter), no instances are available\n  // then try other zone\n  private final Stack<DiscoveryTreeNode> rerunStack = new Stack<>();\n\n  private DiscoveryTreeNode currentNode;\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getInputParameters() {\n    return (T) inputParameters;\n  }\n\n  public void setInputParameters(Object inputParameters) {\n    this.inputParameters = inputParameters;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getContextParameter(String name) {\n    return (T) contextParameters.get(name);\n  }\n\n  public void putContextParameter(String name, Object value) {\n    contextParameters.put(name, value);\n  }\n\n  public void setCurrentNode(DiscoveryTreeNode node) {\n    this.currentNode = node;\n  }\n\n  public void pushRerunFilter() {\n    rerunStack.push(currentNode);\n  }\n\n  public DiscoveryTreeNode popRerunFilter() {\n    if (rerunStack.isEmpty()) {\n      return null;\n    }\n\n    return rerunStack.pop();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport org.springframework.core.Ordered;\n\n/**\n * Server list filters for DiscoveryTree.\n *\n * Implementation Notice: DiscoveryFilter is initialized using bean and instance shared for all\n * microservices. If implementation has states, can put the states to DiscoveryContext or parent DiscoveryTreeNode.\n */\npublic interface DiscoveryFilter extends Ordered {\n  default boolean enabled() {\n    return true;\n  }\n\n  /**\n   * grouping filter, means grouping instances to some groups\n   *  eg: operation/ZoneAware/transport\n   */\n  default boolean isGroupingFilter() {\n    return false;\n  }\n\n  DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent);\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryTree.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\n/**\n * <pre>\n * DiscoveryTree is used to:\n * 1.get all instances by app/microserviceName\n * 2.filter all instances set, and output another set, the output set is instance or something else, this depend on filter set\n *\n * DiscoveryFilter have different types:\n * 1.normal filter: just filter input set\n * 2.grouping filter: will split input set to groups\n * 3.convert filter: eg: convert from instance to endpoint\n * different types can composite in one filter\n *\n * features:\n * 1.if some filter output set is empty, DiscoveryTree can support try refilter logic\n *   eg: if there is no available instances in self AZ, can refilter in other AZ\n * 2.every filter must try to cache result, avoid calculate every time.\n *\n * usage:\n * 1.declare a field: DiscoveryTree discoveryTree = new DiscoveryTree();\n * 2.initialize:\n *     discoveryTree.loadFromSPI(DiscoveryFilter.class);\n *     // add filters by your requirement\n *     discoveryTree.addFilter(new EndpointDiscoveryFilter());\n *     discoveryTree.sort();\n * 3.filter for a invocation:\n *     DiscoveryContext context = new DiscoveryContext();\n *     context.setInputParameters(invocation);\n *     VersionedCache endpointsVersionedCache = discoveryTree.discovery(context,\n *         invocation.getAppId(),\n *         invocation.getMicroserviceName(),\n *         invocation.getMicroserviceVersionRule());\n *     if (endpointsVersionedCache.isEmpty()) {\n *       // 404 not found logic\n *       ......\n *       return;\n *     }\n *\n *     // result is endpoints or something else, which is depends on your filter set\n *     List&lt;Endpoint&gt; endpoints = endpointsVersionedCache.data();\n *</pre>\n */\npublic class DiscoveryTree {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DiscoveryTree.class);\n\n  private final Map<String, Map<String, DiscoveryTreeNode>> root = new ConcurrentHashMapEx<>();\n\n  private final Object lock = new Object();\n\n  private List<DiscoveryFilter> filters = Collections.emptyList();\n\n  private final DiscoveryManager discoveryManager;\n\n  public DiscoveryTree(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Autowired\n  public void setDiscoveryFilters(List<DiscoveryFilter> filters) {\n    this.filters = filters;\n    log();\n  }\n\n  private void log() {\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"DiscoveryFilters(name, enabled, order, group):\");\n    for (DiscoveryFilter filter : filters) {\n      sb.append(\"(\").append(filter.getClass().getName()).append(\",\")\n          .append(filter.enabled()).append(\",\").append(filter.getOrder()).append(\",\")\n          .append(filter.isGroupingFilter()).append(\")\");\n    }\n    LOGGER.info(sb.toString());\n  }\n\n  boolean isMatch(VersionedCache existing, VersionedCache inputCache) {\n    return existing != null && existing.isSameVersion(inputCache);\n  }\n\n  boolean isExpired(VersionedCache existing, VersionedCache inputCache) {\n    return existing == null || existing.isExpired(inputCache);\n  }\n\n  public DiscoveryTreeNode discovery(DiscoveryContext context, String appId, String microserviceName) {\n    VersionedCache instanceVersionedCache = this.discoveryManager.getOrCreateVersionedCache(appId, microserviceName);\n\n    return discovery(appId, microserviceName, context, instanceVersionedCache);\n  }\n\n  DiscoveryTreeNode discovery(String appId, String microserviceName, DiscoveryContext context,\n      VersionedCache inputCache) {\n    DiscoveryTreeNode tmpRoot = getOrCreateRoot(appId, microserviceName, inputCache);\n    DiscoveryTreeNode parent = tmpRoot.children()\n        .computeIfAbsent(inputCache.name(), name -> new DiscoveryTreeNode().fromCache(inputCache));\n    return doDiscovery(context, parent);\n  }\n\n  protected DiscoveryTreeNode getOrCreateRoot(String appId, String microserviceName, VersionedCache inputCache) {\n    DiscoveryTreeNode tmpRoot = root.computeIfAbsent(appId, k -> new ConcurrentHashMapEx<>()).get(microserviceName);\n    if (isMatch(tmpRoot, inputCache)) {\n      return tmpRoot;\n    }\n\n    synchronized (lock) {\n      if (isExpired(tmpRoot, inputCache)) {\n        // not initialized or inputCache newer than root, create new root\n        tmpRoot = new DiscoveryTreeNode().cacheVersion(inputCache.cacheVersion());\n        root.get(appId).put(microserviceName, tmpRoot);\n        return tmpRoot;\n      }\n\n      if (tmpRoot.isSameVersion(inputCache)) {\n        // reuse root directly\n        return tmpRoot;\n      }\n    }\n\n    // root newer than inputCache, it's a minimal probability event:\n    // 1) thread 1, use v1 inputCache, run into getOrCreateRoot, but did not run any code yet, suspend and switch to thread 2\n    // 2) thread 2, use v2 inputCache, v2 > v1, create new root\n    // 3) thread 1 go on, then root is newer than inputCache\n    //    but if create old children in new version root, it's a wrong logic\n    // so just create a temporary root for the inputCache, DO NOT assign to root\n    tmpRoot = new DiscoveryTreeNode().cacheVersion(inputCache.cacheVersion());\n    root.get(appId).put(microserviceName, tmpRoot);\n    return tmpRoot;\n  }\n\n  protected DiscoveryTreeNode doDiscovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n    for (int idx = 0; idx < filters.size(); ) {\n      DiscoveryFilter filter = filters.get(idx);\n      if (!filter.enabled()) {\n        idx++;\n        continue;\n      }\n      context.setCurrentNode(parent);\n\n      DiscoveryTreeNode child = filter.discovery(context, parent);\n      if (child == null) {\n        // impossible, throw exception to help fix bug\n        throw new ServiceCombException(filter.getClass().getName() + \" discovery return null.\");\n      }\n\n      child.level(idx + 1);\n      if (!filter.isGroupingFilter()) {\n        child.name(parent.name());\n      }\n\n      if (child.isEmpty()) {\n        // maybe need to rerun some filter\n        DiscoveryTreeNode rerunNode = context.popRerunFilter();\n        if (rerunNode != null) {\n          parent = rerunNode;\n          idx = parent.level();\n          continue;\n        }\n\n        // no rerun support, go on even result is empty\n        // because maybe some filter use other mechanism to create an instance(eg:domain name)\n      }\n\n      parent = child;\n      idx++;\n    }\n\n    return parent;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryTreeNode.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\npublic class DiscoveryTreeNode extends VersionedCache {\n  private volatile boolean childrenInited;\n\n  private volatile int level;\n\n  protected Map<String, Object> attributes = new ConcurrentHashMapEx<>();\n\n  protected Map<String, DiscoveryTreeNode> children = new ConcurrentHashMapEx<>();\n\n  public boolean childrenInited() {\n    return childrenInited;\n  }\n\n  public DiscoveryTreeNode childrenInited(boolean childrenInited) {\n    this.childrenInited = childrenInited;\n    return this;\n  }\n\n  public int level() {\n    return level;\n  }\n\n  public DiscoveryTreeNode level(int level) {\n    this.level = level;\n    return this;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T attribute(String key) {\n    return (T) attributes.get(key);\n  }\n\n  public DiscoveryTreeNode attribute(String key, Object value) {\n    attributes.put(key, value);\n    return this;\n  }\n\n  public Map<String, DiscoveryTreeNode> children() {\n    return children;\n  }\n\n  public DiscoveryTreeNode children(Map<String, DiscoveryTreeNode> children) {\n    this.children = children;\n    return this;\n  }\n\n  public DiscoveryTreeNode child(String childName) {\n    return children.get(childName);\n  }\n\n  public DiscoveryTreeNode child(String childName, DiscoveryTreeNode child) {\n    children.put(childName, child);\n    return this;\n  }\n\n  public DiscoveryTreeNode fromCache(VersionedCache other) {\n    this.cacheVersion = other.cacheVersion();\n    this.name = other.name();\n    this.data(other.data());\n    return this;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/InstancePing.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.discovery;\n\nimport org.springframework.core.Ordered;\n\npublic interface InstancePing extends Ordered {\n  boolean ping(StatefulDiscoveryInstance instance);\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/InstanceStatusDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.HistoryStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.IsolationStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.PingStatus;\n\npublic class InstanceStatusDiscoveryFilter extends AbstractGroupDiscoveryFilter {\n  public static final String PARAMETER = \"status_level\";\n\n  public static final String GROUP_PREFIX = \"status_group_\";\n\n  public static final String GROUP_SIZE = \"status_group_size\";\n\n  public static final String SERVICECOMB_LOADBALANCE_FILTER_STATUS_ENABLED = \"servicecomb.loadbalance.filter.status.enabled\";\n\n  @Override\n  public int getOrder() {\n    return -10000;\n  }\n\n  @Override\n  public boolean enabled() {\n\n    if (enabled == null) {\n      enabled = dynamicProperties.getBooleanProperty(SERVICECOMB_LOADBALANCE_FILTER_STATUS_ENABLED,\n          value -> enabled = value,\n          true);\n    }\n    return enabled;\n  }\n\n  @Override\n  protected String groupsSizeParameter() {\n    return GROUP_SIZE;\n  }\n\n  @Override\n  protected String contextParameter() {\n    return PARAMETER;\n  }\n\n  @Override\n  protected String groupPrefix() {\n    return GROUP_PREFIX;\n  }\n\n  @Override\n  public void init(DiscoveryContext context, DiscoveryTreeNode parent) {\n    List<StatefulDiscoveryInstance> instances = parent.data();\n    List<StatefulDiscoveryInstance> level0 = new ArrayList<>();\n    List<StatefulDiscoveryInstance> level1 = new ArrayList<>();\n    List<StatefulDiscoveryInstance> level2 = new ArrayList<>();\n    List<StatefulDiscoveryInstance> level3 = new ArrayList<>();\n\n    int groups = 1;\n\n    for (StatefulDiscoveryInstance instance : instances) {\n      if (HistoryStatus.CURRENT == instance.getHistoryStatus() &&\n          MicroserviceInstanceStatus.UP == instance.getStatus() &&\n          PingStatus.OK == instance.getPingStatus() &&\n          IsolationStatus.NORMAL == instance.getIsolationStatus()) {\n        level0.add(instance);\n        continue;\n      }\n      if (HistoryStatus.CURRENT == instance.getHistoryStatus() &&\n          MicroserviceInstanceStatus.UP == instance.getStatus() &&\n          PingStatus.UNKNOWN == instance.getPingStatus() &&\n          IsolationStatus.NORMAL == instance.getIsolationStatus()) {\n        level1.add(instance);\n        continue;\n      }\n      if (HistoryStatus.HISTORY == instance.getHistoryStatus() &&\n          MicroserviceInstanceStatus.UP == instance.getStatus() &&\n          PingStatus.OK == instance.getPingStatus() &&\n          IsolationStatus.NORMAL == instance.getIsolationStatus()) {\n        level2.add(instance);\n        continue;\n      }\n      level3.add(instance);\n    }\n\n    if (!level0.isEmpty()) {\n      parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n          .subName(parent, GROUP_PREFIX + groups).data(level0));\n      groups++;\n    }\n    if (!level1.isEmpty()) {\n      parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n          .subName(parent, GROUP_PREFIX + groups).data(level1));\n      groups++;\n    }\n    if (!level2.isEmpty()) {\n      parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n          .subName(parent, GROUP_PREFIX + groups).data(level2));\n      groups++;\n    }\n    parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n        .subName(parent, GROUP_PREFIX + groups).data(level3));\n\n    parent.attribute(GROUP_SIZE, groups);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/MicroserviceInstanceCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\nimport com.google.common.cache.Cache;\nimport com.google.common.cache.CacheBuilder;\nimport com.google.common.util.concurrent.UncheckedExecutionException;\n\n/**\n * 在公钥认证场景，需要查询对端的实例信息。\n *\n * 微服务实例缓存 key 为：serviceId@instanceId 缓存limit：1000 缓存老化策略：30分钟没有访问就过期。\n *\n */\npublic class MicroserviceInstanceCache {\n\n  private static final Logger logger = LoggerFactory.getLogger(MicroserviceInstanceCache.class);\n\n  private static final Cache<String, DiscoveryInstance> instances = CacheBuilder.newBuilder()\n      .maximumSize(1000)\n      .expireAfterAccess(30, TimeUnit.MINUTES)\n      .build();\n\n  private final DiscoveryManager discoveryManager;\n\n  public MicroserviceInstanceCache(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  public DiscoveryInstance getOrCreate(String application, String serviceName) {\n    try {\n      String key = String.format(\"%s@%s\", application, serviceName);\n      return instances.get(key, () -> {\n        VersionedCache instances = discoveryManager.getOrCreateVersionedCache(application, serviceName);\n        List<StatefulDiscoveryInstance> statefulDiscoveryInstances = instances.data();\n        if (CollectionUtils.isEmpty(statefulDiscoveryInstances)) {\n          throw new IllegalArgumentException(\"instance id not exists.\");\n        }\n        return statefulDiscoveryInstances.get(0);\n      });\n    } catch (ExecutionException | UncheckedExecutionException e) {\n      logger.error(\"get microservice instance from cache failed, {}, {}\",\n          String.format(\"%s@%s\", application, serviceName),\n          e.getMessage());\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.AbstractDiscoveryInstance;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\n\n/**\n * Wrapper class for DiscoveryInstance with states like: isolation, health, metrics and so on.\n */\npublic class StatefulDiscoveryInstance extends AbstractDiscoveryInstance {\n  public enum IsolationStatus {\n    NORMAL,\n    ISOLATED\n  }\n\n  public enum PingStatus {\n    UNKNOWN,\n    OK,\n    FAIL\n  }\n\n  public enum HistoryStatus {\n    CURRENT,\n    HISTORY\n  }\n\n  private final DiscoveryInstance discoveryInstance;\n\n  private IsolationStatus isolationStatus = IsolationStatus.NORMAL;\n\n  private long isolatedTime;\n\n  private long isolateDuration;\n\n  private PingStatus pingStatus = PingStatus.UNKNOWN;\n\n  private long pingTime = System.currentTimeMillis();\n\n  private HistoryStatus historyStatus = HistoryStatus.CURRENT;\n\n  public StatefulDiscoveryInstance(DiscoveryInstance discoveryInstance) {\n    this.discoveryInstance = discoveryInstance;\n  }\n\n  public IsolationStatus getIsolationStatus() {\n    return isolationStatus;\n  }\n\n  public void setIsolationStatus(\n      IsolationStatus isolationStatus) {\n    this.isolationStatus = isolationStatus;\n  }\n\n  public PingStatus getPingStatus() {\n    return pingStatus;\n  }\n\n  public void setPingStatus(PingStatus pingStatus) {\n    this.pingStatus = pingStatus;\n  }\n\n  public HistoryStatus getHistoryStatus() {\n    return historyStatus;\n  }\n\n  public void setHistoryStatus(HistoryStatus historyStatus) {\n    this.historyStatus = historyStatus;\n  }\n\n  public long getIsolatedTime() {\n    return isolatedTime;\n  }\n\n  public void setIsolatedTime(long isolatedTime) {\n    this.isolatedTime = isolatedTime;\n  }\n\n  public long getIsolateDuration() {\n    return isolateDuration;\n  }\n\n  public void setIsolateDuration(long isolateDuration) {\n    this.isolateDuration = isolateDuration;\n  }\n\n  public long getPingTime() {\n    return pingTime;\n  }\n\n  public void setPingTime(long pingTime) {\n    this.pingTime = pingTime;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return this.discoveryInstance.getStatus();\n  }\n\n  @Override\n  public String getRegistryName() {\n    return this.discoveryInstance.getRegistryName();\n  }\n\n  @Override\n  public String getEnvironment() {\n    return this.discoveryInstance.getEnvironment();\n  }\n\n  @Override\n  public String getApplication() {\n    return this.discoveryInstance.getApplication();\n  }\n\n  @Override\n  public String getServiceName() {\n    return this.discoveryInstance.getServiceName();\n  }\n\n  @Override\n  public String getAlias() {\n    return this.discoveryInstance.getAlias();\n  }\n\n  @Override\n  public String getVersion() {\n    return this.discoveryInstance.getVersion();\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return this.discoveryInstance.getDataCenterInfo();\n  }\n\n  @Override\n  public String getDescription() {\n    return this.discoveryInstance.getDescription();\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return this.discoveryInstance.getProperties();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return this.discoveryInstance.getSchemas();\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return this.discoveryInstance.getEndpoints();\n  }\n\n  @Override\n  public String getInstanceId() {\n    return this.discoveryInstance.getInstanceId();\n  }\n\n  @Override\n  public String getServiceId() {\n    return this.discoveryInstance.getServiceId();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/TelnetInstancePing.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.net.InetSocketAddress;\nimport java.net.Socket;\n\nimport org.apache.servicecomb.foundation.common.net.IpPort;\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\npublic class TelnetInstancePing implements InstancePing {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TelnetInstancePing.class);\n\n  @Override\n  public boolean ping(StatefulDiscoveryInstance instance) {\n    if (CollectionUtils.isEmpty(instance.getEndpoints())) {\n      return false;\n    }\n\n    for (String endpoint : instance.getEndpoints()) {\n      IpPort ipPort = NetUtils.parseIpPortFromURI(endpoint);\n      try (Socket s = new Socket()) {\n        s.connect(new InetSocketAddress(ipPort.getHostOrIp(), ipPort.getPort()), 3000);\n        return true;\n      } catch (Exception e) {\n        LOGGER.warn(\"ping instance {}/{}/{}/{} endpoint {} failed\",\n            instance.getApplication(),\n            instance.getServiceName(),\n            instance.getRegistryName(),\n            instance.getInstanceId(), endpoint);\n      }\n    }\n\n    return false;\n  }\n\n  @Override\n  public int getOrder() {\n    return 10000;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/resources/META-INF/services/org.apache.servicecomb.registry.consumer.MicroserviceInstancePing",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.registry.consumer.SimpleMicroserviceInstancePing\n"
  },
  {
    "path": "foundations/foundation-registry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.RegistryConfiguration\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/TestDiscoveryManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.registry.api.AbstractDiscoveryInstance;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.HistoryStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.IsolationStatus;\nimport org.apache.servicecomb.registry.discovery.TelnetInstancePing;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestDiscoveryManager {\n\n  @Test\n  public void test_initial_service_list_correct() {\n    MyDiscovery discovery1 = Mockito.spy(new MyDiscovery());\n    MyDiscoveryInstance instance1 = Mockito.mock(MyDiscoveryInstance.class);\n    DiscoveryManager discoveryManager = new DiscoveryManager(List.of(discovery1), List.of(new TelnetInstancePing()));\n    Mockito.when(discovery1.findServiceInstances(\"app\", \"service\"))\n        .thenReturn(List.of(instance1));\n    Mockito.when(instance1.getInstanceId()).thenReturn(\"instance1\");\n    //first read\n    VersionedCache versionedCache = discoveryManager.getOrCreateVersionedCache(\"app\", \"service\");\n    List<StatefulDiscoveryInstance> result = versionedCache.data();\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertEquals(\"instance1\", result.get(0).getInstanceId());\n    Assertions.assertEquals(HistoryStatus.CURRENT, result.get(0).getHistoryStatus());\n    // second read\n    versionedCache = discoveryManager.getOrCreateVersionedCache(\"app\", \"service\");\n    result = versionedCache.data();\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertEquals(\"instance1\", result.get(0).getInstanceId());\n    Assertions.assertEquals(HistoryStatus.CURRENT, result.get(0).getHistoryStatus());\n  }\n\n  @Test\n  public void test_initial_empty_service_list_correct() {\n    MyDiscovery discovery1 = Mockito.spy(new MyDiscovery());\n    DiscoveryManager discoveryManager = new DiscoveryManager(List.of(discovery1), List.of(new TelnetInstancePing()));\n    Mockito.when(discovery1.findServiceInstances(\"app\", \"service\"))\n        .thenReturn(Collections.emptyList());\n    //first read\n    VersionedCache versionedCache = discoveryManager.getOrCreateVersionedCache(\"app\", \"service\");\n    List<StatefulDiscoveryInstance> result = versionedCache.data();\n    Assertions.assertEquals(0, result.size());\n    // second read\n    discoveryManager.getOrCreateVersionedCache(\"app\", \"service\");\n    result = versionedCache.data();\n    Assertions.assertEquals(0, result.size());\n  }\n\n  @Test\n  public void test_isolate_service_instance_correct() {\n    MyDiscovery discovery1 = Mockito.spy(new MyDiscovery());\n    MyDiscoveryInstance instance1 = Mockito.mock(MyDiscoveryInstance.class);\n    DiscoveryManager discoveryManager = new DiscoveryManager(List.of(discovery1), List.of(new TelnetInstancePing()));\n    Mockito.when(discovery1.findServiceInstances(\"app\", \"service\"))\n        .thenReturn(List.of(instance1));\n    Mockito.when(instance1.getInstanceId()).thenReturn(\"instance1\");\n    Mockito.when(instance1.getApplication()).thenReturn(\"app\");\n    Mockito.when(instance1.getServiceName()).thenReturn(\"service\");\n\n    VersionedCache versionedCache = discoveryManager.getOrCreateVersionedCache(\"app\", \"service\");\n    List<StatefulDiscoveryInstance> result = versionedCache.data();\n    discoveryManager.onInstanceIsolated(result.get(0), 10000L);\n    versionedCache = discoveryManager.getOrCreateVersionedCache(\"app\", \"service\");\n    result = versionedCache.data();\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertEquals(\"instance1\", result.get(0).getInstanceId());\n    Assertions.assertEquals(HistoryStatus.CURRENT, result.get(0).getHistoryStatus());\n    Assertions.assertEquals(IsolationStatus.ISOLATED, result.get(0).getIsolationStatus());\n  }\n\n  static class MyDiscovery implements Discovery<MyDiscoveryInstance> {\n\n    @Override\n    public String name() {\n      return \"my\";\n    }\n\n    @Override\n    public boolean enabled(String application, String serviceName) {\n      return true;\n    }\n\n    @Override\n    public List<MyDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n      return null;\n    }\n\n    @Override\n    public List<String> findServices(String application) {\n      return null;\n    }\n\n    @Override\n    public void setInstanceChangedListener(InstanceChangedListener<MyDiscoveryInstance> instanceChangedListener) {\n\n    }\n\n    @Override\n    public void init() {\n\n    }\n\n    @Override\n    public void run() {\n\n    }\n\n    @Override\n    public void destroy() {\n\n    }\n\n    @Override\n    public boolean enabled() {\n      return true;\n    }\n  }\n\n  static class MyDiscoveryInstance extends AbstractDiscoveryInstance {\n    @Override\n    public MicroserviceInstanceStatus getStatus() {\n      return null;\n    }\n\n    @Override\n    public String getRegistryName() {\n      return null;\n    }\n\n    @Override\n    public String getEnvironment() {\n      return null;\n    }\n\n    @Override\n    public String getApplication() {\n      return null;\n    }\n\n    @Override\n    public String getServiceName() {\n      return null;\n    }\n\n    @Override\n    public String getAlias() {\n      return null;\n    }\n\n    @Override\n    public String getVersion() {\n      return null;\n    }\n\n    @Override\n    public DataCenterInfo getDataCenterInfo() {\n      return null;\n    }\n\n    @Override\n    public String getDescription() {\n      return null;\n    }\n\n    @Override\n    public Map<String, String> getProperties() {\n      return null;\n    }\n\n    @Override\n    public Map<String, String> getSchemas() {\n      return null;\n    }\n\n    @Override\n    public List<String> getEndpoints() {\n      return null;\n    }\n\n    @Override\n    public String getInstanceId() {\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestAbstractDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestAbstractDiscoveryFilter {\n  int initCallCount;\n\n  int childrenInitedCallCount;\n\n  boolean[] inited = new boolean[] {true, true};\n\n  DiscoveryContext context = new DiscoveryContext();\n\n  DiscoveryTreeNode child = new DiscoveryTreeNode().name(\"c1\");\n\n  DiscoveryTreeNode parent = new DiscoveryTreeNode() {\n    public boolean childrenInited() {\n      childrenInitedCallCount++;\n      return inited[childrenInitedCallCount - 1];\n    }\n  };\n\n  class AbstractDiscoveryFilterForTest extends AbstractDiscoveryFilter {\n    @Override\n    public int getOrder() {\n      return 0;\n    }\n\n    @Override\n    protected void init(DiscoveryContext context, DiscoveryTreeNode parent) {\n      initCallCount++;\n    }\n\n    @Override\n    protected String findChildName(DiscoveryContext context, DiscoveryTreeNode parent) {\n      return child.name();\n    }\n  }\n\n  AbstractDiscoveryFilterForTest filter = new AbstractDiscoveryFilterForTest();\n\n  DiscoveryTreeNode result;\n\n  private void doDiscovery() {\n    parent.child(child.name(), child);\n    result = filter.discovery(context, parent);\n  }\n\n  @Test\n  public void discoveryInited() {\n    doDiscovery();\n\n    Assertions.assertEquals(1, childrenInitedCallCount);\n    Assertions.assertEquals(0, initCallCount);\n    Assertions.assertSame(child, result);\n  }\n\n  @Test\n  public void discoveryNotInitedOnce() {\n    inited[0] = false;\n    doDiscovery();\n\n    Assertions.assertEquals(2, childrenInitedCallCount);\n    Assertions.assertEquals(0, initCallCount);\n    Assertions.assertSame(child, result);\n  }\n\n  @Test\n  public void discoveryNotInitedTwice() {\n    inited[0] = false;\n    inited[1] = false;\n    doDiscovery();\n\n    Assertions.assertEquals(2, childrenInitedCallCount);\n    Assertions.assertEquals(1, initCallCount);\n    Assertions.assertSame(child, result);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestAbstractTransportDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.UUID;\n\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestAbstractTransportDiscoveryFilter {\n  class AbstractEndpointDiscoveryFilterForTest extends AbstractEndpointDiscoveryFilter {\n    @Override\n    public int getOrder() {\n      return 0;\n    }\n\n    @Override\n    protected String findTransportName(DiscoveryContext context, DiscoveryTreeNode parent) {\n      return transportName;\n    }\n\n    @Override\n    protected Object createEndpoint(DiscoveryContext context, String transportName, String endpoint,\n        StatefulDiscoveryInstance instance) {\n      if (disableCreate) {\n        return null;\n      }\n\n      return endpoint;\n    }\n  }\n\n  boolean disableCreate;\n\n  String transportName;\n\n  AbstractEndpointDiscoveryFilterForTest filter = new AbstractEndpointDiscoveryFilterForTest();\n\n  DiscoveryContext context = new DiscoveryContext();\n\n  DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\");\n\n  DiscoveryTreeNode result;\n\n  @Test\n  public void isGroupingFilter() {\n    Assertions.assertTrue(filter.isGroupingFilter());\n  }\n\n  @Test\n  public void isTransportNameMatch_expectAll() {\n    Assertions.assertTrue(filter.isTransportNameMatch(\"any\", \"\"));\n  }\n\n  @Test\n  public void isTransportNameMatch_equals() {\n    Assertions.assertTrue(filter.isTransportNameMatch(\"rest\", \"rest\"));\n  }\n\n  @Test\n  public void isTransportNameMatch_notEquals() {\n    Assertions.assertFalse(filter.isTransportNameMatch(\"rest\", \"highway\"));\n  }\n\n  @Test\n  public void discoveryNotExist() {\n    transportName = \"notExist\";\n    parent.data(Collections.emptyList());\n    result = filter.discovery(context, parent);\n\n    Assertions.assertTrue(result.isEmpty());\n  }\n\n  @Test\n  public void discoveryExist() {\n    transportName = \"rest\";\n    DiscoveryTreeNode child = new DiscoveryTreeNode();\n    parent.child(transportName, child);\n    result = filter.discovery(context, parent);\n\n    Assertions.assertSame(child, result);\n  }\n\n  private StatefulDiscoveryInstance createInstance(String... schemas) {\n    String id = UUID.randomUUID().toString();\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance = new StatefulDiscoveryInstance(discoveryInstance);\n    List<String> endpoints = new ArrayList<>();\n    for (int idx = 0; idx < schemas.length; idx++) {\n      String schema = schemas[idx];\n      endpoints.add(String.format(\"%s://%s:%d\", schema, id, 8080 + idx));\n    }\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(id);\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(endpoints);\n    return instance;\n  }\n\n  private List<StatefulDiscoveryInstance> createMicroserviceInstances(StatefulDiscoveryInstance... instances) {\n    List<StatefulDiscoveryInstance> result = new ArrayList<>();\n    for (StatefulDiscoveryInstance instance : instances) {\n      result.add(instance);\n    }\n    return result;\n  }\n\n  @Test\n  public void createDiscoveryTree_oneTransport() {\n    StatefulDiscoveryInstance instance1 = createInstance(\"a\", \"b\");\n    StatefulDiscoveryInstance instance2 = createInstance(\"b\");\n    List<StatefulDiscoveryInstance> instances = createMicroserviceInstances(instance1, instance2);\n    parent.data(instances);\n\n    result = filter.createDiscoveryTreeNode(\"a\", context, parent);\n\n    Assertions.assertEquals(\"parent/a\", result.name());\n    MatcherAssert.assertThat(result.collectionData(),\n        Matchers.contains(instance1.getEndpoints().get(0)));\n  }\n\n  @Test\n  public void createDiscoveryTree_allTransport() {\n    StatefulDiscoveryInstance instance1 = createInstance(\"a\", \"b\");\n    StatefulDiscoveryInstance instance2 = createInstance(\"b\");\n    List<StatefulDiscoveryInstance> instances = createMicroserviceInstances(instance1, instance2);\n    parent.data(instances);\n\n    result = filter.createDiscoveryTreeNode(\"\", context, parent);\n\n    Assertions.assertEquals(\"parent/\", result.name());\n\n    List<String> expect = new ArrayList<>();\n    expect.addAll(instance1.getEndpoints());\n    expect.addAll(instance2.getEndpoints());\n    MatcherAssert.assertThat(result.collectionData(), Matchers.contains(expect.toArray()));\n  }\n\n  @Test\n  public void createDiscoveryTree_ignoreInvalid() {\n    StatefulDiscoveryInstance instance1 = createInstance(\"a\", \"b\");\n    StatefulDiscoveryInstance instance2 = createInstance(\"\");\n    List<StatefulDiscoveryInstance> instances = createMicroserviceInstances(instance1, instance2);\n    parent.data(instances);\n\n    result = filter.createDiscoveryTreeNode(\"\", context, parent);\n\n    Assertions.assertEquals(\"parent/\", result.name());\n    MatcherAssert.assertThat(result.collectionData(),\n        Matchers.contains(instance1.getEndpoints().toArray()));\n  }\n\n  @Test\n  public void createEndpointNull() {\n    disableCreate = true;\n    StatefulDiscoveryInstance instance1 = createInstance(\"a\", \"b\");\n    List<StatefulDiscoveryInstance> instances = createMicroserviceInstances(instance1);\n    parent.data(instances);\n\n    result = filter.createDiscoveryTreeNode(\"\", context, parent);\n\n    Assertions.assertEquals(\"parent/\", result.name());\n    MatcherAssert.assertThat(result.collectionData(), Matchers.empty());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestDiscoveryContext {\n  DiscoveryContext context = new DiscoveryContext();\n\n  @Test\n  public void inputParameters() {\n    Object inputParameters = new Object();\n    context.setInputParameters(inputParameters);\n\n    Assertions.assertSame(inputParameters, context.getInputParameters());\n  }\n\n  @Test\n  public void contextParameters() {\n    String name = \"name\";\n    Object value = new Object();\n    context.putContextParameter(name, value);\n\n    Assertions.assertSame(value, context.getContextParameter(name));\n    Assertions.assertNull(context.getContextParameter(\"notExist\"));\n  }\n\n  @Test\n  public void rerun() {\n    Assertions.assertNull(context.popRerunFilter());\n\n    DiscoveryTreeNode node = new DiscoveryTreeNode();\n    context.setCurrentNode(node);\n    context.pushRerunFilter();\n\n    Assertions.assertSame(node, context.popRerunFilter());\n    Assertions.assertNull(context.popRerunFilter());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryTree.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestDiscoveryTree {\n  DiscoveryContext context = new DiscoveryContext();\n\n  DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\");\n\n  DiscoveryTreeNode result;\n\n  @BeforeEach\n  public void before() {\n\n  }\n\n  @AfterEach\n  public void tearDown() {\n  }\n\n  @Test\n  public void isMatch_existingNull() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    Assertions.assertFalse(discoveryTree.isMatch(null, null));\n  }\n\n  @Test\n  public void isMatch_yes() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(new DiscoveryManager(Collections.emptyList(),\n        List.of(new TelnetInstancePing())));\n    parent.cacheVersion(1);\n    Assertions.assertTrue(discoveryTree.isMatch(new DiscoveryTreeNode().cacheVersion(1), parent));\n  }\n\n  @Test\n  public void isMatch_no() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    parent.cacheVersion(0);\n    Assertions.assertFalse(discoveryTree.isExpired(new DiscoveryTreeNode().cacheVersion(1), parent));\n  }\n\n  @Test\n  public void isExpired_existingNull() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    Assertions.assertTrue(discoveryTree.isExpired(null, null));\n  }\n\n  @Test\n  public void isExpired_yes() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    parent.cacheVersion(1);\n    Assertions.assertTrue(discoveryTree.isExpired(new DiscoveryTreeNode().cacheVersion(0), parent));\n  }\n\n  @Test\n  public void isExpired_no() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    parent.cacheVersion(0);\n    Assertions.assertFalse(discoveryTree.isExpired(new DiscoveryTreeNode().cacheVersion(0), parent));\n  }\n\n  static class DiscoveryFilterForTest implements DiscoveryFilter {\n    protected String groupName;\n\n    public DiscoveryFilterForTest(String groupName) {\n      this.groupName = groupName;\n    }\n\n    @Override\n    public int getOrder() {\n      return 0;\n    }\n\n    @Override\n    public boolean isGroupingFilter() {\n      return groupName != null;\n    }\n\n    @Override\n    public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n      DiscoveryTreeNode child = new DiscoveryTreeNode();\n      if (groupName != null) {\n        child.subName(parent, groupName);\n      }\n      return child;\n    }\n  }\n\n  @Test\n  public void filterNormal() {\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    parent.name(\"1.0.0-2.0.0\");\n\n    discoveryTree.setDiscoveryFilters(Arrays.asList(new DiscoveryFilterForTest(\"g1\"),\n        new DiscoveryFilterForTest(null), new DiscoveryFilterForTest(\"g2\"),\n        new DiscoveryFilterForTest(null)));\n    result = discoveryTree.discovery(\"app\", \"service\", context, parent);\n\n    Assertions.assertEquals(\"1.0.0-2.0.0/g1/g2\", result.name());\n  }\n\n  @Test\n  public void easyDiscovery() {\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"app\", \"svc\")).thenReturn(parent);\n\n    result = discoveryTree.discovery(context, \"app\", \"svc\");\n    Assertions.assertEquals(parent.name(), result.name());\n    Assertions.assertEquals(parent.cacheVersion(), result.cacheVersion());\n  }\n\n  @Test\n  public void discovery_filterReturnNull() {\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"app\", \"service\")).thenReturn(parent);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    DiscoveryFilter filter = new DiscoveryFilter() {\n      @Override\n      public int getOrder() {\n        return 0;\n      }\n\n      @Override\n      public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n        return null;\n      }\n    };\n    discoveryTree.setDiscoveryFilters(Arrays.asList(filter));\n\n    ServiceCombException exception = Assertions.assertThrows(ServiceCombException.class,\n        () -> result = discoveryTree.discovery(context, \"app\", \"service\"));\n    Assertions.assertEquals(filter.getClass().getName() + \" discovery return null.\", exception.getMessage());\n  }\n\n  @Test\n  public void filterRerun() {\n    parent.name(\"1.0.0-2.0.0\");\n\n    DiscoveryFilterForTest f1 = new DiscoveryFilterForTest(\"g1\") {\n      @Override\n      public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n        if (context.getContextParameter(\"step\") == null) {\n          context.pushRerunFilter();\n          context.putContextParameter(\"step\", 1);\n          return new DiscoveryTreeNode().name(groupName).data(\"first\");\n        }\n\n        return new DiscoveryTreeNode().name(groupName).data(\"second\");\n      }\n    };\n    DiscoveryFilterForTest f2 = new DiscoveryFilterForTest(null) {\n      @Override\n      public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) {\n        if (\"first\".equals(parent.data())) {\n          return new DiscoveryTreeNode();\n        }\n\n        return new DiscoveryTreeNode().data(parent.data());\n      }\n    };\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    discoveryTree.setDiscoveryFilters(Arrays.asList(f1, f2));\n    result = discoveryTree.discovery(\"app\", \"service\", context, parent);\n\n    Assertions.assertEquals(\"second\", result.data());\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void test_multi_service_discovery_correct() {\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    DiscoveryContext discoveryContext = new DiscoveryContext();\n\n    List<String> service1 = Arrays.asList(\"s11\", \"s12\");\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"app\", \"service1\"))\n        .thenReturn(new VersionedCache().name(\"0+\").data(service1));\n    DiscoveryTreeNode result = discoveryTree.discovery(discoveryContext, \"app\", \"service1\");\n    Assertions.assertArrayEquals(service1.toArray(new String[0]),\n        ((List<String>) result.data()).toArray(new String[0]));\n\n    List<String> service2 = Arrays.asList(\"s21\", \"s22\");\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"app\", \"service2\"))\n        .thenReturn(new VersionedCache().name(\"0+\").data(service2));\n    result = discoveryTree.discovery(discoveryContext, \"app\", \"service2\");\n    Assertions.assertArrayEquals(service2.toArray(new String[0]),\n        ((List<String>) result.data()).toArray(new String[0]));\n\n    result = discoveryTree.discovery(discoveryContext, \"app\", \"service1\");\n    Assertions.assertArrayEquals(service1.toArray(new String[0]),\n        ((List<String>) result.data()).toArray(new String[0]));\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void test_one_service_concurrent_correct() throws Exception {\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    DiscoveryContext discoveryContext = new DiscoveryContext();\n    InstanceStatusDiscoveryFilter filter = new InstanceStatusDiscoveryFilter();\n    DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class);\n    Mockito.when(dynamicProperties.getBooleanProperty(Mockito.eq(\"servicecomb.loadbalance.filter.status.enabled\"),\n            Mockito.any(),\n            Mockito.eq(true)))\n        .thenReturn(true);\n    filter.setDynamicProperties(dynamicProperties);\n    discoveryTree.setDiscoveryFilters(List.of(filter));\n\n    StatefulDiscoveryInstance instance1 = Mockito.mock(StatefulDiscoveryInstance.class);\n    StatefulDiscoveryInstance instance2 = Mockito.mock(StatefulDiscoveryInstance.class);\n\n    VersionedCache expects0 = new VersionedCache().autoCacheVersion().name(\"0+\")\n        .data(Arrays.asList(instance1, instance2));\n    VersionedCache[] expects999 = new VersionedCache[999];\n    for (int i = 0; i < 999; i++) {\n      expects999[i] = new VersionedCache().name(\"0+\")\n          .data(Arrays.asList(instance1, instance2)).cacheVersion(i + 1);\n    }\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"app\", \"service1\"))\n        .thenReturn(expects0, expects999);\n\n    CountDownLatch countDownLatch = new CountDownLatch(1000);\n    AtomicInteger success = new AtomicInteger(0);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        for (int j = 0; j < 100; j++) {\n          DiscoveryTreeNode result = discoveryTree.discovery(discoveryContext, \"app\", \"service1\");\n          if (((List<StatefulDiscoveryInstance>) result.data()).size() == 2) {\n            success.getAndIncrement();\n          }\n          countDownLatch.countDown();\n        }\n      }).start();\n    }\n\n    countDownLatch.await(3000, TimeUnit.MILLISECONDS);\n    Assertions.assertEquals(1000, success.get());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryTreeNode.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestDiscoveryTreeNode {\n  DiscoveryTreeNode node = new DiscoveryTreeNode();\n\n  @Test\n  public void childrenInited() {\n    Assertions.assertFalse(node.childrenInited());\n\n    node.childrenInited(true);\n    Assertions.assertTrue(node.childrenInited());\n  }\n\n  @Test\n  public void level() {\n    node.level(1);\n\n    Assertions.assertEquals(1, node.level());\n  }\n\n  @Test\n  public void attribute() {\n    node.attribute(\"k1\", \"v1\");\n\n    Assertions.assertEquals(\"v1\", node.attribute(\"k1\"));\n  }\n\n  @Test\n  public void children() {\n    Map<String, DiscoveryTreeNode> children = new HashMap<>();\n    node.children(children);\n\n    Assertions.assertSame(children, node.children());\n  }\n\n  @Test\n  public void child() {\n    DiscoveryTreeNode child = new DiscoveryTreeNode().name(\"child\");\n    node.child(child.name(), child);\n\n    Assertions.assertSame(child, node.child(child.name()));\n  }\n\n  @Test\n  public void fromCache() {\n    Object data = new Object();\n    VersionedCache other = new VersionedCache().cacheVersion(1).name(\"cache\").data(data);\n    node.fromCache(other);\n\n    Assertions.assertEquals(1, node.cacheVersion());\n    Assertions.assertEquals(\"cache\", node.name());\n    Assertions.assertSame(data, node.data());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestInstanceStatusDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.discovery;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.HistoryStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.IsolationStatus;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance.PingStatus;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestInstanceStatusDiscoveryFilter {\n  @Test\n  public void test_all_group_correct_init() {\n    InstanceStatusDiscoveryFilter filter = new InstanceStatusDiscoveryFilter();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode();\n    List<StatefulDiscoveryInstance> instances = new ArrayList<>();\n    StatefulDiscoveryInstance instance1 = Mockito.mock(StatefulDiscoveryInstance.class);\n    Mockito.when(instance1.getHistoryStatus()).thenReturn(HistoryStatus.CURRENT);\n    Mockito.when(instance1.getStatus()).thenReturn(MicroserviceInstanceStatus.UP);\n    Mockito.when(instance1.getPingStatus()).thenReturn(PingStatus.OK);\n    Mockito.when(instance1.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL);\n    StatefulDiscoveryInstance instance2 = Mockito.mock(StatefulDiscoveryInstance.class);\n    Mockito.when(instance2.getHistoryStatus()).thenReturn(HistoryStatus.CURRENT);\n    Mockito.when(instance2.getStatus()).thenReturn(MicroserviceInstanceStatus.UP);\n    Mockito.when(instance2.getPingStatus()).thenReturn(PingStatus.UNKNOWN);\n    Mockito.when(instance2.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL);\n    StatefulDiscoveryInstance instance3 = Mockito.mock(StatefulDiscoveryInstance.class);\n    Mockito.when(instance3.getHistoryStatus()).thenReturn(HistoryStatus.HISTORY);\n    Mockito.when(instance3.getStatus()).thenReturn(MicroserviceInstanceStatus.UP);\n    Mockito.when(instance3.getPingStatus()).thenReturn(PingStatus.OK);\n    Mockito.when(instance3.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL);\n    StatefulDiscoveryInstance instance4 = Mockito.mock(StatefulDiscoveryInstance.class);\n    Mockito.when(instance4.getHistoryStatus()).thenReturn(HistoryStatus.CURRENT);\n    Mockito.when(instance4.getStatus()).thenReturn(MicroserviceInstanceStatus.UP);\n    Mockito.when(instance4.getPingStatus()).thenReturn(PingStatus.FAIL);\n    Mockito.when(instance4.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL);\n    instances.addAll(Arrays.asList(instance1, instance2, instance3, instance4));\n\n    parent.name(\"parent\");\n    parent.data(instances);\n    filter.init(new DiscoveryContext(), parent);\n\n    List<StatefulDiscoveryInstance> level0 = parent\n        .child(InstanceStatusDiscoveryFilter.GROUP_PREFIX + 1)\n        .data();\n    Assertions.assertEquals(1, level0.size());\n    List<StatefulDiscoveryInstance> level1 = parent\n        .child(InstanceStatusDiscoveryFilter.GROUP_PREFIX + 2)\n        .data();\n    Assertions.assertEquals(1, level1.size());\n    Assertions.assertEquals(1, level1.size());\n    List<StatefulDiscoveryInstance> level2 = parent\n        .child(InstanceStatusDiscoveryFilter.GROUP_PREFIX + 3)\n        .data();\n    Assertions.assertEquals(1, level2.size());\n    List<StatefulDiscoveryInstance> level3 = parent\n        .child(InstanceStatusDiscoveryFilter.GROUP_PREFIX + 4)\n        .data();\n    Assertions.assertEquals(1, level3.size());\n\n    Assertions.assertEquals(null, parent\n        .child(InstanceStatusDiscoveryFilter.GROUP_PREFIX + 5));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-registry/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n  <Appenders>\n    <Console name=\"Console\" target=\"SYSTEM_OUT\">\n      <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\"/>\n    </Console>\n  </Appenders>\n  <Loggers>\n    <Root level=\"INFO\">\n      <AppenderRef ref=\"Console\"/>\n    </Root>\n  </Loggers>\n</Configuration>\n"
  },
  {
    "path": "foundations/foundation-spi/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>foundations</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>foundation-spi</artifactId>\n  <name>Java Chassis::Foundations::SSL</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>slf4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.auth;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\npublic class AuthHeaderLoader {\n  private final List<AuthHeaderProvider> authHeaderProviders =\n      SPIServiceUtils.getSortedService(AuthHeaderProvider.class);\n\n  private static final AuthHeaderLoader INSTANCE = new AuthHeaderLoader();\n\n  private AuthHeaderLoader() {\n\n  }\n\n  public static AuthHeaderLoader getInstance() {\n    return INSTANCE;\n  }\n\n  public Map<String, String> loadAuthHeaders(SignRequest signRequest) {\n    Map<String, String> result = new HashMap<>();\n    authHeaderProviders.forEach(provider -> result.putAll(provider.getSignAuthHeaders(signRequest)));\n    return result;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.auth;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic interface AuthHeaderProvider {\n  /**\n   * Obtain RBAC authentication request header, host is the key of cache\n   *\n   * @param host engine address ip\n   * @return auth headers\n   */\n  default Map<String, String> authHeaders(String host) {\n    return new HashMap<>(0);\n  }\n\n  default Map<String, String> getSignAuthHeaders(SignRequest request) {\n    String host = \"\";\n    if (request != null && request.getEndpoint() != null) {\n      host = request.getEndpoint().getHost();\n    }\n    return authHeaders(host);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/SignRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.auth;\n\nimport java.io.InputStream;\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class SignRequest {\n\n  /**\n   * the resource path being requested\n   */\n  private String resourcePath;\n\n  /**\n   *  queryParams parameters being sent as part of this request.\n   */\n  private Map<String, String[]> queryParams;\n\n  /**\n   * Map of the headers included in this request\n   */\n  private final Map<String, String> headers = new HashMap<>();\n\n  /**\n   * The service endpoint to which this request should be sent\n   */\n  private URI endpoint;\n\n  /**\n   * The HTTP method to use when sending this request.\n   */\n  private String httpMethod = \"GET\";\n\n  /**\n   * An optional stream from which to read the request payload.\n   */\n  private InputStream content;\n\n  /**\n   * The datetime in milliseconds for which the signature needs to be\n   * computed.\n   */\n  private final long signingDateTimeMilli = System.currentTimeMillis();\n\n  /**\n   * The scope of the signature.\n   */\n  private String scope;\n\n  /**\n   * The region to be used for computing the signature.\n   */\n  private String regionName;\n\n  /**\n   * The name of the service.\n   */\n  private String serviceName;\n\n  /**\n   * UTC formatted version of the signing time stamp.\n   */\n  private String formattedSigningDateTime;\n\n  /**\n   * UTC Formatted Signing date with time stamp stripped\n   */\n  private String formattedSigningDate;\n\n  public SignRequest() {\n\n  }\n\n  public String getResourcePath() {\n    return resourcePath;\n  }\n\n  public void setResourcePath(String resourcePath) {\n    this.resourcePath = resourcePath;\n  }\n\n\n  public long getSigningDateTimeMilli() {\n    return signingDateTimeMilli;\n  }\n\n  public String getScope() {\n    return scope;\n  }\n\n  public void setScope(String scope) {\n    this.scope = scope;\n  }\n\n  public String getRegionName() {\n    if (regionName == null) {\n      return \"\";\n    }\n    return regionName;\n  }\n\n  public void setRegionName(String regionName) {\n    this.regionName = regionName;\n  }\n\n  public String getServiceName() {\n    if (serviceName == null) {\n      return \"\";\n    }\n    return serviceName;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public String getFormattedSigningDateTime() {\n    return formattedSigningDateTime;\n  }\n\n  public void setFormattedSigningDateTime(String formattedSigningDateTime) {\n    this.formattedSigningDateTime = formattedSigningDateTime;\n  }\n\n  public String getFormattedSigningDate() {\n    return formattedSigningDate;\n  }\n\n  public void setFormattedSigningDate(String formattedSigningDate) {\n    this.formattedSigningDate = formattedSigningDate;\n  }\n\n  public Map<String, String> getHeaders() {\n    return headers;\n  }\n\n  public String getHttpMethod() {\n    return httpMethod;\n  }\n\n\n  public void setHttpMethod(String httpMethod) {\n    this.httpMethod = httpMethod;\n  }\n\n\n  public void setEndpoint(URI endpoint) {\n    this.endpoint = endpoint;\n  }\n\n\n  public URI getEndpoint() {\n    return endpoint;\n  }\n\n\n  public InputStream getContent() {\n    return content;\n  }\n\n\n  public void setContent(InputStream content) {\n    this.content = content;\n  }\n\n\n  public void setHeaders(Map<String, String> headers) {\n    this.headers.clear();\n    this.headers.putAll(headers);\n  }\n\n\n  public Map<String, String[]> getQueryParams() {\n    return queryParams;\n  }\n\n  public void setQueryParams(Map<String, String[]> queryParams) {\n    this.queryParams = queryParams;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/bootstrap/BootStrapService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.bootstrap;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\nimport org.springframework.core.env.Environment;\n\n/**\n * A boot strap service is loaded after Spring Environment is created.\n *\n * In boot strap service, user's can only read configurations from Environment. Dynamic configurations\n *\n * from config center is not available.\n *\n * e.g. an authentication service must be connected before connecting to config center.\n * e.g. an config center configurations must be read before connecting to config center.\n */\npublic interface BootStrapService extends SPIOrder {\n  void startup(Environment environment);\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIEnabled.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic interface SPIEnabled {\n  boolean enabled();\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIOrder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport org.springframework.core.Ordered;\n\npublic interface SPIOrder extends Ordered {\n  default int getOrder() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/common/utils/SPIServiceUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.lang.reflect.Method;\nimport java.util.AbstractMap.SimpleEntry;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.ServiceLoader;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.ReflectionUtils;\n\n/**\n * SPI Service utils\n *\n *\n */\npublic final class SPIServiceUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SPIServiceUtils.class);\n\n  // load one service, maybe trigger load another service\n  // computeIfAbsent can not support this feature\n  // so use double check\n  private static final Object LOCK = new Object();\n\n  private static final Map<Class<?>, List<Object>> cache = new ConcurrentHashMap<>();\n\n  private SPIServiceUtils() {\n\n  }\n\n  /**\n   * no cache, return new instances every time.\n   */\n  public static <T> List<T> loadSortedService(Class<T> serviceType) {\n    List<Entry<Integer, T>> serviceEntries = new ArrayList<>();\n    ServiceLoader<T> serviceLoader = ServiceLoader.load(serviceType);\n    serviceLoader.forEach(service -> {\n      int serviceOrder = 0;\n      Method getOrder = ReflectionUtils.findMethod(service.getClass(), \"getOrder\");\n      if (getOrder != null) {\n        serviceOrder = (int) ReflectionUtils.invokeMethod(getOrder, service);\n      }\n\n      Entry<Integer, T> entry = new SimpleEntry<>(serviceOrder, service);\n      serviceEntries.add(entry);\n    });\n\n    List<T> services = serviceEntries.stream()\n        .sorted(Comparator.comparingInt(Entry::getKey))\n        .map(Entry::getValue)\n        .collect(Collectors.toList());\n\n    StringBuilder info = new StringBuilder();\n    for (int idx = 0; idx < services.size(); idx++) {\n      T service = services.get(idx);\n      info.append(\"{\").append(idx).append(\",\").append(service.getClass().getSimpleName()).append(\"}\");\n    }\n    LOGGER.info(\"Found SPI service {}, services={}.\", serviceType.getSimpleName(), info);\n\n    return services;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> List<T> getOrLoadSortedService(Class<T> serviceType) {\n    List<Object> services = cache.get(serviceType);\n    if (services == null) {\n      synchronized (LOCK) {\n        services = cache.get(serviceType);\n        if (services == null) {\n          services = (List<Object>) loadSortedService(serviceType);\n          cache.put(serviceType, services);\n        }\n      }\n    }\n\n    return (List<T>) services;\n  }\n\n  /**\n   * get target service.if target services are array,only random access to a service.\n   */\n  public static <T> T getTargetService(Class<T> serviceType) {\n    List<T> services = getOrLoadSortedService(serviceType);\n    if (services.isEmpty()) {\n      LOGGER.info(\"Can not find SPI service for {}\", serviceType.getName());\n      return null;\n    }\n\n    return services.get(0);\n  }\n\n  public static <T> List<T> getAllService(Class<T> serviceType) {\n    return getOrLoadSortedService(serviceType);\n  }\n\n  public static <T> List<T> getSortedService(Class<T> serviceType) {\n    return getOrLoadSortedService(serviceType);\n  }\n\n  public static <T> T getPriorityHighestService(Class<T> serviceType) {\n    List<T> services = getOrLoadSortedService(serviceType);\n    if (services.isEmpty()) {\n      LOGGER.info(\"Can not find SPI service for {}\", serviceType.getName());\n      return null;\n    }\n\n    return services.get(0);\n  }\n\n  public static <T> Collection<T> getPriorityHighestServices(Function<T, String> keyFunc, Class<T> serviceType) {\n    List<T> services = getOrLoadSortedService(serviceType);\n    if (services.isEmpty()) {\n      LOGGER.info(\"Can not find SPI service for {}\", serviceType.getName());\n      return null;\n    }\n\n    Map<String, T> map = new HashMap<>();\n    services.forEach(instance -> map.putIfAbsent(keyFunc.apply(instance), instance));\n    return map.values();\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T, IMPL> IMPL getTargetService(Class<T> serviceType, Class<IMPL> implType) {\n    List<T> services = getOrLoadSortedService(serviceType);\n    return (IMPL) services\n        .stream()\n        .filter(service -> service.getClass().equals(implType))\n        .findFirst()\n        .orElse(null);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic interface SPIServiceDef {\n\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic interface SPIServiceDef0 {\n\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDef0Impl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic class SPIServiceDef0Impl implements SPIServiceDef0 {\n\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/SPIServiceDefImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\npublic class SPIServiceDefImpl implements SPIServiceDef {\n\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/test/java/org/apache/servicecomb/foundation/common/utils/TestSPIServiceUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.common.utils;\n\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.ServiceLoader;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.condition.EnabledOnJre;\nimport org.junit.jupiter.api.condition.JRE;\nimport org.mockito.Mockito;\nimport org.springframework.core.Ordered;\n\nimport mockit.Deencapsulation;\nimport mockit.Expectations;\n\n/**\n * Test SPIServiceUtils\n *\n *\n */\npublic class TestSPIServiceUtils {\n  @Test\n  public void testGetTargetServiceNull() {\n    SPIServiceDef0 service = SPIServiceUtils.getTargetService(SPIServiceDef0.class);\n    Assertions.assertNull(service);\n  }\n\n  @Test\n  public void testGetTargetServiceNotNull() {\n    SPIServiceDef service = SPIServiceUtils.getTargetService(SPIServiceDef.class);\n    Assertions.assertNotNull(service);\n\n    Assertions.assertSame(service, SPIServiceUtils.getTargetService(SPIServiceDef.class));\n  }\n\n  @Test\n  public void testGetTargetService_special_null() {\n    Assertions.assertNull(SPIServiceUtils.getTargetService(SPIServiceDef0.class, SPIServiceDef0Impl.class));\n  }\n\n  @Test\n  public void testGetTargetService_special_notNull() {\n    SPIServiceDef service = SPIServiceUtils.getTargetService(SPIServiceDef.class, SPIServiceDefImpl.class);\n    Assertions.assertNotNull(service);\n  }\n\n  @Test\n  @EnabledOnJre(JRE.JAVA_8)\n  public void testSort() {\n    Ordered o1 = Mockito.mock(Ordered.class);\n    Ordered o2 = Mockito.mock(Ordered.class);\n    Map<String, Ordered> map = new LinkedHashMap<>();\n    map.put(\"a\", o1);\n    map.put(\"b\", o2);\n\n    ServiceLoader<Ordered> serviceLoader = ServiceLoader.load(Ordered.class);\n    Deencapsulation.setField(serviceLoader, \"providers\", map);\n    new Expectations(ServiceLoader.class) {\n      {\n        o1.getOrder();\n        result = -1;\n        o2.getOrder();\n        result = Integer.MAX_VALUE;\n        ServiceLoader.load(Ordered.class);\n        result = serviceLoader;\n      }\n    };\n\n    MatcherAssert.assertThat(SPIServiceUtils.getSortedService(Ordered.class), Matchers.contains(o1, o2));\n    MatcherAssert.assertThat(SPIServiceUtils.getAllService(Ordered.class), Matchers.contains(o1, o2));\n    MatcherAssert.assertThat(SPIServiceUtils.getPriorityHighestService(Ordered.class), Matchers.is(o1));\n\n    Map<Class<?>, List<Object>> cache = Deencapsulation.getField(SPIServiceUtils.class, \"cache\");\n    cache.clear();\n  }\n\n  @Test\n  public void getPriorityHighestService_null() {\n    Assertions.assertNull(SPIServiceUtils.getPriorityHighestService(SPIServiceDef0.class));\n  }\n\n  interface PriorityIntf {\n    String getName();\n\n    int getOrder();\n  }\n\n  public static class PriorityImpl implements PriorityIntf {\n    private final String name;\n\n    private final int order;\n\n    public PriorityImpl(String name, int order) {\n      this.name = name;\n      this.order = order;\n    }\n\n    @Override\n    public String getName() {\n      return name;\n    }\n\n    @Override\n    public int getOrder() {\n      return order;\n    }\n\n    @Override\n    public String toString() {\n      return \"PriorityImpl{\" +\n              \"name='\" + name + '\\'' +\n              \", order=\" + order +\n              '}';\n    }\n  }\n\n  @Test\n  @EnabledOnJre(JRE.JAVA_8)\n  public void getPriorityHighestServices() {\n    Map<String, PriorityIntf> instances = new LinkedHashMap<>();\n    instances.putIfAbsent(\"1\", new PriorityImpl(\"n1\", 0));\n    instances.putIfAbsent(\"2\", new PriorityImpl(\"n1\", -1));\n    instances.putIfAbsent(\"3\", new PriorityImpl(\"n1\", 1));\n    instances.putIfAbsent(\"4\", new PriorityImpl(\"n2\", 0));\n    instances.putIfAbsent(\"5\", new PriorityImpl(\"n2\", -1));\n    instances.putIfAbsent(\"6\", new PriorityImpl(\"n2\", 1));\n\n    ServiceLoader<PriorityIntf> serviceLoader = ServiceLoader.load(PriorityIntf.class);\n    Deencapsulation.setField(serviceLoader, \"providers\", instances);\n    new Expectations(ServiceLoader.class) {\n      {\n        ServiceLoader.load(PriorityIntf.class);\n        result = serviceLoader;\n      }\n    };\n\n    MatcherAssert.assertThat(SPIServiceUtils.getPriorityHighestServices(PriorityIntf::getName, PriorityIntf.class),\n            Matchers.containsInAnyOrder(instances.get(\"2\"), instances.get(\"5\")));\n\n    Map<Class<?>, List<Object>> cache = Deencapsulation.getField(SPIServiceUtils.class, \"cache\");\n    cache.clear();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-spi/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.common.utils.SPIServiceDef",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.foundation.common.utils.SPIServiceDefImpl\n"
  },
  {
    "path": "foundations/foundation-ssl/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>foundations</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>foundation-ssl</artifactId>\n  <name>Java Chassis::Foundations::SSL</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-context</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.slf4j</groupId>\n      <artifactId>slf4j-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.netty</groupId>\n      <artifactId>netty-tcnative-boringssl-static</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/CertificateUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.security.cert.CertificateParsingException;\nimport java.security.cert.X509Certificate;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * 证书处理的功能方法\n *\n */\npublic final class CertificateUtil {\n  private static final int SUBALTNAME_DNSNAME = 2;\n\n  private static final int SUBALTNAME_IPADDRESS = 7;\n\n  private CertificateUtil() {\n\n  }\n\n  /**\n   * 将证书链进行排序。颁发机构的证书排在前面，所有者排在后面。如：rootCA > subCA > owner。\n   * <B>注意：</B>传入的证书必须是“一条完整证书链\"。\n   * @param cerChain\n   *            将要排序的证书链。\n   * @return 排序后的证书链。\n   */\n  private static X509Certificate[] sort(X509Certificate[] cerChain) {\n    X509Certificate[] chain = new X509Certificate[cerChain.length];\n    X509Certificate root = findRootCA(cerChain);\n    chain[0] = root;\n\n    for (int i = 1; i < chain.length; i++) {\n      X509Certificate parent = chain[i - 1];\n      for (X509Certificate child : cerChain) {\n        String parentDN = parent.getSubjectX500Principal().getName();\n        String childDN = child.getSubjectX500Principal().getName();\n        if (parentDN.equals(childDN)) {\n          continue;\n        }\n\n        String childIssuerDN = child.getIssuerX500Principal().getName();\n        if (parentDN.equals(childIssuerDN)) {\n          chain[i] = child;\n          break;\n        }\n      }\n    }\n\n    return chain;\n  }\n\n  /**\n   * 从证书链里面返回根证书，即自签名的证书。\n   * <B>注意：</B>传入的证书必须是“一条完整证书链\"。\n   * @param cerChain\n   *            证书链。\n   * @return 根证书。\n   */\n  private static X509Certificate findRootCA(X509Certificate[] cerChain) {\n    if (cerChain.length == 1) {\n      return cerChain[0];\n    }\n\n    for (X509Certificate item : cerChain) {\n      String subjectDN = item.getSubjectX500Principal().getName();\n      String issuserDN = item.getIssuerX500Principal().getName();\n      if (subjectDN.equals(issuserDN)) {\n        return item;\n      }\n    }\n\n    throw new IllegalArgumentException(\"bad certificate chain: no root CA.\");\n  }\n\n  /**\n   * 从证书链里面返回证书所有者。即CA颁发的证书的所有者。位于证书链最下方。\n   * <B>注意：</B>传入的证书必须是“一条完整证书链\"。\n   * @param cerChain\n   *            证书链。\n   * @return 所有者\n   */\n  public static X509Certificate findOwner(X509Certificate[] cerChain) {\n    X509Certificate[] sorted = sort(cerChain);\n    return sorted[sorted.length - 1];\n  }\n\n  public static Set<String> getCN(X509Certificate cert) {\n    Set<String> names = new HashSet<>();\n\n    // 读取CN\n    String subjectDN = cert.getSubjectX500Principal().getName();\n    String[] pairs = subjectDN.split(\",\");\n    for (String p : pairs) {\n      String[] kv = p.split(\"=\");\n      if (kv.length == 2 && kv[0].equals(\"CN\")) {\n        names.add(kv[1]);\n      }\n    }\n\n    // 读取SubjectAlternativeNames\n    try {\n      Collection<List<?>> collection = cert.getSubjectAlternativeNames();\n      if (collection != null) {\n        for (List<?> list : collection) {\n          if (list.size() == 2) {\n            Object key = list.get(0);\n            Object value = list.get(1);\n            if (key instanceof Integer && value instanceof String) {\n              int intKey = (Integer) key;\n              String strValue = (String) value;\n              if (intKey == SUBALTNAME_DNSNAME || intKey == SUBALTNAME_IPADDRESS) {\n                names.add(strValue);\n              }\n            }\n          }\n        }\n      }\n    } catch (CertificateParsingException e) {\n      throw new IllegalArgumentException(\"can not read AlternativeNames.\");\n    }\n\n    return names;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/ClientAuth.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\npublic final class ClientAuth {\n  public static final String REQUIRED = \"REQUIRED\";\n\n  public static final String REQUEST = \"REQUEST\";\n\n  public static final String NONE = \"NONE\";\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/KeyStoreUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.security.KeyStore;\nimport java.security.cert.CRL;\nimport java.security.cert.CRLException;\nimport java.security.cert.CertificateException;\nimport java.security.cert.CertificateFactory;\nimport java.util.Collection;\n\nimport javax.net.ssl.KeyManager;\nimport javax.net.ssl.KeyManagerFactory;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.TrustManagerFactory;\n\npublic final class KeyStoreUtil {\n  private KeyStoreUtil() {\n\n  }\n\n  public static KeyStore createKeyStore(String storeName, String storeType,\n      char[] storeValue) {\n    if (storeName == null) {\n      return null;\n    }\n\n    File storeFile = new File(storeName);\n\n    try {\n      if (storeFile.isFile()) {\n        return createKeyStore(new FileInputStream(storeFile), storeType, storeValue);\n      }\n\n      ClassLoader classLoader =\n          Thread.currentThread().getContextClassLoader() == null ? KeyStoreUtil.class.getClassLoader()\n              : Thread.currentThread().getContextClassLoader();\n      URL resource = classLoader.getResource(storeName);\n      if (resource != null) {\n        return createKeyStore(resource.openStream(), storeType, storeValue);\n      }\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\"Bad key store or value.\"\n          + e.getMessage());\n    }\n\n    return null;\n  }\n\n  public static KeyStore createKeyStore(InputStream store, String storeType,\n      char[] storeValue) {\n    try (InputStream is = store) {\n      KeyStore keystore = KeyStore.getInstance(storeType);\n      keystore.load(is, storeValue);\n      return keystore;\n    } catch (Exception e) {\n      throw new IllegalArgumentException(\"Bad key store or value.\"\n          + e.getMessage());\n    }\n  }\n\n  @SuppressWarnings({\"rawtypes\", \"unchecked\"})\n  public static CRL[] createCRL(String crlfile) {\n    InputStream is = null;\n    try {\n      CertificateFactory cf = CertificateFactory.getInstance(\"X.509\");\n      is = new FileInputStream(crlfile);\n      Collection c = cf.generateCRLs(is);\n      return (CRL[]) c.toArray(new CRL[0]);\n    } catch (CertificateException e) {\n      throw new IllegalArgumentException(\"bad cert file.\");\n    } catch (FileNotFoundException e) {\n      throw new IllegalArgumentException(\"crl file not found.\");\n    } catch (CRLException e) {\n      throw new IllegalArgumentException(\"bad crl file.\");\n    } finally {\n      if (is != null) {\n        try {\n          is.close();\n        } catch (IOException e) {\n          ignore();\n        }\n      }\n    }\n  }\n\n  public static KeyManager[] createKeyManagers(final KeyStore keystore,\n      char[] keyvalue) {\n    try {\n      KeyManagerFactory kmfactory =\n          KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());\n      kmfactory.init(keystore, keyvalue);\n      return kmfactory.getKeyManagers();\n    } catch (Exception e) {\n      throw new IllegalArgumentException(\"Bad key store.\"\n          + e.getMessage());\n    }\n  }\n\n  public static TrustManager[] createTrustManagers(final KeyStore keystore) {\n    try {\n      TrustManagerFactory tmfactory =\n          TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());\n      tmfactory.init(keystore);\n      return tmfactory.getTrustManagers();\n    } catch (Exception e) {\n      throw new IllegalArgumentException(\"Bad trust store.\"\n          + e.getMessage());\n    }\n  }\n\n  private static void ignore() {\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLCustom.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * 和应用相关的信息，方便定制使用。 目前主要包含密码解密、证书路径、IP和Port等内容。\n *\n */\npublic abstract class SSLCustom {\n  private static final Logger LOG = LoggerFactory.getLogger(SSLCustom.class);\n\n  public static SSLCustom defaultSSLCustom() {\n    final SSLCustom custom = new SSLCustom() {\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n\n      @Override\n      public String getFullPath(String filename) {\n        return filename;\n      }\n    };\n    return custom;\n  }\n\n  public static SSLCustom createSSLCustom(String name) {\n    try {\n      if (name != null && !name.isEmpty()) {\n        return (SSLCustom) Class.forName(name).getDeclaredConstructor().newInstance();\n      }\n    } catch (ReflectiveOperationException e) {\n      LOG.warn(\"init SSLCustom class failed, name is \" + name);\n    }\n    return defaultSSLCustom();\n  }\n\n  public abstract char[] decode(char[] encrypted);\n\n  public abstract String getFullPath(String filename);\n\n  public String getHost() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.IOException;\nimport java.net.UnknownHostException;\nimport java.security.KeyManagementException;\nimport java.security.KeyStore;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.SecureRandom;\n\nimport javax.net.ssl.KeyManager;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLEngine;\nimport javax.net.ssl.SSLServerSocket;\nimport javax.net.ssl.SSLServerSocketFactory;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.X509ExtendedTrustManager;\n\nimport org.apache.commons.lang3.StringUtils;\n\n\n/**\n * 根据传递的SSLOption构造SSL上下文。请参考JSSE获取相关API的层次参考。\n *\n */\npublic final class SSLManager {\n  private SSLManager() {\n\n  }\n\n  public static SSLContext createSSLContext(SSLOption option, SSLCustom custom) {\n    try {\n      String keyStoreName = custom.getFullPath(option.getKeyStore());\n      char[] keyStoreValue = option.getKeyStoreValue() == null ? new char[0] :\n          custom.decode(option.getKeyStoreValue().toCharArray());\n      KeyStore keyStore =\n          KeyStoreUtil.createKeyStore(keyStoreName,\n              option.getKeyStoreType(),\n              keyStoreValue);\n\n      KeyManager[] keyManager = null;\n      if (keyStore != null) {\n        keyManager =\n            KeyStoreUtil.createKeyManagers(keyStore, keyStoreValue);\n      }\n\n      String trustStoreName = custom.getFullPath(option.getTrustStore());\n      char[] trustStoreValue = option.getTrustStoreValue() == null ? new char[0] :\n          custom.decode(option.getTrustStoreValue().toCharArray());\n      KeyStore trustStore =\n          KeyStoreUtil.createKeyStore(trustStoreName,\n              option.getTrustStoreType(),\n              trustStoreValue);\n\n      TrustManager[] trustManager;\n      if (trustStore != null) {\n        trustManager =\n            KeyStoreUtil.createTrustManagers(trustStore);\n      } else {\n        trustManager = new TrustManager[] {new TrustAllManager()};\n      }\n\n      TrustManager[] wrapped = new TrustManager[trustManager.length];\n      for (int i = 0; i < trustManager.length; i++) {\n        wrapped[i] =\n            new TrustManagerExt((X509ExtendedTrustManager) trustManager[i],\n                option, custom);\n      }\n\n      // ?: ssl context version\n      SSLContext context = SSLContext.getInstance(\"TLS\");\n      context.init(keyManager, wrapped, new SecureRandom());\n      return context;\n    } catch (NoSuchAlgorithmException e) {\n      throw new IllegalArgumentException(\"NoSuchAlgorithmException.\"\n          + e.getMessage());\n    } catch (KeyManagementException e) {\n      throw new IllegalArgumentException(\"KeyManagementException.\"\n          + e.getMessage());\n    }\n  }\n\n  public static SSLSocketFactory createSSLSocketFactory(SSLOption option, SSLCustom custom) {\n    SSLContext context = createSSLContext(option, custom);\n    SSLSocketFactory factory = context.getSocketFactory();\n    String[] supported = factory.getSupportedCipherSuites();\n    String[] enabled = option.getCiphers().split(\",\");\n    return new SSLSocketFactoryExt(factory, getEnabledCiphers(supported, enabled),\n        option.getProtocols().split(\",\"));\n  }\n\n  public static SSLEngine createSSLEngine(SSLOption option, SSLCustom custom) {\n    SSLContext context = createSSLContext(option, custom);\n    SSLEngine engine =\n        context.createSSLEngine();\n    engine.setEnabledProtocols(option.getProtocols().split(\",\"));\n    String[] supported = engine.getSupportedCipherSuites();\n    String[] enabled = option.getCiphers().split(\",\");\n    engine.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));\n    setClientAuth(option, engine);\n    return engine;\n  }\n\n  public static SSLEngine createSSLEngine(SSLOption option, SSLCustom custom, String peerHost, int peerPort) {\n    SSLContext context = createSSLContext(option, custom);\n    SSLEngine engine =\n        context.createSSLEngine(peerHost, peerPort);\n    engine.setEnabledProtocols(option.getProtocols().split(\",\"));\n    String[] supported = engine.getSupportedCipherSuites();\n    String[] enabled = option.getCiphers().split(\",\");\n    engine.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));\n    setClientAuth(option, engine);\n    return engine;\n  }\n\n  private static void setClientAuth(SSLOption option, SSLEngine engine) {\n    if (option.isAuthPeer() || ClientAuth.REQUIRED.equals(option.getClientAuth())) {\n      engine.setNeedClientAuth(true);\n      return;\n    }\n    if (ClientAuth.NONE.equals(option.getClientAuth())) {\n      engine.setNeedClientAuth(false);\n      engine.setWantClientAuth(false);\n      return;\n    }\n    engine.setWantClientAuth(true);\n  }\n\n  private static void setClientAuth(SSLOption option, SSLServerSocket serverSocket) {\n    if (option.isAuthPeer() || ClientAuth.REQUIRED.equals(option.getClientAuth())) {\n      serverSocket.setNeedClientAuth(true);\n      return;\n    }\n    if (ClientAuth.NONE.equals(option.getClientAuth())) {\n      serverSocket.setNeedClientAuth(false);\n      serverSocket.setWantClientAuth(false);\n      return;\n    }\n    serverSocket.setWantClientAuth(true);\n  }\n\n  public static SSLServerSocket createSSLServerSocket(SSLOption option,\n      SSLCustom custom) {\n    try {\n      SSLContext context = createSSLContext(option, custom);\n      SSLServerSocketFactory factory = context.getServerSocketFactory();\n      SSLServerSocket socket =\n          (SSLServerSocket) factory.createServerSocket();\n      socket.setEnabledProtocols(option.getProtocols().split(\",\"));\n      String[] supported = socket.getSupportedCipherSuites();\n      String[] enabled = option.getCiphers().split(\",\");\n      socket.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));\n      setClientAuth(option, socket);\n      return socket;\n    } catch (UnknownHostException e) {\n      throw new IllegalArgumentException(\"unknown host\");\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\"unable create socket\");\n    }\n  }\n\n  public static SSLSocket createSSLSocket(SSLOption option, SSLCustom custom) {\n    try {\n      SSLContext context = createSSLContext(option, custom);\n      SSLSocketFactory factory = context.getSocketFactory();\n      SSLSocket socket =\n          (SSLSocket) factory.createSocket();\n      socket.setEnabledProtocols(option.getProtocols().split(\",\"));\n      String[] supported = socket.getSupportedCipherSuites();\n      String[] enabled = option.getCiphers().split(\"\\\\s*,\\\\s*\");\n      socket.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));\n      return socket;\n    } catch (UnknownHostException e) {\n      throw new IllegalArgumentException(\"unknown host\");\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\"unable create socket\");\n    }\n  }\n\n  private static String[] getEnabledCiphers(String[] supported,\n      String[] enabled) {\n    String[] result = new String[enabled.length];\n    int count = 0;\n    for (String e : enabled) {\n      for (String s : supported) {\n        if (e.equals(s)) {\n          result[count++] = e;\n          break;\n        }\n      }\n    }\n\n    if (count == 0) {\n      throw new IllegalArgumentException(\"no enabled cipher suits.\");\n    }\n\n    String[] r = new String[count];\n    System.arraycopy(result, 0, r, 0, count);\n    return r;\n  }\n\n  public static String[] getEnabledCiphers(SSLOption sslOption) {\n    SSLOption option = new SSLOption();\n    if (StringUtils.isNotEmpty(sslOption.getProtocols())) {\n      option.setProtocols(sslOption.getProtocols());\n    } else {\n      option.setProtocols(\"TLSv1.2\");\n    }\n    option.setCiphers(sslOption.getCiphers());\n    SSLCustom custom = SSLCustom.defaultSSLCustom();\n    SSLSocket socket = createSSLSocket(option, custom);\n    return socket.getEnabledCipherSuites();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Properties;\n\nimport org.springframework.core.env.Environment;\n\n/**\n * SSL配置选项。\n *\n */\npublic final class SSLOption {\n  public static final SSLOption DEFAULT_OPTION = new SSLOption();\n\n  public static final String DEFAULT_CIPHERS = \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,\"\n      + \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\";\n\n  static {\n    DEFAULT_OPTION.setEngine(\"jdk\");\n    DEFAULT_OPTION.setProtocols(\"TLSv1.2\");\n    DEFAULT_OPTION.setCiphers(DEFAULT_CIPHERS);\n    DEFAULT_OPTION.setAuthPeer(false);\n    DEFAULT_OPTION.setCheckCNHost(false);\n    DEFAULT_OPTION.setCheckCNWhite(false);\n    DEFAULT_OPTION.setCheckCNWhiteFile(\"white.list\");\n    DEFAULT_OPTION.setAllowRenegotiate(true);\n    DEFAULT_OPTION.setStorePath(\"internal\");\n    DEFAULT_OPTION.setTrustStore(\"trust.jks\");\n    DEFAULT_OPTION.setTrustStoreType(\"JKS\");\n    DEFAULT_OPTION.setTrustStoreValue(\"trustStoreValue\");\n    DEFAULT_OPTION.setKeyStore(\"server.p12\");\n    DEFAULT_OPTION.setKeyStoreType(\"PKCS12\");\n    DEFAULT_OPTION.setKeyStoreValue(\"keyStoreValue\");\n    DEFAULT_OPTION.setCrl(\"revoke.crl\");\n  }\n\n  private String engine;\n\n  private String protocols;\n\n  private String ciphers;\n\n  private boolean authPeer;\n\n  private boolean checkCNHost;\n\n  private boolean checkCNWhite;\n\n  private String checkCNWhiteFile;\n\n  private boolean allowRenegotiate;\n\n  private String clientAuth;\n\n  private String storePath;\n\n  private String trustStore;\n\n  private String trustStoreType;\n\n  private String trustStoreValue;\n\n  private String keyStore;\n\n  private String keyStoreType;\n\n  private String keyStoreValue;\n\n  private String crl;\n\n  private String sslCustomClass;\n\n  public String getEngine() {\n    return engine;\n  }\n\n  public void setEngine(String engine) {\n    this.engine = engine;\n  }\n\n  public void setProtocols(String protocols) {\n    this.protocols = protocols;\n  }\n\n  public void setCiphers(String ciphers) {\n    this.ciphers = ciphers;\n  }\n\n  public void setAuthPeer(boolean authPeer) {\n    this.authPeer = authPeer;\n  }\n\n  public void setCheckCNHost(boolean checkCNHost) {\n    this.checkCNHost = checkCNHost;\n  }\n\n  public void setCheckCNWhite(boolean checkCNWhite) {\n    this.checkCNWhite = checkCNWhite;\n  }\n\n  public void setCheckCNWhiteFile(String checkCNWhiteFile) {\n    this.checkCNWhiteFile = checkCNWhiteFile;\n  }\n\n  public void setAllowRenegotiate(boolean allowRenegotiate) {\n    this.allowRenegotiate = allowRenegotiate;\n  }\n\n  public void setStorePath(String storePath) {\n    this.storePath = storePath;\n  }\n\n  public void setTrustStore(String trustStore) {\n    this.trustStore = trustStore;\n  }\n\n  public void setTrustStoreType(String trustStoreType) {\n    this.trustStoreType = trustStoreType;\n  }\n\n  public void setTrustStoreValue(String trustStoreValue) {\n    this.trustStoreValue = trustStoreValue;\n  }\n\n  public void setKeyStore(String keyStore) {\n    this.keyStore = keyStore;\n  }\n\n  public void setKeyStoreType(String keyStoreType) {\n    this.keyStoreType = keyStoreType;\n  }\n\n  public void setKeyStoreValue(String keyStoreValue) {\n    this.keyStoreValue = keyStoreValue;\n  }\n\n  public void setCrl(String crl) {\n    this.crl = crl;\n  }\n\n  public String getProtocols() {\n    return protocols;\n  }\n\n  public String getCiphers() {\n    return ciphers;\n  }\n\n  public boolean isAuthPeer() {\n    return authPeer;\n  }\n\n  public boolean isCheckCNHost() {\n    return checkCNHost;\n  }\n\n  public boolean isCheckCNWhite() {\n    return checkCNWhite;\n  }\n\n  public String getCheckCNWhiteFile() {\n    return checkCNWhiteFile;\n  }\n\n  public boolean isAllowRenegotiate() {\n    return allowRenegotiate;\n  }\n\n  public String getStorePath() {\n    return storePath;\n  }\n\n  public String getClientAuth() {\n    return this.clientAuth;\n  }\n\n  public void setClientAuth(String clientAuth) {\n    this.clientAuth = clientAuth;\n  }\n\n  public String getTrustStore() {\n    return trustStore;\n  }\n\n  public String getTrustStoreType() {\n    return trustStoreType;\n  }\n\n  public String getTrustStoreValue() {\n    return trustStoreValue;\n  }\n\n  public String getKeyStore() {\n    return keyStore;\n  }\n\n  public String getKeyStoreType() {\n    return keyStoreType;\n  }\n\n  public String getKeyStoreValue() {\n    return keyStoreValue;\n  }\n\n  public String getCrl() {\n    return crl;\n  }\n\n  public static SSLOption build(String optionfile) {\n    File file = new File(optionfile);\n    if (!file.isFile()) {\n      throw new IllegalArgumentException(\"Bad file name.\");\n    }\n\n    try {\n      SSLOption option = new SSLOption();\n      option.load(file.getCanonicalPath());\n      return option;\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\"Bad file name.\");\n    }\n  }\n\n  public static SSLOption build(InputStream inputStream) {\n    SSLOption option = new SSLOption();\n    option.load(inputStream);\n    return option;\n  }\n\n  public static String getStringProperty(Environment environment, String defaultValue,\n      String... keys) {\n    String property = null;\n    for (String key : keys) {\n      property = environment.getProperty(key);\n      if (property != null) {\n        break;\n      }\n    }\n\n    if (property != null) {\n      return property;\n    } else {\n      return defaultValue;\n    }\n  }\n\n  private static boolean getBooleanProperty(Environment environment, boolean defaultValue,\n      String... keys) {\n    String property = null;\n    for (String key : keys) {\n      property = environment.getProperty(key);\n      if (property != null) {\n        break;\n      }\n    }\n\n    if (property != null) {\n      return Boolean.parseBoolean(property);\n    } else {\n      return defaultValue;\n    }\n  }\n\n  public static SSLOption build(String tag, Environment environment) {\n    SSLOption option = new SSLOption();\n    option.engine = getStringProperty(environment,\n        DEFAULT_OPTION.getEngine(),\n        \"ssl.\" + tag + \".engine\",\n        \"ssl.engine\");\n    option.protocols =\n        getStringProperty(environment,\n            DEFAULT_OPTION.getProtocols(),\n            \"ssl.\" + tag + \".protocols\",\n            \"ssl.protocols\");\n    option.ciphers =\n        getStringProperty(environment, DEFAULT_OPTION.getCiphers(), \"ssl.\" + tag + \".ciphers\", \"ssl.ciphers\");\n    option.authPeer =\n        getBooleanProperty(environment, DEFAULT_OPTION.isAuthPeer(), \"ssl.\" + tag + \".authPeer\", \"ssl.authPeer\");\n    option.checkCNHost =\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNHost(),\n            \"ssl.\" + tag + \".checkCN.host\",\n            \"ssl.checkCN.host\");\n    option.checkCNWhite =\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNWhite(),\n            \"ssl.\" + tag + \".checkCN.white\",\n            \"ssl.checkCN.white\");\n    option.checkCNWhiteFile = getStringProperty(environment,\n        DEFAULT_OPTION.getCiphers(),\n        \"ssl.\" + tag + \".checkCN.white.file\",\n        \"ssl.checkCN.white.file\");\n    option.allowRenegotiate = getBooleanProperty(environment,\n        DEFAULT_OPTION.isAllowRenegotiate(),\n        \"ssl.\" + tag + \".allowRenegotiate\",\n        \"ssl.allowRenegotiate\");\n    option.storePath =\n        getStringProperty(environment,\n            DEFAULT_OPTION.getStorePath(),\n            \"ssl.\" + tag + \".storePath\",\n            \"ssl.storePath\");\n    option.clientAuth =\n        getStringProperty(environment,\n            DEFAULT_OPTION.getClientAuth(),\n            \"ssl.\" + tag + \".storePath\",\n            \"ssl.clientAuth\");\n    option.trustStore =\n        getStringProperty(environment,\n            DEFAULT_OPTION.getTrustStore(),\n            \"ssl.\" + tag + \".trustStore\",\n            \"ssl.trustStore\");\n    option.trustStoreType = getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreType(),\n        \"ssl.\" + tag + \".trustStoreType\",\n        \"ssl.trustStoreType\");\n    option.trustStoreValue = getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreValue(),\n        \"ssl.\" + tag + \".trustStoreValue\",\n        \"ssl.trustStoreValue\");\n    option.keyStore =\n        getStringProperty(environment, DEFAULT_OPTION.getKeyStore(), \"ssl.\" + tag + \".keyStore\", \"ssl.keyStore\");\n    option.keyStoreType =\n        getStringProperty(environment,\n            DEFAULT_OPTION.getKeyStoreType(),\n            \"ssl.\" + tag + \".keyStoreType\",\n            \"ssl.keyStoreType\");\n    option.keyStoreValue = getStringProperty(environment,\n        DEFAULT_OPTION.getKeyStoreValue(),\n        \"ssl.\" + tag + \".keyStoreValue\",\n        \"ssl.keyStoreValue\");\n    option.crl = getStringProperty(environment, DEFAULT_OPTION.getCrl(), \"ssl.\" + tag + \".crl\", \"ssl.crl\");\n    option.sslCustomClass =\n        getStringProperty(environment, null, \"ssl.\" + tag + \".sslCustomClass\", \"ssl.sslCustomClass\");\n    return option;\n  }\n\n  private void fromProperty(Properties props) {\n    this.protocols = propString(props, \"ssl.protocols\");\n    this.ciphers = propString(props, \"ssl.ciphers\");\n    this.authPeer = propBoolean(props, \"ssl.authPeer\");\n    this.checkCNHost = propBoolean(props, \"ssl.checkCN.host\");\n    this.checkCNWhite = propBoolean(props, \"ssl.checkCN.white\");\n    this.checkCNWhiteFile = propString(props, \"ssl.checkCN.white.file\");\n    this.allowRenegotiate = propBoolean(props, \"ssl.allowRenegotiate\");\n    this.storePath = propString(props, \"ssl.storePath\");\n    this.clientAuth = propString(props, \"ssl.clientAuth\", false);\n    this.trustStore = propString(props, \"ssl.trustStore\");\n    this.trustStoreType = propString(props, \"ssl.trustStoreType\");\n    this.trustStoreValue = propString(props, \"ssl.trustStoreValue\");\n    this.keyStore = propString(props, \"ssl.keyStore\");\n    this.keyStoreType = propString(props, \"ssl.keyStoreType\");\n    this.keyStoreValue = propString(props, \"ssl.keyStoreValue\");\n    this.crl = propString(props, \"ssl.crl\");\n    this.sslCustomClass = props.getProperty(\"ssl.sslCustomClass\");\n  }\n\n  private String propString(Properties props, String key) {\n    return propString(props, key, true);\n  }\n\n  private String propString(Properties props, String key, boolean required) {\n    String s = props.getProperty(key);\n    if (s == null && required) {\n      throw new IllegalArgumentException(\"No key :\" + key);\n    }\n    return s;\n  }\n\n  private boolean propBoolean(Properties props, String key) {\n    String s = props.getProperty(key);\n    if (s == null) {\n      throw new IllegalArgumentException(\"No key :\" + key);\n    }\n    return Boolean.parseBoolean(s);\n  }\n\n  private void load(InputStream inputStream) {\n    Properties props = new Properties();\n    Reader reader = null;\n    try {\n      reader =\n          new InputStreamReader(inputStream, StandardCharsets.UTF_8);\n      props.load(reader);\n      fromProperty(props);\n    } catch (IOException e) {\n      throw new IllegalArgumentException(\n          \"Can not read ssl client config file\");\n    } finally {\n      if (reader != null) {\n        try {\n          reader.close();\n        } catch (IOException e) {\n          ignore();\n        }\n      }\n\n      if (inputStream != null) {\n        try {\n          inputStream.close();\n        } catch (IOException e) {\n          ignore();\n        }\n      }\n    }\n  }\n\n  // visible for testing\n  void load(String path) {\n    try {\n      load(new FileInputStream(path));\n    } catch (FileNotFoundException e) {\n      throw new IllegalArgumentException(\n          \"Can not read ssl client config file: \" + path);\n    }\n  }\n\n  private void ignore() {\n  }\n\n  public String getSslCustomClass() {\n    return this.sslCustomClass;\n  }\n\n  public void setSslCustomClass(String sslCustomClass) {\n    this.sslCustomClass = sslCustomClass;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOptionFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport org.springframework.core.env.Environment;\n\npublic interface SSLOptionFactory {\n  static SSLOptionFactory createSSLOptionFactory(String tag, Environment environment) {\n    String name = SSLOption.getStringProperty(environment,\n        null,\n        \"ssl.\" + tag + \".sslOptionFactory\",\n        \"ssl.sslOptionFactory\");\n    return createSSLOptionFactory(name);\n  }\n\n  static SSLOptionFactory createSSLOptionFactory(String className) {\n    if (className != null && !className.isEmpty()) {\n      try {\n        return (SSLOptionFactory) Class.forName(className).getDeclaredConstructor().newInstance();\n      } catch (ReflectiveOperationException e) {\n        throw new IllegalStateException(\"Failed to create SSLOptionFactory.\", e);\n      }\n    }\n    return null;\n  }\n\n  SSLOption createSSLOption();\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLSocketFactoryExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\n\n/**\n * 扩展SSLSocketFactory，设置算法和协议列表。\n *\n */\npublic class SSLSocketFactoryExt extends SSLSocketFactory {\n  private final SSLSocketFactory sslSocketFactory;\n\n  private final String[] ciphers;\n\n  private final String[] protos;\n\n  public SSLSocketFactoryExt(SSLSocketFactory factory, String[] ciphers, String[] protos) {\n    this.sslSocketFactory = factory;\n    this.ciphers = ciphers;\n    this.protos = protos;\n  }\n\n  @Override\n  public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {\n    return wrapSocket((SSLSocket) this.sslSocketFactory.createSocket(s, host, port, autoClose));\n  }\n\n  @Override\n  public String[] getDefaultCipherSuites() {\n    return this.sslSocketFactory.getDefaultCipherSuites();\n  }\n\n  @Override\n  public String[] getSupportedCipherSuites() {\n    return this.sslSocketFactory.getSupportedCipherSuites();\n  }\n\n  @Override\n  public Socket createSocket(String host, int port) throws IOException, UnknownHostException {\n    return wrapSocket((SSLSocket) this.sslSocketFactory.createSocket(host, port));\n  }\n\n  @Override\n  public Socket createSocket(InetAddress host, int port) throws IOException {\n    return wrapSocket((SSLSocket) this.sslSocketFactory.createSocket(host, port));\n  }\n\n  @Override\n  public Socket createSocket(String host, int port, InetAddress localHost,\n      int localPort) throws IOException, UnknownHostException {\n    return wrapSocket((SSLSocket) this.sslSocketFactory.createSocket(host,\n        port,\n        localHost,\n        localPort));\n  }\n\n  @Override\n  public Socket createSocket(InetAddress address, int port, InetAddress localAddress,\n      int localPort) throws IOException {\n    return wrapSocket((SSLSocket) this.sslSocketFactory.createSocket(address,\n        port,\n        localAddress,\n        localPort));\n  }\n\n  private SSLSocket wrapSocket(SSLSocket socket) {\n    socket.setEnabledProtocols(protos);\n    socket.setEnabledCipherSuites(ciphers);\n    return socket;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/TrustAllManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.net.Socket;\nimport java.security.cert.CertificateException;\nimport java.security.cert.X509Certificate;\n\nimport javax.net.ssl.SSLEngine;\nimport javax.net.ssl.X509ExtendedTrustManager;\n\n/** it is not secure */\npublic class TrustAllManager extends X509ExtendedTrustManager {\n\n  @Override\n  public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {\n  }\n\n  @Override\n  public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {\n  }\n\n  @Override\n  public X509Certificate[] getAcceptedIssuers() {\n    return null;\n  }\n\n  @Override\n  public void checkClientTrusted(X509Certificate[] chain, String authType,\n      Socket socket) throws CertificateException {\n  }\n\n  @Override\n  public void checkClientTrusted(X509Certificate[] chain, String authType,\n      SSLEngine engine) throws CertificateException {\n  }\n\n  @Override\n  public void checkServerTrusted(X509Certificate[] chain, String authType,\n      Socket socket) throws CertificateException {\n  }\n\n  @Override\n  public void checkServerTrusted(X509Certificate[] chain, String authType,\n      SSLEngine engine) throws CertificateException {\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/TrustManagerExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.net.InetAddress;\nimport java.net.NetworkInterface;\nimport java.net.Socket;\nimport java.net.SocketException;\nimport java.nio.charset.StandardCharsets;\nimport java.security.cert.CRL;\nimport java.security.cert.CertificateException;\nimport java.security.cert.X509Certificate;\nimport java.util.Enumeration;\nimport java.util.Set;\n\nimport javax.net.ssl.SSLEngine;\nimport javax.net.ssl.SSLSession;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.X509ExtendedTrustManager;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * 扩展TurstManager\n *\n */\npublic class TrustManagerExt extends X509ExtendedTrustManager {\n  private static final Logger LOG = LoggerFactory.getLogger(TrustManagerExt.class);\n\n  private static final int WHITE_SIZE = 1024;\n\n  private final X509ExtendedTrustManager trustManager;\n\n  private final SSLOption option;\n\n  private final SSLCustom custom;\n\n  public TrustManagerExt(X509ExtendedTrustManager manager, SSLOption option,\n      SSLCustom custom) {\n    this.trustManager = manager;\n    this.option = option;\n    this.custom = custom;\n  }\n\n  @Override\n  public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {\n    if (!option.isAuthPeer()) {\n      return;\n    }\n\n    checkTrustedCustom(chain, null);\n    trustManager.checkClientTrusted(chain, authType);\n  }\n\n  @Override\n  public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {\n    if (!option.isAuthPeer()) {\n      return;\n    }\n\n    checkTrustedCustom(chain, null);\n    trustManager.checkServerTrusted(chain, authType);\n  }\n\n  @Override\n  public X509Certificate[] getAcceptedIssuers() {\n    return trustManager.getAcceptedIssuers();\n  }\n\n  @Override\n  public void checkClientTrusted(X509Certificate[] chain, String authType,\n      Socket socket) throws CertificateException {\n    if (!option.isAuthPeer()) {\n      return;\n    }\n\n    String ip = null;\n    if (socket != null && socket.isConnected()\n        && socket instanceof SSLSocket) {\n      InetAddress inetAddress = socket.getInetAddress();\n      if (inetAddress != null) {\n        ip = inetAddress.getHostAddress();\n      }\n    }\n    checkTrustedCustom(chain, ip);\n    trustManager.checkClientTrusted(chain, authType, socket);\n  }\n\n  @Override\n  public void checkClientTrusted(X509Certificate[] chain, String authType,\n      SSLEngine engine) throws CertificateException {\n    if (!option.isAuthPeer()) {\n      return;\n    }\n\n    String ip = null;\n    if (engine != null) {\n      SSLSession session = engine.getHandshakeSession();\n      ip = session.getPeerHost();\n    }\n    checkTrustedCustom(chain, ip);\n    trustManager.checkClientTrusted(chain, authType, engine);\n  }\n\n  @Override\n  public void checkServerTrusted(X509Certificate[] chain, String authType,\n      Socket socket) throws CertificateException {\n    if (!option.isAuthPeer()) {\n      return;\n    }\n\n    String ip = null;\n    if (socket != null && socket.isConnected()\n        && socket instanceof SSLSocket) {\n      InetAddress inetAddress = socket.getInetAddress();\n      if (inetAddress != null) {\n        ip = inetAddress.getHostAddress();\n      }\n    }\n    checkTrustedCustom(chain, ip);\n    trustManager.checkServerTrusted(chain, authType, socket);\n  }\n\n  @Override\n  public void checkServerTrusted(X509Certificate[] chain, String authType,\n      SSLEngine engine) throws CertificateException {\n    if (!option.isAuthPeer()) {\n      return;\n    }\n\n    String ip = null;\n    if (engine != null) {\n      SSLSession session = engine.getHandshakeSession();\n      ip = session.getPeerHost();\n    }\n    checkTrustedCustom(chain, ip);\n    trustManager.checkServerTrusted(chain, authType, engine);\n  }\n\n  private void checkTrustedCustom(X509Certificate[] chain, String ip) throws CertificateException {\n    checkCNHost(chain, ip);\n    checkCNWhite(chain);\n    checkCRL(chain);\n  }\n\n  // ? : learn java default / apache CN check\n  private void checkCNHost(X509Certificate[] chain, String ip) throws CertificateException {\n    if (option.isCheckCNHost()) {\n      X509Certificate owner = CertificateUtil.findOwner(chain);\n      Set<String> cns = CertificateUtil.getCN(owner);\n      String ipTmp = ip == null ? custom.getHost() : ip;\n      // 从本机来的请求， 只要CN与本机的任何一个IP地址匹配即可\n      if (\"127.0.0.1\".equals(ipTmp)) {\n        try {\n          Enumeration<NetworkInterface> interfaces =\n              NetworkInterface.getNetworkInterfaces();\n          if (interfaces != null) {\n            while (interfaces.hasMoreElements()) {\n              NetworkInterface nif = interfaces.nextElement();\n              Enumeration<InetAddress> ias = nif.getInetAddresses();\n              while (ias.hasMoreElements()) {\n                InetAddress ia = ias.nextElement();\n                String local = ia.getHostAddress();\n                if (cnValid(cns, local)) {\n                  return;\n                }\n              }\n            }\n          }\n        } catch (SocketException e) {\n          throw new CertificateException(\"Get local address fail.\");\n        }\n      } else if (cnValid(cns, ipTmp)) {\n        return;\n      }\n      LOG.error(\"CN does not match IP: e=\" + cns\n          + \",t=\" + ip);\n      throw new CertificateException(\"CN does not match IP: e=\" + cns\n          + \",t=\" + ip);\n    }\n  }\n\n  private boolean cnValid(Set<String> certsCN, String srcCN) {\n    for (String cert : certsCN) {\n      if (cert.equals(srcCN)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  private void checkCNWhite(X509Certificate[] chain) throws CertificateException {\n    if (option.isCheckCNWhite()) {\n      FileInputStream fis = null;\n      InputStreamReader reader = null;\n      try {\n        String white = option.getCheckCNWhiteFile();\n        white = custom.getFullPath(white);\n        fis = new FileInputStream(white);\n        reader = new InputStreamReader(fis, StandardCharsets.UTF_8);\n        char[] buffer = new char[WHITE_SIZE];\n        int len = reader.read(buffer);\n        String[] cns = new String(buffer, 0, len).split(\"\\\\s+\");\n        X509Certificate owner = CertificateUtil.findOwner(chain);\n        Set<String> certCN = CertificateUtil.getCN(owner);\n        for (String c : cns) {\n          if (cnValid(certCN, c)) {\n            return;\n          }\n        }\n      } catch (FileNotFoundException e) {\n        throw new CertificateException(\n            \"CN does not match white. no white file.\");\n      } catch (IOException e) {\n        throw new CertificateException(\n            \"CN does not match white. can not read file.\");\n      } finally {\n        try {\n          if (reader != null) {\n            reader.close();\n          }\n        } catch (IOException e) {\n          ignore();\n        }\n        try {\n          if (fis != null) {\n            fis.close();\n          }\n        } catch (IOException e) {\n          ignore();\n        }\n      }\n\n      LOG.error(\"CN does not match white.\");\n      throw new CertificateException(\"CN does not match white.\");\n    }\n  }\n\n  private void checkCRL(X509Certificate[] chain) throws CertificateException {\n    String crl = option.getCrl();\n    crl = custom.getFullPath(crl);\n    File file = new File(crl);\n    if (!file.exists()) {\n      return;\n    }\n\n    CRL[] crls = KeyStoreUtil.createCRL(crl);\n    X509Certificate owner = CertificateUtil.findOwner(chain);\n    for (CRL c : crls) {\n      if (c.isRevoked(owner)) {\n        LOG.error(\"certificate revoked\");\n        throw new CertificateException(\"certificate revoked\");\n      }\n    }\n  }\n\n  private static void ignore() {\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/CertificateUtilTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.math.BigInteger;\nimport java.security.InvalidKeyException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.NoSuchProviderException;\nimport java.security.Principal;\nimport java.security.PublicKey;\nimport java.security.SignatureException;\nimport java.security.cert.CertificateEncodingException;\nimport java.security.cert.CertificateException;\nimport java.security.cert.CertificateExpiredException;\nimport java.security.cert.CertificateNotYetValidException;\nimport java.security.cert.X509Certificate;\nimport java.util.Date;\nimport java.util.Set;\n\nimport javax.security.auth.x500.X500Principal;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport mockit.Expectations;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class CertificateUtilTest {\n  @SuppressWarnings(\"deprecation\")\n  static class MyX509Certificate extends X509Certificate {\n    private static final long serialVersionUID = -3585440601605666278L;\n\n    public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {\n    }\n\n    @Override\n    public boolean hasUnsupportedCriticalExtension() {\n      return false;\n    }\n\n    @Override\n    public Set<String> getCriticalExtensionOIDs() {\n      return null;\n    }\n\n    @Override\n    public Set<String> getNonCriticalExtensionOIDs() {\n      return null;\n    }\n\n    @Override\n    public byte[] getExtensionValue(String oid) {\n      return null;\n    }\n\n    @Override\n    public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {\n    }\n\n    @Override\n    public int getVersion() {\n      return 0;\n    }\n\n    @Override\n    public BigInteger getSerialNumber() {\n      return null;\n    }\n\n    @Override\n    public Principal getIssuerDN() {\n      return null;\n    }\n\n    @Override\n    public Principal getSubjectDN() {\n      return null;\n    }\n\n    @Override\n    public Date getNotBefore() {\n      return null;\n    }\n\n    @Override\n    public Date getNotAfter() {\n      return null;\n    }\n\n    @Override\n    public byte[] getTBSCertificate() throws CertificateEncodingException {\n      return null;\n    }\n\n    @Override\n    public byte[] getSignature() {\n      return null;\n    }\n\n    @Override\n    public String getSigAlgName() {\n      return null;\n    }\n\n    @Override\n    public String getSigAlgOID() {\n      return null;\n    }\n\n    @Override\n    public byte[] getSigAlgParams() {\n      return null;\n    }\n\n    @Override\n    public boolean[] getIssuerUniqueID() {\n      return null;\n    }\n\n    @Override\n    public boolean[] getSubjectUniqueID() {\n      return null;\n    }\n\n    @Override\n    public boolean[] getKeyUsage() {\n      return null;\n    }\n\n    @Override\n    public int getBasicConstraints() {\n      return 0;\n    }\n\n    @Override\n    public byte[] getEncoded() throws CertificateEncodingException {\n      return null;\n    }\n\n    @Override\n    public void verify(PublicKey key)\n        throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,\n        SignatureException {\n\n    }\n\n    @Override\n    public void verify(PublicKey key, String sigProvider)\n        throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,\n        SignatureException {\n    }\n\n    @Override\n    public String toString() {\n      return null;\n    }\n\n    @Override\n    public PublicKey getPublicKey() {\n      return null;\n    }\n  }\n\n  @Before\n  public void setUp() {\n  }\n\n  @After\n  public void tearDown() {\n  }\n\n  @Test\n  public void testGetCN(@Mocked X500Principal aX500Principal, @Mocked MyX509Certificate myX509Certificate) {\n    new Expectations() {\n      {\n        aX500Principal.getName();\n        result = \"CN=Test1234\";\n        myX509Certificate.getSubjectX500Principal();\n        result = aX500Principal;\n      }\n    };\n\n    MyX509Certificate xxmyX509Certificate = new MyX509Certificate();\n    Set<String> strExpect = CertificateUtil.getCN(xxmyX509Certificate);\n\n    Assertions.assertTrue(strExpect.contains(\"Test1234\"));\n  }\n\n  @Test\n  public void testGetCNException(@Mocked X500Principal aX500Principal,\n      @Mocked MyX509Certificate myX509Certificate) {\n    new Expectations() {\n      {\n        aX500Principal.getName();\n        result = \"NOCN=Test1234\";\n        myX509Certificate.getSubjectX500Principal();\n        result = aX500Principal;\n      }\n    };\n\n    MyX509Certificate xxmyX509Certificate = new MyX509Certificate();\n\n    try {\n      Set<String> strExpect = CertificateUtil.getCN(xxmyX509Certificate);\n      Assertions.assertEquals(strExpect.size(), 0);\n    } catch (IllegalArgumentException e) {\n      Assertions.assertNotNull(null);\n    }\n  }\n\n  @Test\n  public void testFindOwner(@Mocked X500Principal aX500Principal1, @Mocked X500Principal aX500Principal2,\n      @Mocked MyX509Certificate myX509Certificate) {\n    new Expectations() {\n      {\n        aX500Principal1.getName();\n        result = \"Huawei\";\n      }\n\n      {\n        aX500Principal2.getName();\n        result = \"Huawei\";\n      }\n\n      {\n        myX509Certificate.getSubjectX500Principal();\n        result = aX500Principal1;\n\n        myX509Certificate.getIssuerX500Principal();\n        result = aX500Principal2;\n      }\n    };\n\n    MyX509Certificate myX509Certificate1 = new MyX509Certificate();\n    MyX509Certificate myX509Certificate2 = new MyX509Certificate();\n\n    MyX509Certificate[] xxmyX509Certificate = new MyX509Certificate[2];\n    xxmyX509Certificate[0] = myX509Certificate1;\n    xxmyX509Certificate[1] = myX509Certificate2;\n\n    X509Certificate aX509Certificate = CertificateUtil.findOwner(xxmyX509Certificate);\n    Assertions.assertNull(aX509Certificate);\n  }\n\n  @Test\n  public void testFindRootCAException(@Mocked X500Principal aX500Principal1, @Mocked X500Principal aX500Principal2,\n      @Mocked MyX509Certificate myX509Certificate) {\n    new Expectations() {\n      {\n        aX500Principal1.getName();\n        result = \"Huawei1\";\n      }\n\n      {\n        aX500Principal2.getName();\n        result = \"Huawei3\";\n      }\n\n      {\n        myX509Certificate.getSubjectX500Principal();\n        result = aX500Principal1;\n\n        myX509Certificate.getIssuerX500Principal();\n        result = aX500Principal2;\n      }\n    };\n\n    MyX509Certificate myX509Certificate1 = new MyX509Certificate();\n    MyX509Certificate myX509Certificate2 = new MyX509Certificate();\n\n    MyX509Certificate[] xxmyX509Certificate = new MyX509Certificate[2];\n    xxmyX509Certificate[0] = myX509Certificate1;\n    xxmyX509Certificate[1] = myX509Certificate2;\n\n    try {\n      X509Certificate aX509Certificate = CertificateUtil.findOwner(xxmyX509Certificate);\n      Assertions.assertNull(aX509Certificate);\n    } catch (IllegalArgumentException e) {\n      Assertions.assertEquals(\"bad certificate chain: no root CA.\", e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/KeyStoreUtilTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.FileNotFoundException;\nimport java.io.InputStream;\nimport java.security.KeyStore;\nimport java.security.cert.CRL;\nimport java.security.cert.CRLException;\nimport java.security.cert.CertificateException;\nimport java.security.cert.CertificateFactory;\nimport java.util.Collection;\n\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport mockit.Mock;\nimport mockit.MockUp;\nimport org.mockito.Mockito;\n\npublic class KeyStoreUtilTest {\n  final String strFilePath = Thread.currentThread().getContextClassLoader().getResource(\"\").getPath();\n\n  @Test\n  public void testCreateKeyStoreException() {\n    String storename = \"\";\n    String storetype = \"testType\";\n    char[] storevalue = \"Changeme_123\".toCharArray();\n\n    try {\n      KeyStoreUtil.createKeyStore(storename, storetype, storevalue);\n    } catch (IllegalArgumentException e) {\n      Assertions.assertEquals(\"Bad key store or value.testType not found\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testCreateKeyStoreException2() {\n    String storename = strFilePath + \"/ssl/trust.jks\";\n    String storetype = \"PKCS12\";\n    char[] storevalue = \"Changeme_123\".toCharArray();\n\n    try {\n      KeyStoreUtil.createKeyStore(storename, storetype, storevalue);\n    } catch (IllegalArgumentException e) {\n      Assertions.assertEquals(\"Bad key store or value.DerInputStream.getLength(): lengthTag=109, too big.\",\n          e.getMessage());\n    }\n  }\n\n  @Test\n  public void testCreateKeyManagersException() {\n    KeyStore keystore;\n\n    String storename = strFilePath + \"/ssl/server.p12\";\n    String storetype = \"PKCS12\";\n    char[] storevalue = \"Changeme_123\".toCharArray();\n\n    keystore = KeyStoreUtil.createKeyStore(storename, storetype, storevalue);\n\n    char[] storeKeyValue = null;\n    try {\n      KeyStoreUtil.createKeyManagers(keystore, storeKeyValue);\n    } catch (IllegalArgumentException e) {\n        Assertions.assertEquals(\"Bad key store.Get Key failed:\"\n                        + \" Cannot read the array length because \\\"password\\\" is null\",\n                e.getMessage());\n    }\n  }\n\n  @Test\n  public void testCreateCRL() {\n    String crlfile = strFilePath + \"/ssl/server.p12\";\n    mockGenerateCRLs();\n    boolean validAssert = true;\n    try {\n      CRL[] crl = KeyStoreUtil.createCRL(crlfile);\n      Assertions.assertNull(crl);\n    } catch (Exception e) {\n      validAssert = false;\n    }\n    Assertions.assertTrue(validAssert);\n  }\n\n  @Test\n  public void testCreateCRLException() {\n    String crlfile = strFilePath + \"/ssl/server.p12\";\n    boolean validAssert = true;\n    try {\n      new MockUp<CertificateFactory>() {\n        @Mock\n        public CertificateFactory getInstance(String type) throws CertificateException {\n          throw new CertificateException();\n        }\n      };\n\n      KeyStoreUtil.createCRL(crlfile);\n    } catch (Exception e) {\n      validAssert = false;\n    }\n    Assertions.assertFalse(validAssert);\n  }\n\n  @Test\n  public void testExceptionFileNotFound() {\n    String crlfile = strFilePath + \"/ssl/server.p12\";\n    boolean validAssert = true;\n    try {\n      new MockUp<CertificateFactory>() {\n        @Mock\n        public CertificateFactory getInstance(\n            String type) throws CertificateException, FileNotFoundException {\n          throw new FileNotFoundException();\n        }\n      };\n      KeyStoreUtil.createCRL(crlfile);\n    } catch (Exception e) {\n      validAssert = false;\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n    Assertions.assertFalse(validAssert);\n  }\n\n  @Test\n  public void testExceptionCRLException() {\n    String crlfile = strFilePath + \"/ssl/server.p12\";\n    boolean validAssert = true;\n    try {\n      new MockUp<CertificateFactory>() {\n        @Mock\n        public CertificateFactory getInstance(String type) throws CertificateException, CRLException {\n          throw new CRLException();\n        }\n      };\n      KeyStoreUtil.createCRL(crlfile);\n    } catch (Exception e) {\n      validAssert = false;\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n    Assertions.assertFalse(validAssert);\n  }\n\n  private void mockGenerateCRLs() {\n    new MockUp<CertificateFactory>() {\n      @SuppressWarnings(\"unchecked\")\n      @Mock\n      public Collection<? extends CRL> generateCRLs(InputStream inStream) throws CRLException {\n        return Mockito.mock(Collection.class);\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/MyOptionFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\npublic class MyOptionFactory implements SSLOptionFactory {\n\n  @Override\n  public SSLOption createSSLOption() {\n    SSLOption option = new SSLOption();\n    option.setProtocols(\"TLSv1.2\");\n    option.setCiphers(\"TLS_RSA_WITH_AES_128_CBC_SHA256\");\n    option.setAuthPeer(false);\n    option.setCheckCNHost(false);\n    option.setCheckCNWhite(false);\n    option.setCheckCNWhiteFile(\"white.list\");\n    return option;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/SSLManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.IOException;\nimport java.net.Inet4Address;\nimport java.net.InetAddress;\nimport java.net.InetSocketAddress;\nimport java.net.NetworkInterface;\nimport java.net.UnknownHostException;\nimport java.security.KeyManagementException;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.Enumeration;\n\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLEngine;\nimport javax.net.ssl.SSLServerSocket;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\n\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class SSLManagerTest {\n  private final String DIR = Thread.currentThread().getContextClassLoader().getResource(\"\").getPath();\n\n  @Test\n  public void testSSLManagerServerAndClient(final @Mocked NetworkInterface nif) throws Exception {\n    final InetAddress ia = Inet4Address.getByName(\"10.57.65.225\");\n    final Enumeration<NetworkInterface> interfaces = new Enumeration<NetworkInterface>() {\n      final int count = 1;\n\n      int cur = 0;\n\n      @Override\n      public boolean hasMoreElements() {\n        if (cur < count) {\n          cur++;\n          return true;\n        }\n        return false;\n      }\n\n      @Override\n      public NetworkInterface nextElement() {\n        return nif;\n      }\n    };\n\n    final Enumeration<InetAddress> ias = new Enumeration<InetAddress>() {\n      final int count = 1;\n\n      int cur = 0;\n\n      @Override\n      public boolean hasMoreElements() {\n        if (cur < count) {\n          cur++;\n          return true;\n        }\n        return false;\n      }\n\n      @Override\n      public InetAddress nextElement() {\n        return ia;\n      }\n    };\n\n    new Expectations() {\n      @Mocked\n      NetworkInterface nif;\n\n      {\n        NetworkInterface.getNetworkInterfaces();\n        result = interfaces;\n      }\n    };\n    new Expectations() {\n      {\n        nif.getInetAddresses();\n        result = ias;\n        ia.getHostAddress();\n        result = \"10.57.65.225\";\n      }\n    };\n\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n    final SSLServerSocket serverSocket = SSLManager.createSSLServerSocket(option, custom);\n    Assertions.assertTrue(serverSocket.getNeedClientAuth());\n    serverSocket.bind(new InetSocketAddress(\"127.0.0.1\", 8886));\n    String[] protos = serverSocket.getEnabledCipherSuites();\n    String[] protosExpected =\n        \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\"\n            .split(\",\");\n    Assertions.assertArrayEquals(protos, protosExpected);\n    String[] ciphers = serverSocket.getEnabledCipherSuites();\n    String[] ciphersExpected =\n        \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\"\n            .split(\",\");\n    Assertions.assertArrayEquals(ciphers, ciphersExpected);\n    Assertions.assertTrue(serverSocket.getNeedClientAuth());\n\n    SSLOption clientoption = SSLOption.build(DIR + \"/client.ssl.properties\");\n    SSLSocket clientsocket = SSLManager.createSSLSocket(clientoption, custom);\n    String[] clientprotos = clientsocket.getEnabledCipherSuites();\n    String[] clientprotosExpected =\n        \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\"\n            .split(\",\");\n    Assertions.assertArrayEquals(clientprotos, clientprotosExpected);\n    String[] clientciphers = clientsocket.getEnabledCipherSuites();\n    String[] clientciphersExpected =\n        \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\"\n            .split(\",\");\n    Assertions.assertArrayEquals(clientciphers, clientciphersExpected);\n    Assertions.assertFalse(clientsocket.getNeedClientAuth());\n    boolean validAssert = true;\n    try {\n      clientsocket.connect(new InetSocketAddress(\"127.0.0.1\", 8886));\n\n      new Thread(() -> {\n\n        try {\n          SSLSocket s = (SSLSocket) serverSocket.accept();\n          s.addHandshakeCompletedListener(arg0 -> {\n\n          });\n          s.getOutputStream().write(new byte[] {0, 1});\n        } catch (IOException e) {\n          e.printStackTrace();\n           Assertions.fail(\"this should not happen\");\n        }\n      }).start();\n\n      clientsocket.startHandshake();\n      clientsocket.close();\n      serverSocket.close();\n\n      // socked successfully opened and closed\n    } catch (Exception e) {\n      e.printStackTrace();\n      validAssert = false;\n    }\n    Assertions.assertTrue(validAssert);\n  }\n\n  @Test\n  public void testCreateSSLEngine() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    SSLEngine aSSLEngine = SSLManager.createSSLEngine(option, custom);\n    // if client mode may not decided at initialization. Different JDK is different, do not check it.\n    // Assertions.assertEquals(false, aSSLEngine.getUseClientMode());\n    Assertions.assertTrue(aSSLEngine.getNeedClientAuth());\n  }\n\n  @Test\n  public void testCreateSSLEngineClientAuthNone() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n    option.setClientAuth(\"NONE\");\n    option.setAuthPeer(false);\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    SSLEngine aSSLEngine = SSLManager.createSSLEngine(option, custom);\n    // if client mode may not decided at initialization. Different JDK is different, do not check it.\n    // Assertions.assertEquals(false, aSSLEngine.getUseClientMode());\n    Assertions.assertFalse(aSSLEngine.getNeedClientAuth());\n    Assertions.assertFalse(aSSLEngine.getWantClientAuth());\n  }\n\n  @Test\n  public void testCreateSSLEnginewithPort() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    int port = 39093;\n    String peerHost = \"host1\";\n    SSLEngine aSSLEngine = SSLManager.createSSLEngine(option, custom, peerHost, port);\n    Assertions.assertNotNull(aSSLEngine);\n    Assertions.assertEquals(\"host1\", aSSLEngine.getPeerHost());\n  }\n\n  @Test\n  public void testCreateSSLContextResource() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.resource.properties\");\n\n    SSLCustom custom = SSLCustom.defaultSSLCustom();\n\n    SSLContext context = SSLManager.createSSLContext(option, custom);\n    Assertions.assertNotNull(context);\n  }\n\n  @Test\n  public void testCreateSSLContextException() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    new MockUp<SSLContext>() {\n      @Mock\n      public SSLContext getInstance(String type) throws NoSuchAlgorithmException {\n        throw new NoSuchAlgorithmException();\n      }\n    };\n\n    try {\n      SSLManager.createSSLContext(option, custom);\n      Assertions.assertNotNull(null);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testCreateSSLContextKeyManagementException() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    new MockUp<SSLContext>() {\n      @Mock\n      public SSLContext getInstance(String type) throws KeyManagementException {\n        throw new KeyManagementException();\n      }\n    };\n\n    try {\n      SSLManager.createSSLContext(option, custom);\n      Assertions.assertNotNull(null);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testCreateSSLServerSocketException() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    new MockUp<SSLContext>() {\n      @Mock\n      public SSLContext getInstance(String type) throws UnknownHostException {\n        throw new UnknownHostException();\n      }\n    };\n\n    try {\n      SSLManager.createSSLServerSocket(option, custom);\n\n      Assertions.assertNotNull(null);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testCreateSSLServerSocketIOException() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    new MockUp<SSLContext>() {\n      @Mock\n      public SSLContext getInstance(String type) throws IOException {\n        throw new IOException();\n      }\n    };\n\n    try {\n      SSLManager.createSSLServerSocket(option, custom);\n      Assertions.assertNotNull(null);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testCreateSSLSocketException() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    new MockUp<SSLContext>() {\n      @Mock\n      public SSLContext getInstance(String type) throws UnknownHostException {\n        throw new UnknownHostException();\n      }\n    };\n\n    try {\n      SSLManager.createSSLSocket(option, custom);\n      Assertions.assertNotNull(null);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testCreateSSLSocketIOException() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    new MockUp<SSLContext>() {\n      @Mock\n      public SSLContext getInstance(String type) throws IOException {\n        throw new IOException();\n      }\n    };\n\n    try {\n      SSLManager.createSSLSocket(option, custom);\n      Assertions.assertNotNull(null);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testCreateSSLSocketFactory() {\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n    SSLCustom custom = new SSLCustom() {\n      @Override\n      public String getFullPath(String filename) {\n        return DIR + \"/ssl/\" + filename;\n      }\n\n      @Override\n      public char[] decode(char[] encrypted) {\n        return encrypted;\n      }\n    };\n\n    SSLSocketFactory aSSLSocketFactory = SSLManager.createSSLSocketFactory(option, custom);\n    Assertions.assertNotNull(aSSLSocketFactory.getDefaultCipherSuites()[0]);\n  }\n\n  @Test\n  public void testGetSupportedCiphers() {\n    SSLOption option = new SSLOption();\n    option.setCiphers(\"TLS_RSA_WITH_AES_128_GCM_SHA256\");\n    option.setProtocols(\"TLSv1.2\");\n    String[] ciphers = SSLManager.getEnabledCiphers(option);\n    Assertions.assertEquals(ciphers[0], \"TLS_RSA_WITH_AES_128_GCM_SHA256\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/SSLOptionTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.Reader;\nimport java.net.URL;\nimport java.util.Properties;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class SSLOptionTest {\n  private static final String DIR = Thread.currentThread().getContextClassLoader().getResource(\"\").getPath();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() throws Exception {\n    Mockito.when(environment.getProperty(\"ssl.protocols\")).thenReturn(\"TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\");\n    Mockito.when(environment.getProperty(\"ssl.ciphers\")).thenReturn(\n        \"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256\");\n    Mockito.when(environment.getProperty(\"ssl.authPeer\")).thenReturn(\"true\");\n    Mockito.when(environment.getProperty(\"ssl.checkCN.host\")).thenReturn(\"true\");\n    Mockito.when(environment.getProperty(\"ssl.checkCN.white\")).thenReturn(\"true\");\n    Mockito.when(environment.getProperty(\"ssl.checkCN.white.file\")).thenReturn(\"white.list\");\n    Mockito.when(environment.getProperty(\"ssl.allowRenegotiate\")).thenReturn(\"false\");\n    Mockito.when(environment.getProperty(\"ssl.storePath\")).thenReturn(\"internal\");\n    Mockito.when(environment.getProperty(\"ssl.trustStore\")).thenReturn(\"trust.jks\");\n    Mockito.when(environment.getProperty(\"ssl.trustStoreType\")).thenReturn(\"JKS\");\n    Mockito.when(environment.getProperty(\"ssl.trustStoreValue\")).thenReturn(\"Changeme_123\");\n    Mockito.when(environment.getProperty(\"ssl.keyStore\")).thenReturn(\"server.p12\");\n    Mockito.when(environment.getProperty(\"ssl.keyStoreType\")).thenReturn(\"PKCS12\");\n    Mockito.when(environment.getProperty(\"ssl.keyStoreValue\")).thenReturn(\"Changeme_123\");\n    Mockito.when(environment.getProperty(\"ssl.crl\")).thenReturn(\"revoke.crl\");\n  }\n\n  @Test\n  public void testSSLOption() {\n\n    SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n\n    String protocols = option.getProtocols();\n    option.setProtocols(protocols);\n    Assertions.assertEquals(\"TLSv1.3,TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\", protocols);\n\n    String ciphers = option.getCiphers();\n    option.setCiphers(ciphers);\n    Assertions.assertEquals(\n        \"TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SH\"\n            +\n            \"A,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\",\n        ciphers);\n\n    boolean authPeer = option.isAuthPeer();\n    option.setAuthPeer(authPeer);\n    Assertions.assertTrue(authPeer);\n\n    boolean checkCNHost = option.isCheckCNHost();\n    option.setCheckCNHost(checkCNHost);\n    Assertions.assertTrue(checkCNHost);\n\n    boolean checkCNWhite = option.isCheckCNWhite();\n    option.setCheckCNWhite(checkCNWhite);\n    Assertions.assertTrue(checkCNWhite);\n\n    String checkCNWhiteFile = option.getCheckCNWhiteFile();\n    option.setCheckCNWhiteFile(checkCNWhiteFile);\n    Assertions.assertEquals(\"white.list\", checkCNWhiteFile);\n\n    boolean allowRenegotiate = option.isAllowRenegotiate();\n    option.setAllowRenegotiate(allowRenegotiate);\n    Assertions.assertFalse(allowRenegotiate);\n\n    String storePath = option.getStorePath();\n    option.setStorePath(storePath);\n    Assertions.assertEquals(\"internal\", storePath);\n\n    String trustStore = option.getTrustStore();\n    option.setTrustStore(trustStore);\n    Assertions.assertEquals(\"trust.jks\", trustStore);\n\n    String trustStoreType = option.getTrustStoreType();\n    option.setTrustStoreType(trustStoreType);\n    Assertions.assertEquals(\"JKS\", trustStoreType);\n\n    String trustStoreValue = option.getTrustStoreValue();\n    option.setTrustStoreValue(trustStoreValue);\n    Assertions.assertEquals(\"Changeme_123\", trustStoreValue);\n\n    String keyStore = option.getKeyStore();\n    option.setKeyStore(keyStore);\n    Assertions.assertEquals(\"server.p12\", keyStore);\n\n    String keyStoreType = option.getKeyStoreType();\n    option.setKeyStoreType(keyStoreType);\n    Assertions.assertEquals(\"PKCS12\", keyStoreType);\n\n    String keyStoreValue = option.getKeyStoreValue();\n    option.setKeyStoreValue(keyStoreValue);\n    Assertions.assertEquals(\"Changeme_123\", keyStoreValue);\n\n    String crl = option.getCrl();\n    option.setCrl(crl);\n    Assertions.assertEquals(\"revoke.crl\", crl);\n  }\n\n  @Test\n  public void testSSLOptionYaml() {\n    Mockito.when(environment.getProperty(\"ssl.server.sslCustomClass\")).thenReturn(\"wwrong\");\n    SSLOption option = SSLOption.build(\"server\", environment);\n\n    String protocols = option.getProtocols();\n    option.setProtocols(protocols);\n    Assertions.assertEquals(\"TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\", protocols);\n\n    String ciphers = option.getCiphers();\n    option.setCiphers(ciphers);\n    Assertions.assertEquals(\"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256\",\n        ciphers);\n\n    boolean authPeer = option.isAuthPeer();\n    option.setAuthPeer(authPeer);\n    Assertions.assertTrue(authPeer);\n\n    boolean checkCNHost = option.isCheckCNHost();\n    option.setCheckCNHost(checkCNHost);\n    Assertions.assertTrue(checkCNHost);\n\n    boolean checkCNWhite = option.isCheckCNWhite();\n    option.setCheckCNWhite(checkCNWhite);\n    Assertions.assertTrue(checkCNWhite);\n\n    String checkCNWhiteFile = option.getCheckCNWhiteFile();\n    option.setCheckCNWhiteFile(checkCNWhiteFile);\n    Assertions.assertEquals(\"white.list\", checkCNWhiteFile);\n\n    boolean allowRenegotiate = option.isAllowRenegotiate();\n    option.setAllowRenegotiate(allowRenegotiate);\n    Assertions.assertFalse(allowRenegotiate);\n\n    String storePath = option.getStorePath();\n    option.setStorePath(storePath);\n    Assertions.assertEquals(\"internal\", storePath);\n\n    String trustStore = option.getTrustStore();\n    option.setTrustStore(trustStore);\n    Assertions.assertEquals(\"trust.jks\", trustStore);\n\n    String trustStoreType = option.getTrustStoreType();\n    option.setTrustStoreType(trustStoreType);\n    Assertions.assertEquals(\"JKS\", trustStoreType);\n\n    String trustStoreValue = option.getTrustStoreValue();\n    option.setTrustStoreValue(trustStoreValue);\n    Assertions.assertEquals(\"Changeme_123\", trustStoreValue);\n\n    String keyStore = option.getKeyStore();\n    option.setKeyStore(keyStore);\n    Assertions.assertEquals(\"server.p12\", keyStore);\n\n    String keyStoreType = option.getKeyStoreType();\n    option.setKeyStoreType(keyStoreType);\n    Assertions.assertEquals(\"PKCS12\", keyStoreType);\n\n    String keyStoreValue = option.getKeyStoreValue();\n    option.setKeyStoreValue(keyStoreValue);\n    Assertions.assertEquals(\"Changeme_123\", keyStoreValue);\n\n    String crl = option.getCrl();\n    option.setCrl(crl);\n    Assertions.assertEquals(\"revoke.crl\", crl);\n\n    option.setSslCustomClass(\"123\");\n\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    Assertions.assertArrayEquals(custom.decode(\"123\".toCharArray()), \"123\".toCharArray());\n  }\n\n  @Test\n  public void testSSLOptionYamlOption2() throws Exception {\n    Mockito.when(environment.getProperty(\"ssl.protocols\")).thenReturn(\"TLSv1.2\");\n\n    SSLOption option = SSLOption.build(\"server\", environment);\n\n    String protocols = option.getProtocols();\n    option.setProtocols(protocols);\n    Assertions.assertEquals(\"TLSv1.2\", protocols);\n    System.clearProperty(\"ssl.protocols\");\n  }\n\n  @Test\n  public void testSSLOptionYamlOptionWithPropertyFalse() throws Exception {\n    Mockito.when(environment.getProperty(\"ssl.authPeer\")).thenReturn(\"false\");\n\n    SSLOption option = SSLOption.build(\"server\", environment);\n\n    boolean authPeer = option.isAuthPeer();\n    option.setAuthPeer(authPeer);\n    Assertions.assertFalse(authPeer);\n    System.getProperties().remove(\"ssl.authPeer\");\n  }\n\n  @Test\n  public void testSSLOptionYamlOptionWithPropertyTrue() throws Exception {\n    SSLOption option = SSLOption.build(\"server\", environment);\n\n    boolean authPeer = option.isAuthPeer();\n    option.setAuthPeer(authPeer);\n    Assertions.assertTrue(authPeer);\n    System.getProperties().remove(\"ssl.authPeer\");\n  }\n\n  @Test\n  public void testSSLOptionYamlOption() throws Exception {\n    SSLOption option = SSLOption.build(\"server\", environment);\n\n    String protocols = option.getProtocols();\n    option.setProtocols(protocols);\n    Assertions.assertEquals(\"TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\", protocols);\n\n    String ciphers = option.getCiphers();\n    option.setCiphers(ciphers);\n    Assertions.assertEquals(\n        \"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256\",\n        ciphers);\n\n    boolean authPeer = option.isAuthPeer();\n    option.setAuthPeer(authPeer);\n    Assertions.assertTrue(authPeer);\n\n    boolean checkCNHost = option.isCheckCNHost();\n    option.setCheckCNHost(checkCNHost);\n    Assertions.assertTrue(checkCNHost);\n\n    boolean checkCNWhite = option.isCheckCNWhite();\n    option.setCheckCNWhite(checkCNWhite);\n    Assertions.assertTrue(checkCNWhite);\n\n    String checkCNWhiteFile = option.getCheckCNWhiteFile();\n    option.setCheckCNWhiteFile(checkCNWhiteFile);\n    Assertions.assertEquals(\"white.list\", checkCNWhiteFile);\n\n    boolean allowRenegotiate = option.isAllowRenegotiate();\n    option.setAllowRenegotiate(allowRenegotiate);\n    Assertions.assertFalse(allowRenegotiate);\n\n    String storePath = option.getStorePath();\n    option.setStorePath(storePath);\n    Assertions.assertEquals(\"internal\", storePath);\n\n    String trustStore = option.getTrustStore();\n    option.setTrustStore(trustStore);\n    Assertions.assertEquals(\"trust.jks\", trustStore);\n\n    String trustStoreType = option.getTrustStoreType();\n    option.setTrustStoreType(trustStoreType);\n    Assertions.assertEquals(\"JKS\", trustStoreType);\n\n    String trustStoreValue = option.getTrustStoreValue();\n    option.setTrustStoreValue(trustStoreValue);\n    Assertions.assertEquals(\"Changeme_123\", trustStoreValue);\n\n    String keyStore = option.getKeyStore();\n    option.setKeyStore(keyStore);\n    Assertions.assertEquals(\"server.p12\", keyStore);\n\n    String keyStoreType = option.getKeyStoreType();\n    option.setKeyStoreType(keyStoreType);\n    Assertions.assertEquals(\"PKCS12\", keyStoreType);\n\n    String keyStoreValue = option.getKeyStoreValue();\n    option.setKeyStoreValue(keyStoreValue);\n    Assertions.assertEquals(\"Changeme_123\", keyStoreValue);\n\n    String crl = option.getCrl();\n    option.setCrl(crl);\n    Assertions.assertEquals(\"revoke.crl\", crl);\n\n    option.setSslCustomClass(\"123\");\n\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    Assertions.assertArrayEquals(custom.decode(\"123\".toCharArray()), \"123\".toCharArray());\n  }\n\n  @SuppressWarnings(\"unused\")\n  @Test\n  public void testSSLOptionNull() {\n    try {\n      SSLOption option = SSLOption.build(DIR + \"/servers.ssl.properties\");\n    } catch (IllegalArgumentException e) {\n      Assertions.assertEquals(\"Bad file name.\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testBuildException() {\n    new MockUp<File>() {\n      @Mock\n      public String getCanonicalPath() throws IOException {\n        throw new IOException();\n      }\n    };\n\n    try {\n      SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n      Assertions.assertNotNull(option);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testBuildIOException() {\n    new MockUp<Properties>() {\n      @Mock\n      public synchronized void load(Reader reader) throws IOException {\n        throw new IOException();\n      }\n    };\n    boolean validAssert = true;\n    try {\n      SSLOption option = SSLOption.build(DIR + \"/server.ssl.properties\");\n      Assertions.assertEquals(\"revoke.crl\", option.getCrl());\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n      validAssert = false;\n    }\n    Assertions.assertFalse(validAssert);\n  }\n\n  @Test\n  public void testBuildInputStream() {\n    try {\n\n      URL url = this.getClass().getResource(\"/server.ssl.properties\");\n\n      InputStream inputStream = url.openStream();\n      SSLOption option = SSLOption.build(inputStream);\n      Assertions.assertNotNull(option);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n    }\n  }\n\n  @Test\n  public void testPrivateMethodException() {\n    SSLOption option = new SSLOption();\n    boolean validAssert = true;\n    try {\n      option.load(\"test\");\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.lang.IllegalArgumentException\", e.getClass().getName());\n      validAssert = false;\n    }\n    Assertions.assertFalse(validAssert);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/TestSSLOptionFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestSSLOptionFactory {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Test\n  public void testSSLOptionFactory() {\n    SSLOptionFactory factory = SSLOptionFactory.createSSLOptionFactory(\"cc\", environment);\n    Assertions.assertNull(factory);\n  }\n\n  @Test\n  public void testSSLOptionFactoryWrong(@Mocked SSLOption option) {\n    new Expectations() {\n      {\n        SSLOption.getStringProperty((Environment) any, anyString, (String[]) any);\n        result = \"wrong\";\n      }\n    };\n\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class,\n        () -> SSLOptionFactory.createSSLOptionFactory(\"cc\", null));\n    Assertions.assertEquals(\"Failed to create SSLOptionFactory.\", exception.getMessage());\n  }\n\n  @Test\n  public void testSSLOptionFactoryCurrent() {\n    new MockUp<SSLOption>() {\n      @Mock\n      public String getStringProperty(Environment environment, String defaultValue,\n          String... keys) {\n        return \"org.apache.servicecomb.foundation.ssl.MyOptionFactory\";\n      }\n    };\n    SSLOptionFactory factory = SSLOptionFactory.createSSLOptionFactory(\"cc\", environment);\n    Assertions.assertEquals(factory.createSSLOption().getProtocols(), \"TLSv1.2\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/TestSSLSocketFactoryExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport javax.net.ssl.SSLSocketFactory;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\npublic class TestSSLSocketFactoryExt {\n\n  private SSLSocketFactoryExt instance = null;\n\n  @Before\n  public void setUp() throws Exception {\n    SSLSocketFactory factory = Mockito.mock(SSLSocketFactoryExt.class);\n    String[] ciphers = {\"test\"};\n\n    String[] protos = {\"test\"};\n    instance = new SSLSocketFactoryExt(factory, ciphers, protos);\n  }\n\n  @After\n  public void tearDown() throws Exception {\n    instance = null;\n  }\n\n  @Test\n  public void testCreateSocketException() {\n    boolean validAssert = true;\n    try {\n      instance.createSocket(\"host\", 8080);\n    } catch (Exception e) {\n      validAssert = false;\n    }\n    Assertions.assertFalse(validAssert);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/TestTrustAllManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport java.net.Socket;\nimport java.security.cert.X509Certificate;\n\nimport javax.net.ssl.SSLEngine;\n\npublic class TestTrustAllManager {\n  @Test\n  public void testTrustAllManager() throws Exception {\n    TrustAllManager manager = new TrustAllManager();\n    manager.checkClientTrusted((X509Certificate[]) null, (String) null);\n    manager.checkServerTrusted((X509Certificate[]) null, (String) null);\n\n    manager.checkClientTrusted((X509Certificate[]) null,\n        (String) null,\n        (Socket) null);\n    manager.checkClientTrusted((X509Certificate[]) null,\n        (String) null,\n        (SSLEngine) null);\n\n    manager.checkServerTrusted((X509Certificate[]) null,\n        (String) null,\n        (Socket) null);\n    manager.checkServerTrusted((X509Certificate[]) null,\n        (String) null,\n        (SSLEngine) null);\n    Assertions.assertNull(manager.getAcceptedIssuers());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/TrustManagerExtTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.ssl;\n\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.math.BigInteger;\nimport java.net.Socket;\nimport java.security.InvalidKeyException;\nimport java.security.KeyStore;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.NoSuchProviderException;\nimport java.security.Principal;\nimport java.security.PublicKey;\nimport java.security.SignatureException;\nimport java.security.cert.CertificateEncodingException;\nimport java.security.cert.CertificateException;\nimport java.security.cert.CertificateExpiredException;\nimport java.security.cert.CertificateNotYetValidException;\nimport java.security.cert.X509Certificate;\nimport java.util.Date;\nimport java.util.Set;\n\nimport javax.net.ssl.SSLEngine;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.X509ExtendedTrustManager;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TrustManagerExtTest {\n  final String strFilePath = Thread.currentThread().getContextClassLoader().getResource(\"\").getPath();\n\n  static class MyX509ExtendedTrustManager extends X509ExtendedTrustManager {\n    public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString,\n        Socket paramSocket) throws CertificateException {\n    }\n\n    public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate,\n        String paramString) throws CertificateException {\n    }\n\n    public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString,\n        Socket paramSocket) throws CertificateException {\n    }\n\n    public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate,\n        String paramString) throws CertificateException {\n    }\n\n    public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString,\n        SSLEngine paramSSLEngine) throws CertificateException {\n    }\n\n    public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString,\n        SSLEngine paramSSLEngine) throws CertificateException {\n    }\n\n    public X509Certificate[] getAcceptedIssuers() {\n      return null;\n    }\n  }\n\n  @SuppressWarnings(\"deprecation\")\n  static class MyX509Certificate extends X509Certificate {\n    private static final long serialVersionUID = -3585440601605666276L;\n\n    public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {\n    }\n\n    @Override\n    public boolean hasUnsupportedCriticalExtension() {\n      return false;\n    }\n\n    @Override\n    public Set<String> getCriticalExtensionOIDs() {\n      return null;\n    }\n\n    @Override\n    public Set<String> getNonCriticalExtensionOIDs() {\n      return null;\n    }\n\n    @Override\n    public byte[] getExtensionValue(String oid) {\n      return null;\n    }\n\n    @Override\n    public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {\n    }\n\n    @Override\n    public int getVersion() {\n      return 0;\n    }\n\n    @Override\n    public BigInteger getSerialNumber() {\n      return null;\n    }\n\n    @Override\n    public Principal getIssuerDN() {\n      return null;\n    }\n\n    @Override\n    public Principal getSubjectDN() {\n      return null;\n    }\n\n    @Override\n    public Date getNotBefore() {\n      return null;\n    }\n\n    @Override\n    public Date getNotAfter() {\n      return null;\n    }\n\n    @Override\n    public byte[] getTBSCertificate() throws CertificateEncodingException {\n      return null;\n    }\n\n    @Override\n    public byte[] getSignature() {\n      return null;\n    }\n\n    @Override\n    public String getSigAlgName() {\n      return null;\n    }\n\n    @Override\n    public String getSigAlgOID() {\n      return null;\n    }\n\n    @Override\n    public byte[] getSigAlgParams() {\n      return null;\n    }\n\n    @Override\n    public boolean[] getIssuerUniqueID() {\n      return null;\n    }\n\n    @Override\n    public boolean[] getSubjectUniqueID() {\n      return null;\n    }\n\n    @Override\n    public boolean[] getKeyUsage() {\n      return null;\n    }\n\n    @Override\n    public int getBasicConstraints() {\n      return 0;\n    }\n\n    @Override\n    public byte[] getEncoded() throws CertificateEncodingException {\n      return null;\n    }\n\n    @Override\n    public void verify(PublicKey key)\n        throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,\n        SignatureException {\n\n    }\n\n    @Override\n    public void verify(PublicKey key, String sigProvider)\n        throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,\n        SignatureException {\n    }\n\n    @Override\n    public String toString() {\n      return null;\n    }\n\n    @Override\n    public PublicKey getPublicKey() {\n      return null;\n    }\n  }\n\n  final SSLOption option = SSLOption.build(strFilePath + \"/server.ssl.properties\");\n\n  final SSLCustom custom = new SSLCustom() {\n    @Override\n    public String getFullPath(String filename) {\n      return strFilePath + \"/ssl/\" + filename;\n    }\n\n    @Override\n    public char[] decode(char[] encrypted) {\n      return encrypted;\n    }\n\n    @Override\n    public String getHost() {\n      return \"10.67.147.115\";\n    }\n  };\n\n  @Before\n  public void setUp() {\n  }\n\n  @After\n  public void tearDown() {\n  }\n\n  @SuppressWarnings(\"unused\")\n  @Test\n  public void testConstructor() {\n    String keyStoreName = custom.getFullPath(option.getKeyStore());\n    char[] keyStoreValue = custom.decode(option.getKeyStoreValue().toCharArray());\n    String trustStoreName = custom.getFullPath(option.getTrustStore());\n    char[] trustStoreValue =\n        custom.decode(option.getTrustStoreValue().toCharArray());\n    KeyStore trustStore =\n        KeyStoreUtil.createKeyStore(trustStoreName,\n            option.getTrustStoreType(),\n            trustStoreValue);\n    TrustManager[] trustManager = KeyStoreUtil.createTrustManagers(trustStore);\n\n    TrustManagerExt trustManagerExt = new TrustManagerExt((X509ExtendedTrustManager) trustManager[0],\n        option, custom);\n    Assertions.assertEquals(3, trustManagerExt.getAcceptedIssuers()[0].getVersion());\n    Assertions.assertNotNull(trustManagerExt);\n  }\n\n  @Test\n  public void testConstructorWithParam() {\n    MyX509Certificate myX509Certificate1 = new MyX509Certificate();\n    MyX509Certificate myX509Certificate2 = new MyX509Certificate();\n\n    MyX509Certificate[] myX509CertificateArray = new MyX509Certificate[2];\n    myX509CertificateArray[0] = myX509Certificate1;\n    myX509CertificateArray[1] = myX509Certificate2;\n\n    new Expectations(CertificateUtil.class) {\n      {\n        CertificateUtil.findOwner((X509Certificate[]) any);\n        result = any;\n\n        CertificateUtil.getCN((X509Certificate) any);\n        result = \"10.67.147.115\";\n      }\n    };\n\n    MyX509ExtendedTrustManager myX509ExtendedTrustManager = new MyX509ExtendedTrustManager();\n    TrustManagerExt trustManagerExt = new TrustManagerExt(myX509ExtendedTrustManager, option, custom);\n\n    Assertions.assertNotNull(trustManagerExt);\n    boolean validAssert = true;\n    try {\n      trustManagerExt.checkClientTrusted(myX509CertificateArray, \"pks\");\n      trustManagerExt.checkServerTrusted(myX509CertificateArray, \"pks\");\n      trustManagerExt.getAcceptedIssuers();\n    } catch (Exception e) {\n      validAssert = false;\n    }\n    Assertions.assertTrue(validAssert);\n  }\n\n  @Test\n  public void testCheckClientTrusted(@Mocked CertificateUtil certificateUtil) {\n    MyX509Certificate myX509Certificate1 = new MyX509Certificate();\n    MyX509Certificate myX509Certificate2 = new MyX509Certificate();\n\n    MyX509Certificate[] myX509CertificateArray = new MyX509Certificate[2];\n    myX509CertificateArray[0] = myX509Certificate1;\n    myX509CertificateArray[1] = myX509Certificate2;\n\n    new Expectations() {\n      {\n        CertificateUtil.findOwner((X509Certificate[]) any);\n        result = any;\n\n        CertificateUtil.getCN((X509Certificate) any);\n        result = \"10.67.147.115\";\n      }\n    };\n\n    MyX509ExtendedTrustManager myX509ExtendedTrustManager = new MyX509ExtendedTrustManager();\n    TrustManagerExt trustManagerExt = new TrustManagerExt(myX509ExtendedTrustManager, option, custom);\n\n    Socket socket = null;\n    SSLEngine sslengine = null;\n    boolean validAssert = true;\n    try {\n      trustManagerExt.checkClientTrusted(myX509CertificateArray, \"pks\", socket);\n      trustManagerExt.checkClientTrusted(myX509CertificateArray, \"pks\", sslengine);\n      trustManagerExt.checkServerTrusted(myX509CertificateArray, \"pks\", socket);\n      trustManagerExt.checkServerTrusted(myX509CertificateArray, \"pks\", sslengine);\n    } catch (Exception e) {\n      validAssert = false;\n    }\n    Assertions.assertTrue(validAssert);\n  }\n\n  @Test\n  public void testCatchException(@Mocked CertificateUtil certificateUtil) {\n    MyX509Certificate myX509Certificate1 = new MyX509Certificate();\n    MyX509Certificate myX509Certificate2 = new MyX509Certificate();\n\n    MyX509Certificate[] myX509CertificateArray = new MyX509Certificate[2];\n    myX509CertificateArray[0] = myX509Certificate1;\n    myX509CertificateArray[1] = myX509Certificate2;\n\n    new Expectations() {\n      {\n        CertificateUtil.findOwner((X509Certificate[]) any);\n        result = any;\n\n        CertificateUtil.getCN((X509Certificate) any);\n        result = \"10.67.147.114\";\n      }\n    };\n\n    MyX509ExtendedTrustManager myX509ExtendedTrustManager = new MyX509ExtendedTrustManager();\n    TrustManagerExt trustManagerExt = new TrustManagerExt(myX509ExtendedTrustManager, option, custom);\n    boolean validAssert = true;\n    try {\n      trustManagerExt.checkClientTrusted(myX509CertificateArray, \"pks\");\n    } catch (CertificateException e) {\n      Assertions.assertEquals(\"CN does not match IP: e=[10.67.147.114],t=null\", e.getMessage());\n      validAssert = false;\n    }\n    Assertions.assertFalse(validAssert);\n  }\n\n  @Test\n  public void testCheckClientTrustedException(@Mocked CertificateUtil certificateUtil) {\n    MyX509Certificate myX509Certificate1 = new MyX509Certificate();\n    MyX509Certificate myX509Certificate2 = new MyX509Certificate();\n\n    MyX509Certificate[] myX509CertificateArray = new MyX509Certificate[2];\n    myX509CertificateArray[0] = myX509Certificate1;\n    myX509CertificateArray[1] = myX509Certificate2;\n\n    new Expectations() {\n      {\n        CertificateUtil.findOwner((X509Certificate[]) any);\n        result = any;\n\n        CertificateUtil.getCN((X509Certificate) any);\n        result = \"10.67.147.115\";\n      }\n    };\n\n    MyX509ExtendedTrustManager myX509ExtendedTrustManager = new MyX509ExtendedTrustManager();\n    TrustManagerExt trustManagerExt = new TrustManagerExt(myX509ExtendedTrustManager, option, custom);\n\n    Socket socket = null;\n    SSLEngine sslengine = null;\n\n    new MockUp<InputStreamReader>() {\n      @Mock\n      public int read(char[] cbuf) throws IOException {\n        throw new IOException();\n      }\n    };\n    boolean validAssert = true;\n    try {\n      trustManagerExt.checkClientTrusted(myX509CertificateArray, \"pks\", socket);\n      trustManagerExt.checkClientTrusted(myX509CertificateArray, \"pks\", sslengine);\n      trustManagerExt.checkServerTrusted(myX509CertificateArray, \"pks\", socket);\n      trustManagerExt.checkServerTrusted(myX509CertificateArray, \"pks\", sslengine);\n    } catch (Exception e) {\n      Assertions.assertEquals(\"java.security.cert.CertificateException\", e.getClass().getName());\n      validAssert = false;\n    }\n    Assertions.assertFalse(validAssert);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/client.ssl.properties",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n#########SSL options\nssl.protocols=TLSv1.3,TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\n## test with extra blank\nssl.ciphers=TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\nssl.authPeer=true\nssl.checkCN.host=false\nssl.checkCN.white=true\nssl.checkCN.white.file=white.list\nssl.allowRenegotiate=false\n\n#########certificates config\nssl.storePath=internal\nssl.trustStore=trust.jks\nssl.trustStoreType=JKS\nssl.trustStoreValue=Changeme_123\nssl.keyStore=server.p12\nssl.keyStoreType=PKCS12\nssl.keyStoreValue=Changeme_123\nssl.crl=revoke.crl\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n#########SSL options\nssl:\n  protocols: TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\n  ciphers: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\n  authPeer: true\n  checkCN.host: true\n  checkCN.white: true\n  checkCN.white.file: white.list\n  allowRenegotiate: false\n  storePath: internal\n  trustStore: trust.jks\n  trustStoreType: JKS\n  trustStoreValue: Changeme_123\n  keyStore: server.p12\n  keyStoreType: PKCS12\n  keyStoreValue: Changeme_123\n  crl: revoke.crl\n  server:\n    sslCustomClass: wwrong\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/server.ssl.properties",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n#########SSL options\nssl.protocols=TLSv1.3,TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\nssl.ciphers=TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\nssl.authPeer=true\nssl.checkCN.host=true\nssl.checkCN.white=true\nssl.checkCN.white.file=white.list\nssl.allowRenegotiate=false\n\n#########certificates config\nssl.storePath=internal\nssl.trustStore=trust.jks\nssl.trustStoreType=JKS\nssl.trustStoreValue=Changeme_123\nssl.keyStore=server.p12\nssl.keyStoreType=PKCS12\nssl.keyStoreValue=Changeme_123\nssl.crl=revoke.crl\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/server.ssl.resource.properties",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n#########SSL options\nssl.protocols=TLSv1.2,TLSv1.1,TLSv1,SSLv2Hello\nssl.ciphers=TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA\nssl.authPeer=true\nssl.checkCN.host=true\nssl.checkCN.white=true\nssl.checkCN.white.file=white.list\nssl.allowRenegotiate=false\n\n#########certificates config\nssl.storePath=internal\nssl.trustStore=ssl/trust.jks\nssl.trustStoreType=JKS\nssl.trustStoreValue=Changeme_123\nssl.keyStore=ssl/server.p12\nssl.keyStoreType=PKCS12\nssl.keyStoreValue=Changeme_123\nssl.crl=revoke.crl\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/ssl/server.cer",
    "content": "Certificate:\n    Data:\n        Version: 3 (0x2)\n        Serial Number:\n            49:d0:cc:fe:b2:03:5e:99:00:00:00:00:00:00:0e:00\n        Signature Algorithm: sha256WithRSAEncryption\n        Issuer: C=CN, ST=GuangDong, L=ShenZhen, O=Huawei Technologies Co., Ltd, OU=OSS & Service Tools Dept, CN=OSS3.0 CA\n        Validity\n            Not Before: Mar 31 00:00:00 2017 GMT\n            Not After : Mar 26 00:00:00 2037 GMT\n        Subject: C=CN, ST=GuangDong, L=ShenZhen, O=Huawei Technologies Co., Ltd, OU=OSS & Service Tools Dept, OU=development, CN=10.57.65.225\n        Subject Public Key Info:\n            Public Key Algorithm: rsaEncryption\n            RSA Public Key: (4096 bit)\n                Modulus (4096 bit):\n                    00:d1:f3:b6:1e:4d:40:d6:4e:d5:41:e6:34:b0:3f:\n                    d1:97:19:5a:1b:c0:a0:91:80:33:43:50:ab:08:df:\n                    6b:e9:43:b4:09:ff:c9:f3:71:cf:8c:c5:61:ec:64:\n                    26:67:24:4d:93:31:5c:1a:bf:e1:fe:c5:fb:2a:dc:\n                    36:26:a5:52:85:b9:4e:1c:42:18:da:d0:68:86:61:\n                    dd:44:62:eb:b7:45:81:1e:3d:08:84:a1:16:06:d7:\n                    4e:26:7b:9a:1a:19:db:eb:e8:22:25:b7:62:5c:7a:\n                    d6:d8:3d:67:f1:a9:fe:bc:b9:af:f1:f6:95:88:19:\n                    e0:89:d3:e1:05:c1:b1:c3:78:9a:99:5a:89:50:ea:\n                    61:32:5a:9c:42:aa:2a:e9:81:a0:a7:7f:31:f6:fa:\n                    ea:1f:6a:d7:c1:2a:71:d0:d4:91:eb:86:25:fb:de:\n                    a7:ef:74:09:f9:5d:e1:33:23:35:36:67:74:60:05:\n                    e6:01:4f:fb:ac:b5:bb:c8:be:4a:60:a8:e1:9e:da:\n                    5f:63:bc:de:cc:08:20:0f:67:c0:17:22:62:43:35:\n                    f1:63:32:4d:94:a0:c2:54:25:f4:78:ac:bc:8f:55:\n                    7e:5c:30:21:0f:aa:34:39:55:9e:ab:99:1b:f1:00:\n                    dc:97:47:d7:0f:74:2d:39:16:f1:44:d7:f2:7e:3e:\n                    c0:fb:bd:41:d9:72:fa:52:1f:96:d3:3e:ad:99:3e:\n                    09:ab:3d:20:3b:60:43:d3:51:89:7f:5e:3e:bc:38:\n                    a0:23:34:f4:2d:1a:fe:fa:a8:39:d5:b6:28:a0:ae:\n                    35:ad:54:40:75:a8:ae:84:46:7f:1b:b3:45:80:3f:\n                    75:38:a7:12:ea:a5:96:7e:c6:47:12:f0:88:74:16:\n                    2b:e4:ca:0f:9d:b2:bc:9b:b7:96:68:8c:be:b0:9b:\n                    aa:bf:7f:5e:41:18:49:0e:51:da:e9:2d:6d:a7:a0:\n                    20:94:6f:4a:7d:05:41:94:27:59:16:64:8c:8b:09:\n                    60:c2:e7:12:72:1f:9e:66:52:08:1f:71:58:a2:c6:\n                    90:13:31:7e:0a:4b:99:56:cc:3d:77:8c:31:19:11:\n                    99:f5:89:60:3a:17:22:6a:a2:00:e1:57:52:83:1f:\n                    55:23:f2:b3:9f:29:5c:5d:e9:00:69:f5:64:74:3c:\n                    1e:9b:da:da:31:28:a5:f4:88:4f:2f:d1:e3:2d:d0:\n                    bb:0e:bb:df:6a:5a:36:55:50:04:58:15:fa:d3:08:\n                    af:ed:40:29:76:57:9e:52:eb:98:90:7d:45:fd:67:\n                    22:07:42:c4:23:f5:e5:32:9a:82:4a:5c:49:ee:b4:\n                    a6:28:81:76:b4:a6:e0:c6:4e:dd:ad:58:06:ca:b9:\n                    53:08:33\n                Exponent: 65537 (0x10001)\n        X509v3 extensions:\n            X509v3 Basic Constraints:\n                CA:FALSE\n            X509v3 Key Usage: critical\n                Digital Signature, Non Repudiation, Key Encipherment\n            X509v3 Subject Key Identifier:\n                27:15:69:5B:D5:13:60:C4:5C:62:54:75:55:A1:1D:4D:57:27:03:1F\n            X509v3 Authority Key Identifier:\n                keyid:D5:4E:82:08:70:16:63:3D:DF:87:25:0B:7D:2E:EB:83:21:6A:BA:5B\n                DirName:/C=CN/ST=GuangDong/L=ShenZhen/O=Huawei Technologies Co., Ltd/OU=OSS & Service Tools Dept/CN=OSS3.0 CA\n                serial:7D:FD:C5:D8:70:DA:6E:0F:00:00:00:00:00:00:00:00\n\n            X509v3 Subject Alternative Name:\n                DNS:10.57.65.225, IP Address:10.57.65.225\n    Signature Algorithm: sha256WithRSAEncryption\n        38:1b:40:c9:3c:7f:63:a0:2d:64:59:2b:d9:4a:4b:db:c4:70:\n        ca:04:f0:e4:61:d2:47:7e:66:2a:f7:2f:15:46:f5:9c:8b:0b:\n        c0:97:f1:b4:e9:93:b0:d4:62:d5:22:a5:83:75:be:3a:9d:cc:\n        79:42:ec:85:11:17:c5:a2:e0:c6:30:64:3f:e2:4a:c1:9c:bd:\n        47:1d:8c:38:e1:2e:06:fe:08:c4:06:65:cb:31:49:a1:6c:5d:\n        c5:f4:68:26:66:c8:b2:c6:40:24:01:db:de:0d:fe:1a:f3:10:\n        07:9b:9c:82:bc:b4:32:6a:7a:19:d7:c1:1a:cb:88:ba:de:e3:\n        15:0c:16:92:ed:61:f0:1e:ca:e3:52:0f:75:be:42:fc:4e:2e:\n        3d:ca:8c:70:03:a9:03:c6:6b:9b:d6:7a:de:75:c0:dd:d4:d8:\n        a6:03:92:5c:76:94:ab:22:dd:4e:a7:52:47:c3:79:46:4e:37:\n        30:a8:4a:5f:4a:ae:3e:c4:cd:43:d0:fa:4b:40:60:98:b9:53:\n        c8:46:3e:22:bc:63:39:30:1c:6f:c7:5e:2c:ce:fc:9f:24:c1:\n        49:a4:6f:ca:b9:72:44:ee:67:f1:f9:59:6a:1a:09:a8:df:64:\n        60:57:c0:88:36:c6:73:5c:fc:1a:00:d9:38:17:d8:85:84:c5:\n        31:88:45:66:ed:f6:fd:98:24:4d:de:68:d9:a0:87:7a:3f:ec:\n        62:ba:d9:16:7e:ef:67:88:bd:c6:b3:70:72:c9:af:21:45:37:\n        b5:d1:84:b7:8b:1a:eb:5c:5f:07:a8:6b:d0:ab:01:56:87:e3:\n        c5:a4:b8:cc:d7:d0:47:38:60:97:85:b5:42:74:12:9e:77:03:\n        19:a7:77:fb:f9:f9:6f:cc:c6:ff:4d:be:65:28:17:a6:45:19:\n        da:12:5f:15:de:77:06:96:43:0e:19:50:7f:82:aa:da:34:78:\n        d8:ca:8b:8e:ba:1d:20:15:f7:89:15:c0:09:26:76:4d:a6:33:\n        4a:ed:a1:5d:be:78:54:18:f3:62:f2:7f:a5:bd:22:db:b1:49:\n        32:87:01:fc:a8:f3:8f:fd:3d:fd:9c:59:aa:b5:8a:d3:a4:49:\n        19:95:ae:6c:24:e4:98:32:92:07:04:e6:4a:33:8c:af:8e:d7:\n        05:64:3a:1e:c6:93:85:89:6b:9f:70:c4:f6:32:fa:bb:c3:53:\n        9c:e2:73:ec:09:6a:d8:8f:23:a1:0f:f1:03:f4:cf:cf:8d:6c:\n        00:37:bb:53:43:9a:7e:99:27:95:ef:05:52:11:d3:0e:a9:d6:\n        e9:88:ab:c2:e9:57:09:95:e6:1c:01:5b:f2:a6:d4:fa:44:57:\n        40:e6:eb:4c:9c:75:12:8b\n-----BEGIN CERTIFICATE-----\nMIIG+TCCBOGgAwIBAgIQSdDM/rIDXpkAAAAAAAAOADANBgkqhkiG9w0BAQsFADCB\nkjELMAkGA1UEBhMCQ04xEjAQBgNVBAgTCUd1YW5nRG9uZzERMA8GA1UEBxMIU2hl\nblpoZW4xJTAjBgNVBAoTHEh1YXdlaSBUZWNobm9sb2dpZXMgQ28uLCBMdGQxITAf\nBgNVBAsUGE9TUyAmIFNlcnZpY2UgVG9vbHMgRGVwdDESMBAGA1UEAxMJT1NTMy4w\nIENBMB4XDTE3MDMzMTAwMDAwMFoXDTM3MDMyNjAwMDAwMFowgasxCzAJBgNVBAYT\nAkNOMRIwEAYDVQQIEwlHdWFuZ0RvbmcxETAPBgNVBAcTCFNoZW5aaGVuMSUwIwYD\nVQQKExxIdWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkMSEwHwYDVQQLFBhPU1Mg\nJiBTZXJ2aWNlIFRvb2xzIERlcHQxFDASBgNVBAsTC2RldmVsb3BtZW50MRUwEwYD\nVQQDEwwxMC41Ny42NS4yMjUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\nAQDR87YeTUDWTtVB5jSwP9GXGVobwKCRgDNDUKsI32vpQ7QJ/8nzcc+MxWHsZCZn\nJE2TMVwav+H+xfsq3DYmpVKFuU4cQhja0GiGYd1EYuu3RYEePQiEoRYG104me5oa\nGdvr6CIlt2JcetbYPWfxqf68ua/x9pWIGeCJ0+EFwbHDeJqZWolQ6mEyWpxCqirp\ngaCnfzH2+uofatfBKnHQ1JHrhiX73qfvdAn5XeEzIzU2Z3RgBeYBT/ustbvIvkpg\nqOGe2l9jvN7MCCAPZ8AXImJDNfFjMk2UoMJUJfR4rLyPVX5cMCEPqjQ5VZ6rmRvx\nANyXR9cPdC05FvFE1/J+PsD7vUHZcvpSH5bTPq2ZPgmrPSA7YEPTUYl/Xj68OKAj\nNPQtGv76qDnVtiigrjWtVEB1qK6ERn8bs0WAP3U4pxLqpZZ+xkcS8Ih0Fivkyg+d\nsrybt5ZojL6wm6q/f15BGEkOUdrpLW2noCCUb0p9BUGUJ1kWZIyLCWDC5xJyH55m\nUggfcViixpATMX4KS5lWzD13jDEZEZn1iWA6FyJqogDhV1KDH1Uj8rOfKVxd6QBp\n9WR0PB6b2toxKKX0iE8v0eMt0LsOu99qWjZVUARYFfrTCK/tQCl2V55S65iQfUX9\nZyIHQsQj9eUymoJKXEnutKYogXa0puDGTt2tWAbKuVMIMwIDAQABo4IBLjCCASow\nCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFCcVaVvVE2DEXGJU\ndVWhHU1XJwMfMIHOBgNVHSMEgcYwgcOAFNVOgghwFmM934clC30u64MharpboYGY\npIGVMIGSMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3VhbmdEb25nMREwDwYDVQQH\nEwhTaGVuWmhlbjElMCMGA1UEChMcSHVhd2VpIFRlY2hub2xvZ2llcyBDby4sIEx0\nZDEhMB8GA1UECxQYT1NTICYgU2VydmljZSBUb29scyBEZXB0MRIwEAYDVQQDEwlP\nU1MzLjAgQ0GCEH39xdhw2m4PAAAAAAAAAAAwHQYDVR0RBBYwFIIMMTAuNTcuNjUu\nMjI1hwQKOUHhMA0GCSqGSIb3DQEBCwUAA4ICAQA4G0DJPH9joC1kWSvZSkvbxHDK\nBPDkYdJHfmYq9y8VRvWciwvAl/G06ZOw1GLVIqWDdb46ncx5QuyFERfFouDGMGQ/\n4krBnL1HHYw44S4G/gjEBmXLMUmhbF3F9GgmZsiyxkAkAdveDf4a8xAHm5yCvLQy\nanoZ18Eay4i63uMVDBaS7WHwHsrjUg91vkL8Ti49yoxwA6kDxmub1nredcDd1Nim\nA5JcdpSrIt1Op1JHw3lGTjcwqEpfSq4+xM1D0PpLQGCYuVPIRj4ivGM5MBxvx14s\nzvyfJMFJpG/KuXJE7mfx+VlqGgmo32RgV8CINsZzXPwaANk4F9iFhMUxiEVm7fb9\nmCRN3mjZoId6P+xiutkWfu9niL3Gs3Byya8hRTe10YS3ixrrXF8HqGvQqwFWh+PF\npLjM19BHOGCXhbVCdBKedwMZp3f7+flvzMb/Tb5lKBemRRnaEl8V3ncGlkMOGVB/\ngqraNHjYyouOuh0gFfeJFcAJJnZNpjNK7aFdvnhUGPNi8n+lvSLbsUkyhwH8qPOP\n/T39nFmqtYrTpEkZla5sJOSYMpIHBOZKM4yvjtcFZDoexpOFiWufcMT2Mvq7w1Oc\n4nPsCWrYjyOhD/ED9M/PjWwAN7tTQ5p+mSeV7wVSEdMOqdbpiKvC6VcJleYcAVvy\nptT6RFdA5utMnHUSiw==\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/ssl/trust.cer",
    "content": "Certificate:\n    Data:\n        Version: 3 (0x2)\n        Serial Number:\n            7d:fd:c5:d8:70:da:6e:0f:00:00:00:00:00:00:00:00\n        Signature Algorithm: sha256WithRSAEncryption\n        Issuer: C=CN, ST=GuangDong, L=ShenZhen, O=Huawei Technologies Co., Ltd, OU=OSS & Service Tools Dept, CN=OSS3.0 CA\n        Validity\n            Not Before: Nov  1 00:00:00 2015 GMT\n            Not After : Oct 25 00:00:00 2040 GMT\n        Subject: C=CN, ST=GuangDong, L=ShenZhen, O=Huawei Technologies Co., Ltd, OU=OSS & Service Tools Dept, CN=OSS3.0 CA\n        Subject Public Key Info:\n            Public Key Algorithm: rsaEncryption\n            RSA Public Key: (4096 bit)\n                Modulus (4096 bit):\n                    00:a3:9d:7e:e8:7b:98:9a:d2:7f:fc:7f:4c:cc:79:\n                    d1:80:fa:1d:77:6f:dd:39:83:4d:4a:4a:2d:49:9f:\n                    e4:e8:ca:3a:7b:89:fa:1c:fc:17:0c:4a:bb:6e:6d:\n                    12:cf:e8:d8:bf:e0:70:b7:0f:ca:fc:9d:d6:26:6d:\n                    ae:92:47:70:ad:33:e3:de:50:f9:6f:9a:75:84:c8:\n                    10:a0:46:b6:4b:37:a3:68:ba:bc:86:86:d4:60:44:\n                    2c:38:38:0e:fb:24:ce:e5:53:4b:6b:42:b6:9e:de:\n                    12:f1:25:21:73:f3:87:d0:cc:bb:6b:fb:e6:b3:53:\n                    21:b3:38:2e:55:90:46:0e:07:3e:48:41:35:3c:13:\n                    f0:69:fd:24:b0:cd:4e:1d:d7:ed:66:80:00:01:ff:\n                    31:1c:48:d1:36:1f:82:82:b6:ed:57:c0:b0:af:cd:\n                    7b:55:57:eb:93:8a:62:e0:74:5d:5c:1e:76:98:f9:\n                    3b:f2:21:c0:5c:08:dd:40:fe:c9:d2:8e:26:69:93:\n                    10:cd:bc:1f:48:30:47:d5:5a:0d:4e:3d:24:ca:c5:\n                    c0:72:14:08:38:db:df:03:6c:43:87:c0:bb:70:15:\n                    e7:55:87:b5:53:18:77:e0:78:46:50:c8:74:78:ba:\n                    19:7f:bf:84:7e:fb:87:d9:a1:6c:bd:53:8f:13:4f:\n                    b3:0c:23:66:7b:69:4e:a3:64:de:48:72:76:37:a2:\n                    86:58:74:7f:dd:77:b1:b0:68:93:9c:cf:6b:00:b9:\n                    0f:10:76:bf:9f:3f:8e:86:3d:da:4b:d2:7b:b1:db:\n                    f1:59:81:b7:87:0b:40:a5:38:ad:91:cd:1a:4c:d9:\n                    79:59:e7:54:40:06:68:68:de:6b:8b:54:fd:84:e3:\n                    89:35:fa:bd:8c:1d:0f:4e:0d:a6:ba:39:f8:bd:e6:\n                    88:ca:a0:aa:d7:92:4d:14:75:09:af:bc:10:e1:98:\n                    c5:fa:40:28:bc:04:0d:b0:ad:63:92:eb:27:94:e9:\n                    a8:65:c9:6f:b3:ab:52:c6:8e:87:2f:64:de:d6:11:\n                    69:77:5c:ce:1e:31:45:fb:6f:b4:72:01:ce:2c:c8:\n                    4d:74:f2:48:28:1a:51:a3:14:50:b1:81:13:7a:4b:\n                    d8:05:e5:98:00:78:c9:2f:a2:46:24:a9:8f:9a:b0:\n                    e0:42:78:80:73:da:cb:7f:50:3c:c5:b9:1b:3c:7f:\n                    b6:e1:c0:cf:c6:f0:94:80:8c:64:87:d5:d4:4e:e4:\n                    53:c8:6e:74:0a:f5:e8:b2:a6:56:11:b4:da:14:46:\n                    82:91:7e:63:8e:58:9f:2d:15:41:dc:d0:81:4d:d8:\n                    40:bd:ca:6a:67:42:b5:5b:87:24:70:95:ce:a4:61:\n                    05:60:4b\n                Exponent: 65537 (0x10001)\n        X509v3 extensions:\n            X509v3 Basic Constraints:\n                CA:TRUE\n            X509v3 Key Usage: critical\n                Certificate Sign, CRL Sign\n            X509v3 Subject Key Identifier:\n                D5:4E:82:08:70:16:63:3D:DF:87:25:0B:7D:2E:EB:83:21:6A:BA:5B\n            X509v3 Authority Key Identifier:\n                keyid:D5:4E:82:08:70:16:63:3D:DF:87:25:0B:7D:2E:EB:83:21:6A:BA:5B\n                DirName:/C=CN/ST=GuangDong/L=ShenZhen/O=Huawei Technologies Co., Ltd/OU=OSS & Service Tools Dept/CN=OSS3.0 CA\n                serial:7D:FD:C5:D8:70:DA:6E:0F:00:00:00:00:00:00:00:00\n\n            X509v3 Subject Alternative Name:\n                email:oss3ca@huawei.com\n    Signature Algorithm: sha256WithRSAEncryption\n        8a:52:5f:99:d0:7b:a0:8c:2d:e8:6c:ff:7a:bc:89:64:03:d4:\n        4d:64:7f:91:65:e4:0c:97:2b:0d:44:c4:b0:74:cc:9c:88:03:\n        96:51:db:7c:94:cf:a0:42:23:7d:34:f4:50:be:b1:3d:b6:c3:\n        30:ce:a1:59:f5:f2:76:b0:1e:c3:e2:4a:62:40:54:3e:5e:f3:\n        f1:5f:d9:19:30:27:e7:4d:42:84:b7:14:a3:cc:be:95:9d:77:\n        b2:35:0d:5e:0b:47:07:2c:18:a9:00:be:37:f9:a5:ba:0b:46:\n        4d:0f:30:a7:04:73:3c:ff:f5:a9:80:24:44:81:83:5c:15:d7:\n        37:cf:ab:aa:81:68:22:4f:b9:a6:e2:c5:2f:d7:12:44:9a:0d:\n        be:a9:dc:74:80:07:fe:19:5c:bd:1c:0c:4c:da:13:c4:89:1b:\n        38:29:67:83:57:2d:83:77:4c:9c:77:65:79:46:4b:80:7f:85:\n        14:8a:84:7c:12:89:55:54:44:48:17:da:4d:5d:04:f3:8f:5b:\n        1c:7e:11:7c:d8:27:16:8d:13:e8:e6:e6:25:49:3f:e2:77:0e:\n        f9:9c:3a:51:fb:8e:90:60:25:a9:4f:51:21:58:ac:ab:9f:d0:\n        cc:fb:1d:11:fc:14:a6:0b:47:76:ab:79:7d:e2:27:80:25:9a:\n        6c:df:e1:1a:ca:e2:14:5d:82:2c:94:bb:0b:d1:ac:09:96:75:\n        da:60:02:97:3c:f9:db:53:29:42:07:65:1e:36:f4:df:c1:fe:\n        29:b6:33:97:fb:94:b5:e8:a3:ec:98:da:ed:a2:62:46:7b:31:\n        75:cb:76:b5:63:b7:2f:14:da:c8:1e:5c:1e:8e:17:b2:08:ad:\n        71:93:e0:d9:a1:53:49:89:32:41:80:01:0e:a9:da:52:72:e3:\n        8d:75:b6:fc:51:04:35:8a:ec:bc:7d:b3:d3:c5:30:d6:71:4f:\n        c0:d0:3e:79:02:4d:38:7a:17:13:7c:39:d3:e7:cb:99:72:c1:\n        76:fd:bf:a2:7a:14:e6:d9:48:f6:28:31:98:af:ab:04:ca:78:\n        35:26:51:11:04:f3:ad:0d:33:38:00:14:3d:07:6c:00:cc:9f:\n        f7:ef:ec:e1:e9:1e:4a:1f:27:22:c2:f3:b9:e8:58:7f:54:80:\n        d2:66:c4:01:2b:d2:c2:19:f0:da:10:3d:e9:3a:0e:d5:76:d5:\n        ca:1f:ea:4d:84:b1:d6:ee:4a:c9:bd:4a:fd:72:68:97:75:8e:\n        f6:7d:95:35:0b:ab:72:42:d3:5c:10:bc:d9:44:e9:dd:1c:a1:\n        be:26:04:e4:10:67:45:b4:96:88:77:e3:1d:a1:d0:dc:60:73:\n        75:c0:f7:ac:4b:4b:47:8e\n-----BEGIN CERTIFICATE-----\nMIIG4jCCBMqgAwIBAgIQff3F2HDabg8AAAAAAAAAADANBgkqhkiG9w0BAQsFADCB\nkjELMAkGA1UEBhMCQ04xEjAQBgNVBAgTCUd1YW5nRG9uZzERMA8GA1UEBxMIU2hl\nblpoZW4xJTAjBgNVBAoTHEh1YXdlaSBUZWNobm9sb2dpZXMgQ28uLCBMdGQxITAf\nBgNVBAsUGE9TUyAmIFNlcnZpY2UgVG9vbHMgRGVwdDESMBAGA1UEAxMJT1NTMy4w\nIENBMB4XDTE1MTEwMTAwMDAwMFoXDTQwMTAyNTAwMDAwMFowgZIxCzAJBgNVBAYT\nAkNOMRIwEAYDVQQIEwlHdWFuZ0RvbmcxETAPBgNVBAcTCFNoZW5aaGVuMSUwIwYD\nVQQKExxIdWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkMSEwHwYDVQQLFBhPU1Mg\nJiBTZXJ2aWNlIFRvb2xzIERlcHQxEjAQBgNVBAMTCU9TUzMuMCBDQTCCAiIwDQYJ\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKOdfuh7mJrSf/x/TMx50YD6HXdv3TmD\nTUpKLUmf5OjKOnuJ+hz8FwxKu25tEs/o2L/gcLcPyvyd1iZtrpJHcK0z495Q+W+a\ndYTIEKBGtks3o2i6vIaG1GBELDg4DvskzuVTS2tCtp7eEvElIXPzh9DMu2v75rNT\nIbM4LlWQRg4HPkhBNTwT8Gn9JLDNTh3X7WaAAAH/MRxI0TYfgoK27VfAsK/Ne1VX\n65OKYuB0XVwedpj5O/IhwFwI3UD+ydKOJmmTEM28H0gwR9VaDU49JMrFwHIUCDjb\n3wNsQ4fAu3AV51WHtVMYd+B4RlDIdHi6GX+/hH77h9mhbL1TjxNPswwjZntpTqNk\n3khydjeihlh0f913sbBok5zPawC5DxB2v58/joY92kvSe7Hb8VmBt4cLQKU4rZHN\nGkzZeVnnVEAGaGjea4tU/YTjiTX6vYwdD04Npro5+L3miMqgqteSTRR1Ca+8EOGY\nxfpAKLwEDbCtY5LrJ5TpqGXJb7OrUsaOhy9k3tYRaXdczh4xRftvtHIBzizITXTy\nSCgaUaMUULGBE3pL2AXlmAB4yS+iRiSpj5qw4EJ4gHPay39QPMW5Gzx/tuHAz8bw\nlICMZIfV1E7kU8hudAr16LKmVhG02hRGgpF+Y45Yny0VQdzQgU3YQL3KamdCtVuH\nJHCVzqRhBWBLAgMBAAGjggEwMIIBLDAMBgNVHRMEBTADAQH/MA4GA1UdDwEB/wQE\nAwIBBjAdBgNVHQ4EFgQU1U6CCHAWYz3fhyULfS7rgyFqulswgc4GA1UdIwSBxjCB\nw4AU1U6CCHAWYz3fhyULfS7rgyFquluhgZikgZUwgZIxCzAJBgNVBAYTAkNOMRIw\nEAYDVQQIEwlHdWFuZ0RvbmcxETAPBgNVBAcTCFNoZW5aaGVuMSUwIwYDVQQKExxI\ndWF3ZWkgVGVjaG5vbG9naWVzIENvLiwgTHRkMSEwHwYDVQQLFBhPU1MgJiBTZXJ2\naWNlIFRvb2xzIERlcHQxEjAQBgNVBAMTCU9TUzMuMCBDQYIQff3F2HDabg8AAAAA\nAAAAADAcBgNVHREEFTATgRFvc3MzY2FAaHVhd2VpLmNvbTANBgkqhkiG9w0BAQsF\nAAOCAgEAilJfmdB7oIwt6Gz/eryJZAPUTWR/kWXkDJcrDUTEsHTMnIgDllHbfJTP\noEIjfTT0UL6xPbbDMM6hWfXydrAew+JKYkBUPl7z8V/ZGTAn501ChLcUo8y+lZ13\nsjUNXgtHBywYqQC+N/mlugtGTQ8wpwRzPP/1qYAkRIGDXBXXN8+rqoFoIk+5puLF\nL9cSRJoNvqncdIAH/hlcvRwMTNoTxIkbOClng1ctg3dMnHdleUZLgH+FFIqEfBKJ\nVVRESBfaTV0E849bHH4RfNgnFo0T6ObmJUk/4ncO+Zw6UfuOkGAlqU9RIVisq5/Q\nzPsdEfwUpgtHdqt5feIngCWabN/hGsriFF2CLJS7C9GsCZZ12mAClzz521MpQgdl\nHjb038H+KbYzl/uUteij7Jja7aJiRnsxdct2tWO3LxTayB5cHo4XsgitcZPg2aFT\nSYkyQYABDqnaUnLjjXW2/FEENYrsvH2z08Uw1nFPwNA+eQJNOHoXE3w50+fLmXLB\ndv2/onoU5tlI9igxmK+rBMp4NSZREQTzrQ0zOAAUPQdsAMyf9+/s4ekeSh8nIsLz\nuehYf1SA0mbEASvSwhnw2hA96ToO1XbVyh/qTYSx1u5Kyb1K/XJol3WO9n2VNQur\nckLTXBC82UTp3RyhviYE5BBnRbSWiHfjHaHQ3GBzdcD3rEtLR44=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "foundations/foundation-ssl/src/test/resources/ssl/white.list",
    "content": "127.0.0.1\n10.67.190.60\n10.67.147.115\n10.57.65.225\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>foundations</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>foundation-test-scaffolding</artifactId>\n  <name>Java Chassis::Foundations::Test Scaffolding</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-context</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-web</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>provided</scope>\n      <optional>true</optional>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n      <scope>provided</scope>\n      <optional>true</optional>\n    </dependency>\n    <dependency>\n      <groupId>com.fasterxml.jackson.core</groupId>\n      <artifactId>jackson-annotations</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>javax.inject</groupId>\n      <artifactId>javax.inject</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-aspects</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.swagger.core.v3</groupId>\n      <artifactId>swagger-core-jakarta</artifactId>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.assertj</groupId>\n      <artifactId>assertj-core</artifactId>\n      <scope>compile</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/AssertUtils.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.foundation.test.scaffolding;\r\n\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\n\r\nimport org.assertj.core.api.AbstractStringAssert;\r\n\r\nimport io.netty.handler.codec.string.LineSeparator;\r\nimport io.vertx.core.json.Json;\r\n\r\npublic interface AssertUtils {\r\n  static AbstractStringAssert<?> assertPrettyJson(Object value) {\r\n    String json = Json.encodePrettily(value)\r\n        .replace(LineSeparator.WINDOWS.value(), LineSeparator.UNIX.value());\r\n    return assertThat(json);\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/exception/RuntimeExceptionWithoutStackTrace.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.test.scaffolding.exception;\n\npublic class RuntimeExceptionWithoutStackTrace extends RuntimeException {\n  private static final long serialVersionUID = -1L;\n\n  public RuntimeExceptionWithoutStackTrace() {\n  }\n\n  public RuntimeExceptionWithoutStackTrace(String message) {\n    super(message);\n  }\n\n  @Override\n  public synchronized Throwable fillInStackTrace() {\n    return this;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.test.scaffolding.log;\n\nimport java.io.Closeable;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.stream.Collectors;\n\nimport org.apache.logging.log4j.Level;\nimport org.apache.logging.log4j.LogManager;\nimport org.apache.logging.log4j.core.Appender;\nimport org.apache.logging.log4j.core.LogEvent;\nimport org.apache.logging.log4j.core.LoggerContext;\nimport org.apache.logging.log4j.core.appender.AbstractAppender;\nimport org.apache.logging.log4j.core.config.Configuration;\nimport org.apache.logging.log4j.core.config.Property;\nimport org.apache.logging.log4j.core.layout.PatternLayout;\n\npublic class LogCollector implements Closeable {\n  List<LogEvent> events = new ArrayList<>();\n\n  Appender appender;\n\n  String appenderName;\n\n  public LogCollector() {\n    LoggerContext ctx = (LoggerContext) LogManager.getContext(false);\n    Configuration config = ctx.getConfiguration();\n    appenderName = \"LogCollector\" + System.nanoTime();\n    appender = new AbstractAppender(appenderName, null, PatternLayout.createDefaultLayout(),\n        true,\n        Property.EMPTY_ARRAY) {\n      @Override\n      public void append(LogEvent event) {\n        events.add(event);\n      }\n    };\n    appender.start();\n    config.getRootLogger().addAppender(appender, Level.ALL, null);\n    ctx.updateLoggers(config);\n  }\n\n  public LogCollector setLogLevel(String logName, Level level) {\n    LoggerContext ctx = (LoggerContext) LogManager.getContext(false);\n    Configuration config = ctx.getConfiguration();\n    config.getLoggerConfig(logName).setLevel(level);\n    return this;\n  }\n\n  public List<LogEvent> getEvents() {\n    return events;\n  }\n\n  public LogEvent getEvent(int index) {\n    return events.get(index);\n  }\n\n  public LogEvent getLastEvents() {\n    return events.get(events.size() - 1);\n  }\n\n  public List<Throwable> getThrowables() {\n    return events.stream()\n        .map(LogEvent::getThrown)\n        .filter(Objects::nonNull)\n        .collect(Collectors.toList());\n  }\n\n  public List<String> getThrowableMessages() {\n    return events.stream()\n        .filter(e -> e.getThrown() != null)\n        .map(e -> e.getThrown().getMessage())\n        .collect(Collectors.toList());\n  }\n\n  public void tearDown() {\n    LoggerContext ctx = (LoggerContext) LogManager.getContext(false);\n    Configuration config = ctx.getConfiguration();\n    appender.stop();\n    config.getRootLogger().removeAppender(appenderName);\n    ctx.updateLoggers(config);\n  }\n\n  public void clear() {\n    events = new ArrayList<>();\n  }\n\n  @Override\n  public void close() {\n    tearDown();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/model/Color.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.model;\n\npublic enum Color {\n  RED,\n  YELLOW,\n  BLUE\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/model/Empty.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.model;\n\npublic class Empty {\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/model/Media.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.model;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\n/**\n * To test the situation that enum values are specified by {@link JsonProperty}.\n */\npublic enum Media {\n  @JsonProperty(\"AAC\")\n  AAC,\n  @JsonProperty\n  FLAC,\n  @JsonProperty(\"H.264\")\n  H_264,\n  @JsonProperty(\"MPEG-2\")\n  MPEG_2,\n  WMV\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/model/People.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.model;\n\nimport java.util.List;\n\npublic class People {\n  public String name;\n\n  public List<People> friends;\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/model/User.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.model;\n\nimport java.util.List;\n\nimport io.swagger.v3.oas.annotations.media.ArraySchema;\nimport io.swagger.v3.oas.annotations.media.Schema;\n\npublic class User {\n  public String name;\n\n  // An issue not fixed by open api\n  // see: https://github.com/swagger-api/swagger-core/issues/3484\n  @ArraySchema(schema = @Schema(implementation = User.class))\n  public List<User> friends;\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/spring/SpringUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.spring;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.UUID;\n\nimport javax.inject.Inject;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.MapPropertySource;\nimport org.springframework.core.env.StandardEnvironment;\nimport org.springframework.util.StringValueResolver;\n\npublic final class SpringUtils {\n  private SpringUtils() {\n  }\n\n  public static StringValueResolver createStringValueResolver(Map<String, Object> map) {\n    StandardEnvironment standardEnvironment = new StandardEnvironment();\n    standardEnvironment.getPropertySources().addFirst(\n        new MapPropertySource(UUID.randomUUID().toString(), map));\n\n    return standardEnvironment::resolvePlaceholders;\n  }\n\n  public static void ensureNoInject(Class<?> cls) {\n    for (Field field : cls.getDeclaredFields()) {\n      if (field.getAnnotation(Inject.class) != null) {\n        throw new IllegalStateException(String\n            .format(\"field %s:%s has %s annotation\",\n                cls.getName(),\n                field.getName(),\n                Inject.class.getName()));\n      }\n\n      if (field.getAnnotation(Autowired.class) != null) {\n        throw new IllegalStateException(String\n            .format(\"field %s:%s has %s annotation\",\n                cls.getName(),\n                field.getName(),\n                Autowired.class.getName()));\n      }\n    }\n\n    for (Method method : cls.getDeclaredMethods()) {\n      if (method.getAnnotation(Inject.class) != null) {\n        throw new IllegalStateException(String\n            .format(\"method %s:%s has %s annotation\",\n                cls.getName(),\n                method.getName(),\n                Inject.class.getName()));\n      }\n\n      if (method.getAnnotation(Autowired.class) != null) {\n        throw new IllegalStateException(String\n            .format(\"method %s:%s has %s annotation\",\n                cls.getName(),\n                method.getName(),\n                Autowired.class.getName()));\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/time/MockClock.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.test.scaffolding.time;\n\nimport java.time.Clock;\nimport java.time.Instant;\nimport java.time.ZoneId;\n\npublic class MockClock extends Clock {\n  private MockValues<Long> values;\n\n  public MockClock() {\n    this(0L);\n  }\n\n  public MockClock(Long... values) {\n    this.setValues(values);\n  }\n\n  public MockClock setValues(Long... values) {\n    this.values = new MockValues<Long>()\n        .setDefaultValue(0L)\n        .setValues(values);\n    return this;\n  }\n\n  @Override\n  public ZoneId getZone() {\n    return null;\n  }\n\n  @Override\n  public Clock withZone(ZoneId zone) {\n    return null;\n  }\n\n  @Override\n  public Instant instant() {\n    return null;\n  }\n\n  @Override\n  public long millis() {\n    return values.read();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/time/MockTicker.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.foundation.test.scaffolding.time;\r\n\r\nimport com.google.common.base.Ticker;\r\n\r\npublic class MockTicker extends Ticker {\r\n  private MockValues<Long> values;\r\n\r\n  public MockTicker() {\r\n    this(0L);\r\n  }\r\n\r\n  public MockTicker(Long... values) {\r\n    this.setValues(values);\r\n  }\r\n\r\n  public MockTicker setValues(Long... values) {\r\n    this.values = new MockValues<Long>()\r\n        .setDefaultValue(0L)\r\n        .setValues(values);\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public long read() {\r\n    return values.read();\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/time/MockValues.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.foundation.test.scaffolding.time;\r\n\r\npublic class MockValues<T> {\r\n  private T defaultValue;\r\n\r\n  private T[] values;\r\n\r\n  private int index;\r\n\r\n  public MockValues<T> setDefaultValue(T defaultValue) {\r\n    this.defaultValue = defaultValue;\r\n    return this;\r\n  }\r\n\r\n  public MockValues<T> setValues(T[] values) {\r\n    this.values = values;\r\n    this.index = 0;\r\n    return this;\r\n  }\r\n\r\n  public T read() {\r\n    if (values == null || values.length == 0) {\r\n      return defaultValue;\r\n    }\r\n\r\n    if (index >= values.length) {\r\n      return values[values.length - 1];\r\n    }\r\n\r\n    T value = values[index];\r\n    index++;\r\n    return value;\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-vertx/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>foundations</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>foundation-vertx</artifactId>\n  <name>Java Chassis::Foundations::Vertx</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-web</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-ssl</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/AddressResolverConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.dns.AddressResolverOptions;\n\npublic class AddressResolverConfig {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(AddressResolverConfig.class);\n\n  /**\n   * get the target endpoints with custom address resolve config\n   * @param tag config tag, such as sc.consumer or cc.consumer\n   * @return AddressResolverOptions\n   */\n  public static AddressResolverOptions getAddressResolverOptions(String tag) {\n    AddressResolverOptions addressResolverOptions = new AddressResolverOptions();\n    addressResolverOptions\n        .setServers(getStringListProperty(\n            AddressResolverOptions.DEFAULT_SERVERS,\n            \"addressResolver.\" + tag + \".servers\",\n            \"addressResolver.servers\"));\n    addressResolverOptions\n        .setOptResourceEnabled(getBooleanProperty(\n            AddressResolverOptions.DEFAULT_OPT_RESOURCE_ENABLED,\n            \"addressResolver.\" + tag + \".optResourceEnabled\",\n            \"addressResolver.optResourceEnabled\"));\n    addressResolverOptions\n        .setCacheMinTimeToLive(getPositiveIntProperty(\n            AddressResolverOptions.DEFAULT_CACHE_MIN_TIME_TO_LIVE,\n            \"addressResolver.\" + tag + \".cacheMinTimeToLive\",\n            \"addressResolver.cacheMinTimeToLive\"));\n    addressResolverOptions\n        .setCacheMaxTimeToLive(getPositiveIntProperty(\n            AddressResolverOptions.DEFAULT_CACHE_MAX_TIME_TO_LIVE,\n            \"addressResolver.\" + tag + \".cacheMaxTimeToLive\",\n            \"addressResolver.cacheMaxTimeToLive\"));\n    addressResolverOptions\n        .setCacheNegativeTimeToLive(getPositiveIntProperty(\n            AddressResolverOptions.DEFAULT_CACHE_NEGATIVE_TIME_TO_LIVE,\n            \"addressResolver.\" + tag + \".cacheNegativeTimeToLive\",\n            \"addressResolver.cacheNegativeTimeToLive\"));\n    addressResolverOptions\n        .setQueryTimeout(getPositiveIntProperty(\n            AddressResolverOptions.DEFAULT_QUERY_TIMEOUT,\n            \"addressResolver.\" + tag + \".queryTimeout\",\n            \"addressResolver.queryTimeout\"));\n    addressResolverOptions\n        .setMaxQueries(getPositiveIntProperty(\n            AddressResolverOptions.DEFAULT_MAX_QUERIES,\n            \"addressResolver.\" + tag + \".maxQueries\",\n            \"addressResolver.maxQueries\"));\n    addressResolverOptions\n        .setRdFlag(getBooleanProperty(\n            AddressResolverOptions.DEFAULT_RD_FLAG,\n            \"addressResolver.\" + tag + \".rdFlag\",\n            \"addressResolver.rdFlag\"));\n    addressResolverOptions\n        .setSearchDomains(getStringListProperty(\n            AddressResolverOptions.DEFAULT_SEARCH_DOMAINS,\n            \"addressResolver.\" + tag + \".searchDomains\",\n            \"addressResolver.searchDomains\"));\n    addressResolverOptions\n        .setNdots(getPositiveIntProperty(\n            AddressResolverOptions.DEFAULT_NDOTS,\n            \"addressResolver.\" + tag + \".ndots\",\n            \"addressResolver.ndots\"));\n    addressResolverOptions\n        .setRotateServers(getBooleanProperty(\n            AddressResolverOptions.DEFAULT_ROTATE_SERVERS,\n            \"addressResolver.\" + tag + \".rotateServers\",\n            \"addressResolver.rotateServers\"));\n    return addressResolverOptions;\n  }\n\n  private static List<String> getStringListProperty(List<String> defaultValue, String... keys) {\n    for (String key : keys) {\n      String[] vals = LegacyPropertyFactory.getProperty(key, String[].class);\n      if (vals != null && vals.length > 0) {\n        return Arrays.asList(vals);\n      }\n    }\n    return defaultValue;\n  }\n\n  private static int getPositiveIntProperty(int defaultValue, String... keys) {\n    for (String key : keys) {\n      Integer val = LegacyPropertyFactory.getProperty(key, Integer.class);\n      if (val != null && val <= 0) {\n        LOGGER.warn(\"Address resolver key:{}'s value:{} is not positive, please check!\", key, val);\n        continue;\n      }\n      if (val != null) {\n        return val;\n      }\n    }\n    return defaultValue;\n  }\n\n  private static boolean getBooleanProperty(boolean defaultValue,\n      String... keys) {\n    for (String key : keys) {\n      Boolean val = LegacyPropertyFactory.getProperty(key, Boolean.class);\n      if (val != null) {\n        return val;\n      }\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/AsyncResultCallback.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport io.vertx.core.AsyncResult;\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\n\npublic interface AsyncResultCallback<T> extends Handler<AsyncResult<T>> {\n  default void success(T data) {\n    handle(Future.succeededFuture(data));\n  }\n\n  default void fail(Throwable e) {\n    handle(Future.failedFuture(e));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/ConnectionEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\npublic enum ConnectionEvent {\n  Connected,\n  Closed\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SharedVertxFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.DefaultVertxMetricsFactory;\nimport org.apache.servicecomb.foundation.vertx.metrics.MetricsOptionsEx;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.shareddata.Shareable;\n\npublic class SharedVertxFactory {\n  static class SharedVertxInfo implements Shareable {\n    public VertxOptions vertxOptions = new VertxOptions();\n\n    public DefaultVertxMetricsFactory metricsFactory = new DefaultVertxMetricsFactory();\n\n    public MetricsOptionsEx metricsOptionsEx = (MetricsOptionsEx) metricsFactory.newOptions();\n\n    public SharedVertxInfo(Environment environment) {\n      vertxOptions.setMetricsOptions(metricsOptionsEx);\n      vertxOptions.setEventLoopPoolSize(readEventLoopPoolSize(environment, \"servicecomb.transport.eventloop.size\"));\n    }\n\n    private static int readEventLoopPoolSize(Environment environment, String key) {\n      int count = environment.getProperty(key, int.class, -1);\n      if (count > 0) {\n        return count;\n      }\n      return VertxOptions.DEFAULT_EVENT_LOOP_POOL_SIZE;\n    }\n  }\n\n  private static final String LOCAL_MAP_NAME = \"scb\";\n\n  private static final String INFO = \"transport-vertx-info\";\n\n  public static DefaultVertxMetricsFactory getMetricsFactory(Environment environment) {\n    SharedVertxInfo info = (SharedVertxInfo) getSharedVertx(environment).sharedData().getLocalMap(LOCAL_MAP_NAME)\n        .get(INFO);\n    return info.metricsFactory;\n  }\n\n  public static Vertx getSharedVertx(Environment environment) {\n    return VertxUtils.getVertxMap().computeIfAbsent(\"transport\",\n        key -> createSharedVertx(environment, key));\n  }\n\n  private static Vertx createSharedVertx(Environment environment, String name) {\n    SharedVertxInfo info = new SharedVertxInfo(environment);\n\n    Vertx vertx = VertxUtils.init(name, info.vertxOptions, info.metricsFactory);\n    info.metricsFactory.setVertx(vertx, info.vertxOptions);\n    vertx.sharedData().getLocalMap(LOCAL_MAP_NAME).put(INFO, info);\n\n    return vertx;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SimpleBodyHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.http.HttpHeaders;\n\nimport io.vertx.ext.web.RoutingContext;\nimport io.vertx.ext.web.handler.impl.BodyHandlerImpl;\n\n/**\n * 扩展的BodyHandler\n * 只支持指定ContentType格式的body数据，关闭了文件上传能力\n */\npublic abstract class SimpleBodyHandler extends BodyHandlerImpl {\n\n  @Override\n  public void handle(RoutingContext context) {\n    if (this.checkContentType(context)) {\n      super.handle(context);\n    }\n  }\n\n  protected boolean checkContentType(RoutingContext context) {\n    String contentType = context.request().getHeader(HttpHeaders.CONTENT_TYPE);\n    if (contentTypeSupported(contentType)) {\n      return true;\n    }\n    Status status = Status.UNSUPPORTED_MEDIA_TYPE;\n    context.response().setStatusCode(status.getStatusCode()).setStatusMessage(status.getReasonPhrase());\n    context.response().end(String.format(\"Content-Type %s is not supported\", contentType));\n    return false;\n  }\n\n  protected abstract boolean contentTypeSupported(String contentType);\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SimpleJsonObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport io.vertx.core.json.JsonObject;\n\npublic class SimpleJsonObject extends JsonObject {\n  /**\n   * 直接保存进map，规避原来的put不支持Object的问题\n   */\n  @Override\n  public JsonObject put(String key, Object value) {\n    getMap().put(key, value);\n    return this;\n  }\n\n  /**\n   * 不必复制，直接使用，规避原来的copy不支持Object的问题\n   */\n  @Override\n  public JsonObject copy() {\n    return this;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/TransportType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\npublic enum TransportType {\n  Highway,\n  Rest\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\npublic final class VertxConst {\n  public static final String PROXY_PRE_NAME = \"servicecomb.proxy.\";\n\n  public static final String PROXY_ENABLE = PROXY_PRE_NAME + \"enable\";\n\n  public static final String PROXY_HOST = PROXY_PRE_NAME + \"host\";\n\n  public static final String PROXY_PORT = PROXY_PRE_NAME + \"port\";\n\n  public static final String PROXY_USERNAME = PROXY_PRE_NAME + \"username\";\n\n  public static final String PROXY_PASSWD = PROXY_PRE_NAME + \"passwd\";\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxTLSBuilder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport java.io.File;\nimport java.net.URL;\nimport java.util.Arrays;\nimport java.util.HashSet;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLManager;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.ssl.SSLOptionFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.http.ClientAuth;\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.WebSocketClientOptions;\nimport io.vertx.core.net.ClientOptionsBase;\nimport io.vertx.core.net.JksOptions;\nimport io.vertx.core.net.NetServerOptions;\nimport io.vertx.core.net.OpenSSLEngineOptions;\nimport io.vertx.core.net.PfxOptions;\nimport io.vertx.core.net.TCPSSLOptions;\n\npublic final class VertxTLSBuilder {\n  private static final Logger LOGGER = LoggerFactory.getLogger(VertxTLSBuilder.class);\n\n  private static final String STORE_PKCS12 = \"PKCS12\";\n\n  private static final String STORE_JKS = \"JKS\";\n\n  private VertxTLSBuilder() {\n\n  }\n\n  public static NetServerOptions buildNetServerOptions(SSLOption sslOption, SSLCustom sslCustom,\n      NetServerOptions netServerOptions) {\n    buildTCPSSLOptions(sslOption, sslCustom, netServerOptions);\n    setClientAuth(sslOption, netServerOptions);\n    return netServerOptions;\n  }\n\n  private static void setClientAuth(SSLOption sslOption, NetServerOptions netServerOptions) {\n    if (sslOption.isAuthPeer() || org.apache.servicecomb.foundation.ssl.ClientAuth.REQUIRED\n        .equals(sslOption.getClientAuth())) {\n      netServerOptions.setClientAuth(ClientAuth.REQUIRED);\n      return;\n    }\n\n    if (org.apache.servicecomb.foundation.ssl.ClientAuth.NONE\n        .equals(sslOption.getClientAuth())) {\n      netServerOptions.setClientAuth(ClientAuth.NONE);\n      return;\n    }\n\n    netServerOptions.setClientAuth(ClientAuth.REQUEST);\n    return;\n  }\n\n  public static void buildHttpClientOptions(String sslKey, HttpClientOptions httpClientOptions) {\n    SSLOptionFactory factory = SSLOptionFactory.createSSLOptionFactory(sslKey, LegacyPropertyFactory.getEnvironment());\n    SSLOption sslOption;\n    if (factory == null) {\n      sslOption = SSLOption.build(sslKey, LegacyPropertyFactory.getEnvironment());\n    } else {\n      sslOption = factory.createSSLOption();\n    }\n    SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass());\n    buildHttpClientOptions(sslOption, sslCustom, httpClientOptions);\n  }\n\n  public static void buildWebSocketClientOptions(String sslKey, WebSocketClientOptions webSocketClientOptions) {\n    SSLOptionFactory factory = SSLOptionFactory.createSSLOptionFactory(sslKey, LegacyPropertyFactory.getEnvironment());\n    SSLOption sslOption;\n    if (factory == null) {\n      sslOption = SSLOption.build(sslKey, LegacyPropertyFactory.getEnvironment());\n    } else {\n      sslOption = factory.createSSLOption();\n    }\n    SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass());\n    buildWebSocketClientOptions(sslOption, sslCustom, webSocketClientOptions);\n  }\n\n  public static HttpClientOptions buildHttpClientOptions(SSLOption sslOption, SSLCustom sslCustom,\n      HttpClientOptions httpClientOptions) {\n    buildClientOptionsBase(sslOption, sslCustom, httpClientOptions);\n    httpClientOptions.setVerifyHost(sslOption.isCheckCNHost());\n    return httpClientOptions;\n  }\n\n  public static WebSocketClientOptions buildWebSocketClientOptions(SSLOption sslOption, SSLCustom sslCustom,\n      WebSocketClientOptions webSocketClientOptions) {\n    buildClientOptionsBase(sslOption, sslCustom, webSocketClientOptions);\n    webSocketClientOptions.setVerifyHost(sslOption.isCheckCNHost());\n    return webSocketClientOptions;\n  }\n\n  public static ClientOptionsBase buildClientOptionsBase(SSLOption sslOption, SSLCustom sslCustom,\n      ClientOptionsBase clientOptionsBase) {\n    buildTCPSSLOptions(sslOption, sslCustom, clientOptionsBase);\n\n    if (sslOption.isAuthPeer()) {\n      clientOptionsBase.setTrustAll(false);\n    } else {\n      clientOptionsBase.setTrustAll(true);\n    }\n    return clientOptionsBase;\n  }\n\n  private static TCPSSLOptions buildTCPSSLOptions(SSLOption sslOption, SSLCustom sslCustom,\n      TCPSSLOptions tcpClientOptions) {\n    tcpClientOptions.setSsl(true);\n\n    if (sslOption.getEngine().equalsIgnoreCase(\"openssl\")) {\n      tcpClientOptions.setSslEngineOptions(new OpenSSLEngineOptions());\n    }\n    String fullKeyStore = sslCustom.getFullPath(sslOption.getKeyStore());\n    if (isFileExists(fullKeyStore)) {\n      if (STORE_PKCS12.equalsIgnoreCase(sslOption.getKeyStoreType())) {\n        PfxOptions keyPfxOptions = new PfxOptions();\n        keyPfxOptions.setPath(fullKeyStore);\n        keyPfxOptions.setPassword(new String(sslCustom.decode(sslOption.getKeyStoreValue().toCharArray())));\n        tcpClientOptions.setKeyCertOptions(keyPfxOptions);\n      } else if (STORE_JKS.equalsIgnoreCase(sslOption.getKeyStoreType())) {\n        JksOptions keyJksOptions = new JksOptions();\n        keyJksOptions.setPath(fullKeyStore);\n        keyJksOptions.setPassword(new String(sslCustom.decode(sslOption.getKeyStoreValue().toCharArray())));\n        tcpClientOptions.setKeyCertOptions(keyJksOptions);\n      } else {\n        throw new IllegalArgumentException(\"invalid key store type.\");\n      }\n    } else {\n      LOGGER.warn(\"keyStore [\" + fullKeyStore + \"] file not exist, please check!\");\n    }\n    String fullTrustStore = sslCustom.getFullPath(sslOption.getTrustStore());\n    if (isFileExists(fullTrustStore)) {\n      if (STORE_PKCS12.equalsIgnoreCase(sslOption.getTrustStoreType())) {\n        PfxOptions trustPfxOptions = new PfxOptions();\n        trustPfxOptions.setPath(fullTrustStore);\n        trustPfxOptions\n            .setPassword(new String(sslCustom.decode(sslOption.getTrustStoreValue().toCharArray())));\n        tcpClientOptions.setTrustOptions(trustPfxOptions);\n      } else if (STORE_JKS.equalsIgnoreCase(sslOption.getTrustStoreType())) {\n        JksOptions trustJksOptions = new JksOptions();\n        trustJksOptions.setPath(fullTrustStore);\n        trustJksOptions\n            .setPassword(new String(sslCustom.decode(sslOption.getTrustStoreValue().toCharArray())));\n        tcpClientOptions.setTrustOptions(trustJksOptions);\n      } else {\n        throw new IllegalArgumentException(\"invalid trust store type.\");\n      }\n    } else {\n      LOGGER.warn(\"trustStore [\" + fullTrustStore + \"] file not exist, please check!\");\n    }\n\n    tcpClientOptions\n        .setEnabledSecureTransportProtocols(new HashSet<>(Arrays.asList(sslOption.getProtocols().split(\",\"))));\n\n    for (String cipher : SSLManager.getEnabledCiphers(sslOption)) {\n      tcpClientOptions.addEnabledCipherSuite(cipher);\n    }\n\n    if (isFileExists(sslCustom.getFullPath(sslOption.getCrl()))) {\n      tcpClientOptions.addCrlPath(sslCustom.getFullPath(sslOption.getCrl()));\n    }\n    return tcpClientOptions;\n  }\n\n  private static boolean isFileExists(String name) {\n    if (StringUtils.isEmpty(name)) {\n      return false;\n    }\n    File f = new File(name);\n    if (f.isFile()) {\n      return true;\n    }\n\n    try {\n      ClassLoader classLoader =\n          Thread.currentThread().getContextClassLoader() == null ? VertxTLSBuilder.class.getClassLoader()\n              : Thread.currentThread().getContextClassLoader();\n      URL resource = classLoader.getResource(name);\n      return resource != null;\n    } catch (Exception e) {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.management.ManagementFactory;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;\nimport org.apache.servicecomb.foundation.vertx.client.ClientVerticle;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.netty.buffer.ByteBuf;\nimport io.vertx.core.AbstractVerticle;\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.Future;\nimport io.vertx.core.Verticle;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.impl.SysProps;\nimport io.vertx.core.impl.VertxThread;\nimport io.vertx.core.internal.VertxBootstrap;\nimport io.vertx.core.spi.VertxMetricsFactory;\nimport io.vertx.core.spi.VertxThreadFactory;\nimport io.vertx.core.transport.Transport;\n\n/**\n * VertxUtils\n *\n *\n */\npublic final class VertxUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(VertxUtils.class);\n\n  private static final long BLOCKED_THREAD_CHECK_INTERVAL = Long.MAX_VALUE / 2;\n\n  // key为vertx实例名称，以支撑vertx功能分组\n  private static final Map<String, Vertx> vertxMap = new ConcurrentHashMapEx<>();\n\n  private VertxUtils() {\n  }\n\n  public static Map<String, Vertx> getVertxMap() {\n    return vertxMap;\n  }\n\n  public static <T extends AbstractVerticle> void deployVerticle(Vertx vertx, Class<T> cls, int instanceCount) {\n    DeploymentOptions options = new DeploymentOptions().setInstances(instanceCount);\n    vertx.deployVerticle(cls.getName(), options);\n  }\n\n  public static <CLIENT_POOL> DeploymentOptions createClientDeployOptions(\n      ClientPoolManager<CLIENT_POOL> clientMgr,\n      int instanceCount) {\n    DeploymentOptions options = new DeploymentOptions().setInstances(instanceCount);\n    SimpleJsonObject config = new SimpleJsonObject();\n    config.put(ClientVerticle.CLIENT_MGR, clientMgr);\n    options.setConfig(config);\n\n    return options;\n  }\n\n  // deploy Verticle and wait for its success. do not call this method in event-loop thread\n  public static <VERTICLE extends Verticle> Map<String, Object> blockDeploy(Vertx vertx,\n      Class<VERTICLE> cls,\n      DeploymentOptions options) throws InterruptedException {\n    Map<String, Object> result = new HashMap<>();\n\n    CountDownLatch latch = new CountDownLatch(1);\n    Future<String> future = vertx.deployVerticle(cls.getName(), options);\n    future.onComplete((success, failure) -> {\n      result.put(\"code\", failure == null);\n\n      if (failure != null) {\n        result.put(\"message\", failure.getMessage());\n        LOGGER.error(\"deploy vertx failed, cause \", failure);\n      }\n\n      latch.countDown();\n    });\n\n    latch.await();\n\n    return result;\n  }\n\n  public static Vertx getOrCreateVertxByName(String name, VertxOptions vertxOptions,\n      VertxMetricsFactory metricsFactory) {\n    return vertxMap.computeIfAbsent(name, vertxName -> init(name, vertxOptions, metricsFactory));\n  }\n\n  public static Vertx init(String name, VertxOptions vertxOptions, VertxMetricsFactory metricsFactory) {\n    if (vertxOptions == null) {\n      vertxOptions = new VertxOptions();\n    }\n\n    boolean isDebug = ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains(\"jdwp\");\n    if (isDebug) {\n      vertxOptions.setBlockedThreadCheckInterval(BLOCKED_THREAD_CHECK_INTERVAL);\n      LOGGER.info(\"in debug mode, disable blocked thread check.\");\n    }\n\n    configureVertxFileCaching(vertxOptions);\n\n    VertxBootstrap bootstrap = bootstrap(vertxOptions, metricsFactory)\n        .threadFactory(new VertxThreadFactory() {\n          @Override\n          public VertxThread newVertxThread(Runnable target, String threadName, boolean worker, long maxExecTime,\n              TimeUnit maxExecTimeUnit) {\n            return VertxThreadFactory.super\n                .newVertxThread(target, name + \"-\" + threadName, worker, maxExecTime, maxExecTimeUnit);\n          }\n        });\n\n    return bootstrap.init().vertx();\n  }\n\n  private static VertxBootstrap bootstrap(VertxOptions options, VertxMetricsFactory metricsFactory) {\n    VertxBootstrap bootstrap = VertxBootstrap.create();\n    bootstrap.options(options);\n    bootstrap.metricsFactory(metricsFactory);\n    Transport tr;\n    if (options.getPreferNativeTransport()) {\n      tr = Transport.nativeTransport();\n    } else {\n      tr = Transport.NIO;\n    }\n    bootstrap.transport(tr.implementation());\n    return bootstrap;\n  }\n\n  /**\n   * 配置vertx的文件缓存功能，默认关闭\n   */\n  private static void configureVertxFileCaching(VertxOptions vertxOptions) {\n    boolean disableFileCPResolving = LegacyPropertyFactory\n        .getBooleanProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, true);\n    vertxOptions.getFileSystemOptions().setClassPathResolvingEnabled(!disableFileCPResolving);\n  }\n\n  // try to reference byte[]\n  // otherwise copy byte[]\n  public static byte[] getBytesFast(InputStream inputStream) throws IOException {\n    if (inputStream instanceof BufferInputStream) {\n      return getBytesFast(((BufferInputStream) inputStream).getByteBuf());\n    }\n\n    return IOUtils.toByteArray(inputStream);\n  }\n\n  public static byte[] getBytesFast(Buffer buffer) {\n    byte[] arr = new byte[buffer.length()];\n    buffer.getBytes(arr, 0);\n    return arr;\n  }\n\n  public static byte[] getBytesFast(ByteBuf byteBuf) {\n    if (byteBuf.hasArray()) {\n      return byteBuf.array();\n    }\n\n    byte[] arr = new byte[byteBuf.writerIndex()];\n    byteBuf.getBytes(0, arr);\n    return arr;\n  }\n\n  public static CompletableFuture<Void> closeVertxByName(String name) {\n    LOGGER.info(\"Closing vertx {}.\", name);\n    CompletableFuture<Void> future = new CompletableFuture<>();\n    Vertx vertx = vertxMap.remove(name);\n    if (vertx == null) {\n      LOGGER.info(\"Vertx {} not exist.\", name);\n      future.complete(null);\n      return future;\n    }\n\n    Future<Void> closeFuture = vertx.close();\n    closeFuture.onComplete((succ, fail) -> {\n      if (fail == null) {\n        LOGGER.info(\"Success to close vertx {}.\", name);\n        future.complete(null);\n        return;\n      }\n\n      future.completeExceptionally(fail);\n    });\n\n    return future;\n  }\n\n  public static void blockCloseVertxByName(String name) {\n    CompletableFuture<Void> future = closeVertxByName(name);\n    try {\n      future.get(30, TimeUnit.SECONDS);\n    } catch (Throwable e) {\n      LOGGER.error(\"Failed to wait close vertx {}.\", name, e);\n    }\n  }\n\n  public static void blockCloseVertx(Vertx vertx) {\n    CountDownLatch latch = new CountDownLatch(1);\n    Future<Void> closeFuture = vertx.close();\n    closeFuture.onComplete((succ, fail) -> {\n      if (fail == null) {\n        LOGGER.info(\"Success to close vertx {}.\", vertx);\n      } else {\n        LOGGER.info(\"Failed to close vertx {}.\", vertx);\n      }\n\n      latch.countDown();\n    });\n\n    try {\n      latch.await(30, TimeUnit.SECONDS);\n    } catch (Throwable e) {\n      LOGGER.info(\"Failed to wait close vertx {}.\", vertx);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/ClientPoolFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client;\n\nimport io.vertx.core.Context;\n\npublic interface ClientPoolFactory<CLIENT_POOL> {\n  CLIENT_POOL createClientPool(Context context);\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/ClientPoolManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client;\n\nimport java.util.List;\nimport java.util.UUID;\nimport java.util.concurrent.CopyOnWriteArrayList;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\n\n/**\n * CLIENT_POOL是一个完备的连接池，支持向同一个目标建立一个或多个连接\n * 之所以再包装一层，是因为多个线程使用一个连接池的场景下\n * 会导致多个线程抢连接池的同一把锁\n * 包装之后，允许使用m个网络线程，每个线程中有1个连接池\n *\n * support both sync and reactive invoke.\n * 1.sync invoke, bind to a net thread\n * 2.async but not in eventloop, select but not bind to a net thread\n * 3.async and in eventloop, use clientPool in self thread\n *\n * sync/async is not about net operation, just about consumer invoke mode.\n */\npublic class ClientPoolManager<CLIENT_POOL> {\n  private final Vertx vertx;\n\n  private final String id = UUID.randomUUID().toString();\n\n  private final ClientPoolFactory<CLIENT_POOL> factory;\n\n  private final List<CLIENT_POOL> pools = new CopyOnWriteArrayList<>();\n\n  // reactive mode, when call from other thread, must select a context for it\n  // if we use threadId to hash a context, will always select the same context from one thread\n  private final AtomicInteger reactiveNextIndex = new AtomicInteger();\n\n  public ClientPoolManager(Vertx vertx, ClientPoolFactory<CLIENT_POOL> factory) {\n    this.vertx = vertx;\n    this.factory = factory;\n  }\n\n  public CLIENT_POOL createClientPool(Context context) {\n    CLIENT_POOL pool = factory.createClientPool(context);\n    addPool(context, pool);\n    return pool;\n  }\n\n  protected void addPool(Context context, CLIENT_POOL pool) {\n    context.put(id, pool);\n    pools.add(pool);\n  }\n\n  public CLIENT_POOL findClientPool(boolean sync) {\n    return findClientPool(sync, null);\n  }\n\n  public CLIENT_POOL findClientPool(boolean sync, Context targetContext) {\n    if (sync) {\n      return findThreadBindClientPool();\n    }\n\n    // reactive mode\n    return findByContext(targetContext);\n  }\n\n  protected CLIENT_POOL findByContext() {\n    return findByContext(null);\n  }\n\n  protected CLIENT_POOL findByContext(Context targetContext) {\n    Context currentContext = targetContext != null ? targetContext : Vertx.currentContext();\n    if (currentContext != null\n        && currentContext.owner() == vertx\n        && currentContext.isEventLoopContext()) {\n      // standard reactive mode\n      CLIENT_POOL clientPool = currentContext.get(id);\n      if (clientPool != null) {\n        return clientPool;\n      }\n\n      // Maybe executed in a call back of a reactive call.\n      // The Context is created in a non-event thread and passed to the event loop\n      // thread by vert.x.\n    }\n\n    // not in correct context:\n    // 1.normal thread\n    // 2.vertx worker thread\n    // 3.other vertx thread\n    // select a existing context\n    assertPoolsInitialized();\n    int idx = reactiveNextIndex.getAndIncrement() % pools.size();\n    if (idx < 0) {\n      idx = -idx;\n    }\n    return pools.get(idx);\n  }\n\n  public CLIENT_POOL findThreadBindClientPool() {\n    assertPoolsInitialized();\n    int idx = (int) (Thread.currentThread().getId() % pools.size());\n    return pools.get(idx);\n  }\n\n  private void assertPoolsInitialized() {\n    if (pools.isEmpty()) {\n      throw new IllegalStateException(\"client pool not initialized successfully when making calls.\"\n          + \"Please check if system boot up is ready or some errors happened when startup.\");\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/ClientVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.AbstractVerticle;\n\npublic class ClientVerticle<CLIENT_POOL> extends AbstractVerticle {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ClientVerticle.class);\n\n  public static final String CLIENT_MGR = \"clientMgr\";\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public void start() throws Exception {\n    try {\n      ClientPoolManager<CLIENT_POOL> clientMgr = (ClientPoolManager<CLIENT_POOL>) config().getValue(CLIENT_MGR);\n      clientMgr.createClientPool(context);\n    } catch (Throwable e) {\n      // vert.x got some states that not print error and execute call back in VertexUtils.blockDeploy, we add a log our self.\n      LOGGER.error(\"\", e);\n      throw e;\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientOptionsSPI.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.http;\n\nimport org.apache.servicecomb.foundation.common.encrypt.Encryptions;\nimport org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;\n\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.HttpVersion;\nimport io.vertx.core.http.WebSocketClientOptions;\nimport io.vertx.core.net.ClientOptionsBase;\nimport io.vertx.core.net.ProxyOptions;\n\n/**\n * common Http Client Options must be set by implementations\n */\npublic interface HttpClientOptionsSPI {\n  /* unique name in this service */\n  String clientName();\n\n  /* loading order */\n  int getOrder();\n\n  /* can turn off the client */\n  boolean enabled();\n\n  /* config tag is used for group configurations, like ssl, address resolver, etc. set config tag to distinguish\n   *  other clients configuration or read the common configuration. */\n  String getConfigTag();\n\n  /*****************  vert.x common settings ***************************/\n  int getEventLoopPoolSize();\n\n  boolean useSharedVertx();\n\n  /*****************  vert.x vertical common settings ***************************/\n  int getInstanceCount();\n\n  boolean isWorker();\n\n  String getWorkerPoolName();\n\n  int getWorkerPoolSize();\n\n  /*****************  http common settings ***************************/\n  HttpVersion getHttpVersion();\n\n  int getConnectTimeoutInMillis();\n\n  int getIdleTimeoutInSeconds();\n\n  boolean isTryUseCompression();\n\n  int getMaxWaitQueueSize();\n\n  int getMaxPoolSize();\n\n  boolean isKeepAlive();\n\n  int getMaxHeaderSize();\n\n  int getKeepAliveTimeout();\n\n  boolean enableLogActivity();\n\n  /***************** http 2 settings ****************************/\n  int getHttp2MultiplexingLimit();\n\n  int getHttp2MaxPoolSize();\n\n  boolean isUseAlpn();\n\n  /*****************  proxy settings ***************************/\n  boolean isProxyEnable();\n\n  String getProxyHost();\n\n  int getProxyPort();\n\n  String getProxyUsername();\n\n  String getProxyPassword();\n\n  /*****************  ssl settings ***************************/\n  boolean isSsl();\n\n  static void buildClientOptionsBase(HttpClientOptionsSPI spi, ClientOptionsBase httpClientOptions) {\n    httpClientOptions.setConnectTimeout(spi.getConnectTimeoutInMillis());\n    httpClientOptions.setIdleTimeout(spi.getIdleTimeoutInSeconds());\n    httpClientOptions.setLogActivity(spi.enableLogActivity());\n\n    if (spi.isProxyEnable()) {\n      ProxyOptions proxy = new ProxyOptions();\n      proxy.setHost(spi.getProxyHost());\n      proxy.setPort(spi.getProxyPort());\n      proxy.setUsername(spi.getProxyUsername());\n      proxy.setPassword(\n          Encryptions.decode(spi.getProxyPassword(), spi.getConfigTag()));\n      httpClientOptions.setProxyOptions(proxy);\n    }\n\n    if (spi.getHttpVersion() == HttpVersion.HTTP_2) {\n      httpClientOptions.setUseAlpn(spi.isUseAlpn());\n    }\n  }\n\n  static HttpClientOptions createHttpClientOptions(HttpClientOptionsSPI spi) {\n    HttpClientOptions httpClientOptions = new HttpClientOptions();\n    buildClientOptionsBase(spi, httpClientOptions);\n\n    httpClientOptions.setProtocolVersion(spi.getHttpVersion());\n    httpClientOptions.setDecompressionSupported(spi.isTryUseCompression());\n    httpClientOptions.setKeepAlive(spi.isKeepAlive());\n    httpClientOptions.setMaxHeaderSize(spi.getMaxHeaderSize());\n\n    if (spi.getHttpVersion() == HttpVersion.HTTP_2) {\n      httpClientOptions.setHttp2ClearTextUpgrade(false);\n      httpClientOptions.setHttp2MultiplexingLimit(spi.getHttp2MultiplexingLimit());\n      httpClientOptions.setHttp2KeepAliveTimeout(spi.getKeepAliveTimeout());\n    } else {\n      httpClientOptions.setKeepAliveTimeout(spi.getKeepAliveTimeout());\n    }\n\n    if (spi.isSsl()) {\n      VertxTLSBuilder.buildHttpClientOptions(spi.getConfigTag(), httpClientOptions);\n    }\n\n    return httpClientOptions;\n  }\n\n  static WebSocketClientOptions createWebSocketClientOptions(HttpClientOptionsSPI spi, boolean sslEnabled) {\n    WebSocketClientOptions webSocketClientOptions = new WebSocketClientOptions();\n    buildClientOptionsBase(spi, webSocketClientOptions);\n\n    if (sslEnabled) {\n      VertxTLSBuilder.buildWebSocketClientOptions(spi.getConfigTag(), webSocketClientOptions);\n    }\n\n    return webSocketClientOptions;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientPoolFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.http;\n\nimport org.apache.servicecomb.foundation.vertx.client.ClientPoolFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.http.HttpClient;\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.PoolOptions;\n\n// execute in vertx context\npublic class HttpClientPoolFactory implements ClientPoolFactory<HttpClientWithContext> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientPoolFactory.class);\n\n  private final HttpClientOptions httpClientOptions;\n\n  private final PoolOptions poolOptions;\n\n  public HttpClientPoolFactory(HttpClientOptions httpClientOptions, PoolOptions poolOptions) {\n    this.httpClientOptions = httpClientOptions;\n    this.poolOptions = poolOptions;\n  }\n\n  @Override\n  public HttpClientWithContext createClientPool(Context context) {\n    HttpClient httpClient = context.owner().httpClientBuilder()\n        .with(httpClientOptions)\n        .with(poolOptions)\n        .withConnectHandler(connection -> {\n          LOGGER.debug(\"http connection connected, local:{}, remote:{}.\",\n              connection.localAddress(), connection.remoteAddress());\n          connection.closeHandler(v ->\n              LOGGER.debug(\"http connection closed, local:{}, remote:{}.\",\n                  connection.localAddress(), connection.remoteAddress())\n          );\n          connection.exceptionHandler(e ->\n              LOGGER.error(\"http connection exception, local:{}, remote:{}.\",\n                  connection.localAddress(), connection.remoteAddress(), e)\n          );\n        }).build();\n    return new HttpClientWithContext(httpClient, context);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientWithContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.http;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.http.HttpClient;\n\npublic class HttpClientWithContext {\n  public interface RunHandler {\n    void run(HttpClient httpClient);\n  }\n\n  private final HttpClient httpClient;\n\n  private final Context context;\n\n  public HttpClientWithContext(HttpClient httpClient, Context context) {\n    this.httpClient = httpClient;\n    this.context = context;\n  }\n\n  public HttpClient getHttpClient() {\n    return httpClient;\n  }\n\n  public void runOnContext(RunHandler handler) {\n    context.runOnContext((v) -> handler.run(httpClient));\n  }\n\n  public Context context() {\n    return context;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClients.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.http;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.vertx.AddressResolverConfig;\nimport org.apache.servicecomb.foundation.vertx.SharedVertxFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;\nimport org.apache.servicecomb.foundation.vertx.client.ClientVerticle;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.ThreadingModel;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.dns.AddressResolverOptions;\nimport io.vertx.core.http.PoolOptions;\nimport io.vertx.core.http.WebSocketClient;\n\n/**\n *  load and manages a set of HttpClient at boot up.\n */\npublic class HttpClients {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HttpClients.class);\n\n  private static final Map<String, ClientPoolManager<HttpClientWithContext>> httpClients = new HashMap<>();\n\n  /* load at boot up, call this method once and only once. */\n  public static void load() {\n    List<HttpClientOptionsSPI> clientOptionsList = SPIServiceUtils.getOrLoadSortedService(HttpClientOptionsSPI.class);\n    clientOptionsList.forEach(option -> {\n      if (option.enabled()) {\n        ClientPoolManager<HttpClientWithContext> clientPoolManager = httpClients.get(option.clientName());\n        if (clientPoolManager != null) {\n          LOGGER.warn(\"client pool {} initialized again.\", option.clientName());\n        }\n        httpClients.put(option.clientName(), createClientPoolManager(option));\n      }\n    });\n  }\n\n  /* destroy at shutdown. */\n  public static void destroy() {\n    httpClients.clear();\n    List<HttpClientOptionsSPI> clientOptionsList = SPIServiceUtils.getOrLoadSortedService(HttpClientOptionsSPI.class);\n    clientOptionsList.forEach(option -> VertxUtils.blockCloseVertxByName(option.clientName()));\n  }\n\n  private static ClientPoolManager<HttpClientWithContext> createClientPoolManager(HttpClientOptionsSPI option) {\n    Vertx vertx = getOrCreateVertx(option);\n    PoolOptions poolOptions = new PoolOptions();\n    poolOptions.setMaxWaitQueueSize(option.getMaxWaitQueueSize());\n    poolOptions.setHttp1MaxSize(option.getMaxPoolSize());\n    poolOptions.setHttp2MaxSize(option.getHttp2MaxPoolSize());\n    ClientPoolManager<HttpClientWithContext> clientPoolManager = new ClientPoolManager<>(vertx,\n        new HttpClientPoolFactory(HttpClientOptionsSPI.createHttpClientOptions(option), poolOptions));\n\n    DeploymentOptions deployOptions = VertxUtils.createClientDeployOptions(clientPoolManager,\n            option.getInstanceCount())\n        .setThreadingModel(option.isWorker() ? ThreadingModel.WORKER : ThreadingModel.EVENT_LOOP)\n        .setWorkerPoolName(option.getWorkerPoolName())\n        .setWorkerPoolSize(option.getWorkerPoolSize());\n    try {\n      VertxUtils.blockDeploy(vertx, ClientVerticle.class, deployOptions);\n      return clientPoolManager;\n    } catch (InterruptedException e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  public static WebSocketClient createWebSocketClient(HttpClientOptionsSPI option, boolean sslEnabled) {\n    Vertx vertx = getOrCreateVertx(option);\n    return vertx.createWebSocketClient(HttpClientOptionsSPI.createWebSocketClientOptions(option, sslEnabled));\n  }\n\n  private static Vertx getOrCreateVertx(HttpClientOptionsSPI option) {\n    if (option.useSharedVertx()) {\n      return SharedVertxFactory.getSharedVertx(LegacyPropertyFactory.getEnvironment());\n    }\n\n    AddressResolverOptions resolverOptions = AddressResolverConfig\n        .getAddressResolverOptions(option.getConfigTag());\n    VertxOptions vertxOptions = new VertxOptions()\n        .setAddressResolverOptions(resolverOptions)\n        .setEventLoopPoolSize(option.getEventLoopPoolSize());\n\n    // Maybe we can deploy only one vert.x for the application. However this has did it like this.\n    return VertxUtils.getOrCreateVertxByName(option.clientName(), vertxOptions, null);\n  }\n\n  /**\n   * get client instance by name\n   * @param clientName instance name\n   * @return the deployed instance name\n   */\n  public static HttpClientWithContext getClient(String clientName) {\n    return getClient(clientName, true);\n  }\n\n  /**\n   * get client instance by name\n   * @param clientName instance name\n   * @param sync reactive or not. false for reactive.\n   * @return the deployed instance name\n   */\n  public static HttpClientWithContext getClient(String clientName, boolean sync) {\n    return getClient(clientName, sync, null);\n  }\n\n  /**\n   * get client instance by name\n   * @param clientName instance name\n   * @param sync reactive or not. false for reactive.\n   * @param targetContext running context\n   * @return the deployed instance name\n   */\n  public static HttpClientWithContext getClient(String clientName, boolean sync, Context targetContext) {\n    ClientPoolManager<HttpClientWithContext> poolManager = httpClients.get(clientName);\n    if (poolManager == null) {\n      LOGGER.error(\"client name [{}] not exists, should only happen in tests.\", clientName);\n      return null;\n    }\n    return poolManager.findClientPool(sync, targetContext);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientConnectionPool.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport java.util.Map;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\nimport io.vertx.core.Context;\n\npublic abstract class AbstractTcpClientConnectionPool<T extends TcpClientConnection> {\n  // 是在哪个context中创建的\n  protected Context context;\n\n  protected NetClientWrapper netClientWrapper;\n\n  // key为address\n  protected Map<String, T> tcpClientMap = new ConcurrentHashMapEx<>();\n\n  public AbstractTcpClientConnectionPool(Context context,\n      NetClientWrapper netClientWrapper) {\n    this.context = context;\n    this.netClientWrapper = netClientWrapper;\n\n    startCheckTimeout(context);\n  }\n\n  protected void startCheckTimeout(Context context) {\n    context.owner().setPeriodic(TimeUnit.SECONDS.toMillis(1), this::onCheckTimeout);\n  }\n\n  private void onCheckTimeout(Long event) {\n    for (TcpClientConnection client : tcpClientMap.values()) {\n      client.checkTimeout();\n    }\n  }\n\n  public T findOrCreateClient(String endpoint) {\n    return tcpClientMap.computeIfAbsent(endpoint, this::create);\n  }\n\n  protected abstract T create(String endpoint);\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\n\npublic abstract class AbstractTcpClientPackage {\n  private static final AtomicLong reqId = new AtomicLong();\n\n  public static long getAndIncRequestId() {\n    return reqId.getAndIncrement();\n  }\n\n  private volatile long msRequestTimeout;\n\n  private volatile long finishWriteToBuffer;\n\n  protected long msgId = getAndIncRequestId();\n\n  public long getMsgId() {\n    return msgId;\n  }\n\n  public long getMsRequestTimeout() {\n    return msRequestTimeout;\n  }\n\n  public void setMsRequestTimeout(long msRequestTimeout) {\n    this.msRequestTimeout = msRequestTimeout;\n  }\n\n  public long getFinishWriteToBuffer() {\n    return finishWriteToBuffer;\n  }\n\n  public void finishWriteToBuffer() {\n    this.finishWriteToBuffer = System.nanoTime();\n  }\n\n  public abstract TcpOutputStream createStream();\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPoolFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport org.apache.servicecomb.foundation.vertx.client.ClientPoolFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\n\npublic abstract class AbstractTcpClientPoolFactory<CLIENT_POOL> implements ClientPoolFactory<CLIENT_POOL> {\n  protected TcpClientConfig normalClientConfig;\n\n  protected TcpClientConfig sslClientConfig;\n\n  public AbstractTcpClientPoolFactory(TcpClientConfig normalClientConfig, TcpClientConfig sslClientConfig) {\n    this.normalClientConfig = normalClientConfig;\n    this.sslClientConfig = sslClientConfig;\n  }\n\n  @Override\n  public CLIENT_POOL createClientPool(Context context) {\n    Vertx vertx = context.owner();\n\n    NetClientWrapper netClientWrapper = new NetClientWrapper(vertx, normalClientConfig, sslClientConfig);\n    return doCreateClientPool(context, netClientWrapper);\n  }\n\n  protected abstract CLIENT_POOL doCreateClientPool(Context context, NetClientWrapper netClientWrapper);\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/NetClientWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.net.NetClient;\nimport io.vertx.core.net.NetSocket;\n\n// netClient do not like httpClient\n// can not support normal and ssl by the same instance\n// so we do this wrap\npublic class NetClientWrapper {\n  private final TcpClientConfig normalClientConfig;\n\n  private final NetClient normalNetClient;\n\n  private final TcpClientConfig sslClientConfig;\n\n  private final NetClient sslNetClient;\n\n  public NetClientWrapper(Vertx vertx, TcpClientConfig normalClientConfig, TcpClientConfig sslClientConfig) {\n    this.normalClientConfig = normalClientConfig;\n    this.normalNetClient = vertx.createNetClient(normalClientConfig);\n\n    this.sslClientConfig = sslClientConfig;\n    this.sslNetClient = vertx.createNetClient(sslClientConfig);\n  }\n\n  public TcpClientConfig getClientConfig(boolean ssl) {\n    if (ssl) {\n      return sslClientConfig;\n    }\n\n    return normalClientConfig;\n  }\n\n  public Future<NetSocket> connect(boolean ssl, int port, String host) {\n    if (ssl) {\n      return sslNetClient.connect(port, host);\n    }\n\n    return normalNetClient.connect(port, host);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport io.vertx.core.net.NetClientOptions;\n\npublic class TcpClientConfig extends NetClientOptions {\n  public static final int DEFAULT_LOGIN_TIMEOUT = 30000;\n\n  private long msLoginTimeout;\n\n  public TcpClientConfig() {\n    msLoginTimeout = DEFAULT_LOGIN_TIMEOUT;\n  }\n\n  public long getMsLoginTimeout() {\n    return msLoginTimeout;\n  }\n\n  public void setMsLoginTimeout(long msLoginTimeout) {\n    this.msLoginTimeout = msLoginTimeout;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Queue;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentLinkedQueue;\nimport java.util.concurrent.TimeoutException;\n\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.vertx.server.TcpParser;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpConnection;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpConst;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.core.AsyncResult;\nimport io.vertx.core.Context;\nimport io.vertx.core.Future;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.net.NetSocket;\nimport io.vertx.core.net.impl.NetSocketImpl;\n\npublic class TcpClientConnection extends TcpConnection {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TcpClientConnection.class);\n\n  enum Status {\n    CONNECTING,\n    DISCONNECTED,\n    TRY_LOGIN,\n    WORKING\n  }\n\n  private final NetClientWrapper netClientWrapper;\n\n  private final TcpClientConfig clientConfig;\n\n  private final URIEndpointObject endpoint;\n\n  private final InetSocketAddress socketAddress;\n\n  private volatile boolean localSupportLogin = false;\n\n  private final boolean remoteSupportLogin;\n\n  private volatile Status status = Status.DISCONNECTED;\n\n  // save msg before login success.\n  // before login, we can not know parameters, like: zip/codec compatible, and so on\n  // so can only save package, can not save byteBuf\n  private final Queue<AbstractTcpClientPackage> packageQueue = new ConcurrentLinkedQueue<>();\n\n  private volatile Map<Long, TcpRequest> requestMap = new ConcurrentHashMap<>();\n\n  public TcpClientConnection(Context context, NetClientWrapper netClientWrapper, String strEndpoint) {\n    this.setContext(context);\n\n    this.netClientWrapper = netClientWrapper;\n    endpoint = new URIEndpointObject(strEndpoint);\n    this.socketAddress = endpoint.getSocketAddress();\n    this.remoteSupportLogin = Boolean.parseBoolean(endpoint.getFirst(TcpConst.LOGIN));\n    this.clientConfig = netClientWrapper.getClientConfig(endpoint.isSslEnabled());\n  }\n\n  public boolean isLocalSupportLogin() {\n    return localSupportLogin;\n  }\n\n  public TcpClientConfig getClientConfig() {\n    return clientConfig;\n  }\n\n  public void setLocalSupportLogin(boolean localSupportLogin) {\n    this.localSupportLogin = localSupportLogin;\n  }\n\n  protected TcpOutputStream createLogin() {\n    return null;\n  }\n\n  protected boolean onLoginResponse(Buffer bodyBuffer) {\n    return true;\n  }\n\n  public CompletableFuture<TcpData> send(AbstractTcpClientPackage tcpClientPackage) {\n    CompletableFuture<TcpData> future = new CompletableFuture<>();\n    send(tcpClientPackage, ar -> {\n      if (ar.failed()) {\n        future.completeExceptionally(ar.cause());\n        return;\n      }\n      future.complete(ar.result());\n    });\n    return future;\n  }\n\n  public void send(AbstractTcpClientPackage tcpClientPackage, TcpResponseCallback callback) {\n    requestMap.put(tcpClientPackage.getMsgId(), new TcpRequest(tcpClientPackage.getMsRequestTimeout(), callback));\n\n    if (writeToBufferQueue(tcpClientPackage)) {\n      return;\n    }\n\n    // before login success, no optimize, just make sure do not lost data\n    context.runOnContext(v -> {\n      if (!writeToBufferQueue(tcpClientPackage)) {\n        packageQueue.add(tcpClientPackage);\n      }\n\n      // connect must call in eventloop thread\n      // otherwise vertx will create a new eventloop thread for it if count\n      //   of eventloop thread is not up to the limit.\n      if (Status.DISCONNECTED.equals(status)) {\n        connect();\n      }\n    });\n  }\n\n  private boolean writeToBufferQueue(AbstractTcpClientPackage tcpClientPackage) {\n    // read status maybe out of eventloop thread, it's not exact\n    // just optimize for main scenes\n    if (Status.WORKING.equals(status)) {\n      // encode in sender thread\n      try (TcpOutputStream os = tcpClientPackage.createStream()) {\n        write(os.getBuffer());\n        tcpClientPackage.finishWriteToBuffer();\n      }\n      return true;\n    }\n\n    return false;\n  }\n\n  @Override\n  protected void writeInContext() {\n    writePackageInContext();\n\n    super.writeInContext();\n  }\n\n  private void writePackageInContext() {\n    for (; ; ) {\n      AbstractTcpClientPackage pkg = packageQueue.poll();\n      if (pkg == null) {\n        break;\n      }\n\n      try (TcpOutputStream os = pkg.createStream()) {\n        Buffer buf = os.getBuffer();\n        netSocket.write(buf);\n        pkg.finishWriteToBuffer();\n      }\n    }\n  }\n\n  @VisibleForTesting\n  protected void connect() {\n    this.status = Status.CONNECTING;\n    LOGGER.info(\"connecting to address {}\", socketAddress.toString());\n\n    Future<NetSocket> result = netClientWrapper.connect(endpoint.isSslEnabled(),\n        socketAddress.getPort(),\n        socketAddress.getHostString());\n    result.onComplete((socket, fail) -> {\n      if (fail == null) {\n        onConnectSuccess(socket);\n        return;\n      }\n\n      onConnectFailed(fail);\n    });\n  }\n\n  private void onConnectSuccess(NetSocket socket) {\n    LOGGER.info(\"connected to address {} success in thread {}.\",\n        socketAddress.toString(),\n        Thread.currentThread().getName());\n    // currently, socket always be NetSocketImpl\n    this.initNetSocket((NetSocketImpl) socket);\n    socket.handler(new TcpParser(this::onReply));\n\n    socket.exceptionHandler(this::onException);\n    socket.closeHandler(this::onClosed);\n\n    // 开始登录\n    tryLogin();\n  }\n\n  @VisibleForTesting\n  void onClosed(Void v) {\n    onDisconnected(new IOException(\"socket closed\"));\n  }\n\n  // 异常断连时，先触发onException，再触发onClosed\n  // 正常断连时，只触发onClosed\n  private void onException(Throwable e) {\n    LOGGER.error(\"{} disconnected from {}, in thread {}, cause {}\",\n        netSocket.localAddress().toString(),\n        socketAddress.toString(),\n        Thread.currentThread().getName(),\n        e.getMessage());\n  }\n\n  private void onDisconnected(Throwable e) {\n    this.status = Status.DISCONNECTED;\n    LOGGER.error(\"{} disconnected from {}, in thread {}, cause {}\",\n        netSocket.localAddress().toString(),\n        socketAddress.toString(),\n        Thread.currentThread().getName(),\n        e.getMessage());\n\n    clearCachedRequest(e);\n  }\n\n  protected void tryLogin() {\n    if (!localSupportLogin || !remoteSupportLogin) {\n      LOGGER.error(\n          \"local or remote not support login, address={}, localSupportLogin={}, remoteSupportLogin={}.\",\n          socketAddress.toString(),\n          localSupportLogin,\n          remoteSupportLogin);\n      onLoginSuccess();\n      return;\n    }\n\n    this.status = Status.TRY_LOGIN;\n    LOGGER.info(\"try login to address {}\", socketAddress.toString());\n\n    try (TcpOutputStream os = createLogin()) {\n      requestMap.put(os.getMsgId(),\n          new TcpRequest(clientConfig.getMsLoginTimeout(), this::onLoginResponse));\n      netSocket.write(os.getBuffer());\n    }\n  }\n\n  private void onLoginResponse(AsyncResult<TcpData> asyncResult) {\n    if (asyncResult.failed()) {\n      LOGGER.error(\"login failed, address {}\", socketAddress.toString(), asyncResult.cause());\n      // 在相应回调中设置状态\n      netSocket.close();\n      return;\n    }\n\n    if (!onLoginResponse(asyncResult.result().getBodyBuffer())) {\n      LOGGER.error(\"login failed, address {}\", socketAddress.toString());\n      // 在相应回调中设置状态\n      netSocket.close();\n      return;\n    }\n\n    LOGGER.info(\"login success, address {}\", socketAddress.toString());\n    onLoginSuccess();\n  }\n\n  private void onLoginSuccess() {\n    this.status = Status.WORKING;\n    writeInContext();\n  }\n\n  private void onConnectFailed(Throwable cause) {\n    // 连接失败\n    this.status = Status.DISCONNECTED;\n    String msg = String.format(\"connect to address %s failed.\",\n        socketAddress.toString());\n    LOGGER.error(msg, cause);\n\n    clearCachedRequest(cause);\n  }\n\n  protected void clearCachedRequest(Throwable cause) {\n    // 在onSendError，用户可能发起一次新的调用，需要避免作多余的清理\n    Map<Long, TcpRequest> oldMap = requestMap;\n    requestMap = new ConcurrentHashMap<>();\n\n    for (TcpRequest request : oldMap.values()) {\n      request.onSendError(cause);\n    }\n    oldMap.clear();\n  }\n\n  protected void onReply(long msgId, Buffer headerBuffer, Buffer bodyBuffer) {\n    TcpRequest request = requestMap.remove(msgId);\n    if (request == null) {\n      LOGGER.error(\"Unknown reply msgId {}, waiting count {}\", msgId, requestMap.size());\n      return;\n    }\n\n    request.onReply(headerBuffer, bodyBuffer);\n  }\n\n  public void checkTimeout() {\n    for (Entry<Long, TcpRequest> entry : requestMap.entrySet()) {\n      TcpRequest request = entry.getValue();\n      if (request.isTimeout()) {\n        // 可能正好收到reply，且被处理了，所以这里的remove不一定有效\n        // 是否有效，根据remove的结果来决定\n        request = requestMap.remove(entry.getKey());\n        if (request != null) {\n          String msg =\n              String.format(\"request timeout, msgId=%d, address=%s\", entry.getKey(), socketAddress);\n          LOGGER.error(msg);\n\n          request.onTimeout(new TimeoutException(msg));\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnectionPool.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport io.vertx.core.Context;\n\npublic class TcpClientConnectionPool extends AbstractTcpClientConnectionPool<TcpClientConnection> {\n  public TcpClientConnectionPool(Context context, NetClientWrapper netClientWrapper) {\n    super(context, netClientWrapper);\n  }\n\n  @Override\n  protected TcpClientConnection create(String endpoint) {\n    return new TcpClientConnection(context, netClientWrapper, endpoint);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientPackage.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\n\npublic class TcpClientPackage extends AbstractTcpClientPackage {\n  private final TcpOutputStream os;\n\n  public TcpClientPackage(TcpOutputStream os) {\n    this.os = os;\n  }\n\n  @Override\n  public TcpOutputStream createStream() {\n    return os;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientPoolFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport io.vertx.core.Context;\n\npublic class TcpClientPoolFactory extends AbstractTcpClientPoolFactory<TcpClientConnectionPool> {\n  public TcpClientPoolFactory(TcpClientConfig normalClientConfig, TcpClientConfig sslClientConfig) {\n    super(normalClientConfig, sslClientConfig);\n  }\n\n  @Override\n  protected TcpClientConnectionPool doCreateClientPool(Context context, NetClientWrapper netClientWrapper) {\n    return new TcpClientConnectionPool(context, netClientWrapper);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class TcpData {\n  private Buffer headerBuffer;\n\n  private Buffer bodyBuffer;\n\n  public TcpData(Buffer headerBuffer, Buffer bodyBuffer) {\n    this.headerBuffer = headerBuffer;\n    this.bodyBuffer = bodyBuffer;\n  }\n\n  public Buffer getHeaderBuffer() {\n    return headerBuffer;\n  }\n\n  public void setHeaderBuffer(Buffer headerBuffer) {\n    this.headerBuffer = headerBuffer;\n  }\n\n  public Buffer getBodyBuffer() {\n    return bodyBuffer;\n  }\n\n  public void setBodyBuffer(Buffer bodyBuffer) {\n    this.bodyBuffer = bodyBuffer;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport java.util.concurrent.TimeoutException;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.buffer.Buffer;\n\npublic class TcpRequest {\n  private final long begin;\n\n  private final long msTimeout;\n\n  private final Context callContext;\n\n  private final long threadId;\n\n  private final TcpResponseCallback responseCallback;\n\n  public TcpRequest(long msTimeout, TcpResponseCallback responseCallback) {\n    callContext = Vertx.currentContext();\n    threadId = Thread.currentThread().getId();\n    this.begin = System.currentTimeMillis();\n    this.msTimeout = msTimeout;\n    this.responseCallback = responseCallback;\n  }\n\n  public void onReply(Buffer headerBuffer, Buffer bodyBuffer) {\n    TcpData tcpData = new TcpData(headerBuffer, bodyBuffer);\n\n    if (callContext == null || threadId == Thread.currentThread().getId()) {\n      responseCallback.success(tcpData);\n      return;\n    }\n\n    callContext.runOnContext(Void -> responseCallback.success(tcpData));\n  }\n\n  public void onSendError(Throwable e) {\n    responseCallback.fail(e);\n  }\n\n  public boolean isTimeout() {\n    return System.currentTimeMillis() - begin >= msTimeout;\n  }\n\n  public void onTimeout(TimeoutException e) {\n    responseCallback.fail(e);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpResponseCallback.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport org.apache.servicecomb.foundation.vertx.AsyncResultCallback;\n\npublic interface TcpResponseCallback extends AsyncResultCallback<TcpData> {\n\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/executor/SinglePoolBlockingExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.executor;\n\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.Executors;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class SinglePoolBlockingExecutor implements Executor {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SinglePoolBlockingExecutor.class);\n\n  private static final Executor SINGLE_POOL = Executors.newSingleThreadExecutor((r) -> {\n    Thread thread = new Thread(r);\n    thread.setName(\"single-pool-blocking-executor\");\n    return thread;\n  });\n\n  public static SinglePoolBlockingExecutor create() {\n    return new SinglePoolBlockingExecutor();\n  }\n\n  private SinglePoolBlockingExecutor() {\n\n  }\n\n  @Override\n  public void execute(Runnable command) {\n    SINGLE_POOL.execute(() -> {\n      try {\n        command.run();\n      } catch (Throwable e) {\n        LOGGER.error(\"Logic should not throw exception, please fix it\", e);\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/executor/VertxContextExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.executor;\n\nimport java.util.concurrent.Executor;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\n\npublic class VertxContextExecutor implements Executor {\n  public static VertxContextExecutor create(Vertx vertx) {\n    return new VertxContextExecutor(vertx.getOrCreateContext());\n  }\n\n  public static VertxContextExecutor create(Context context) {\n    return new VertxContextExecutor(context);\n  }\n\n  private final Context context;\n\n  private VertxContextExecutor(Context context) {\n    this.context = context;\n  }\n\n  @Override\n  public void execute(Runnable command) {\n    if (context == Vertx.currentContext()) {\n      command.run();\n      return;\n    }\n\n    context.runOnContext(v -> command.run());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/executor/VertxWorkerExecutor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.executor;\n\nimport java.util.concurrent.Executor;\n\nimport io.vertx.core.Vertx;\n\npublic class VertxWorkerExecutor implements Executor {\n\n  @Override\n  public void execute(Runnable command) {\n    Vertx.currentContext().owner().executeBlocking(() -> {\n      command.run();\n      return null;\n    }, false);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/AbstractHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.security.Principal;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\nimport jakarta.servlet.AsyncContext;\nimport jakarta.servlet.DispatcherType;\nimport jakarta.servlet.RequestDispatcher;\nimport jakarta.servlet.ServletConnection;\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.ServletInputStream;\nimport jakarta.servlet.ServletRequest;\nimport jakarta.servlet.ServletResponse;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.HttpServletResponse;\nimport jakarta.servlet.http.HttpSession;\nimport jakarta.servlet.http.HttpUpgradeHandler;\nimport jakarta.servlet.http.Part;\n\npublic abstract class AbstractHttpServletRequest extends BodyBufferSupportImpl implements HttpServletRequestEx {\n  private final Map<String, Object> attributeMap = new HashMap<>();\n\n  @Override\n  public Object getAttribute(String name) {\n    return attributeMap.get(name);\n  }\n\n  @Override\n  public Enumeration<String> getAttributeNames() {\n    return Collections.enumeration(attributeMap.keySet());\n  }\n\n  @Override\n  public String getCharacterEncoding() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setCharacterEncoding(String env) throws UnsupportedEncodingException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getRequestId() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getProtocolRequestId() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public ServletConnection getServletConnection() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getContentLength() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public long getContentLengthLong() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getContentType() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public ServletInputStream getInputStream() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getParameter(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Enumeration<String> getParameterNames() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String[] getParameterValues(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Map<String, String[]> getParameterMap() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getProtocol() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getScheme() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getServerName() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getServerPort() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public BufferedReader getReader() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getRemoteAddr() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getRemoteHost() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setAttribute(String name, Object o) {\n    attributeMap.put(name, o);\n  }\n\n  @Override\n  public void removeAttribute(String name) {\n    attributeMap.remove(name);\n  }\n\n  @Override\n  public Locale getLocale() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Enumeration<Locale> getLocales() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isSecure() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public RequestDispatcher getRequestDispatcher(String path) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getRemotePort() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getLocalName() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getLocalAddr() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getLocalPort() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public ServletContext getServletContext() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public AsyncContext startAsync() throws IllegalStateException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)\n      throws IllegalStateException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isAsyncStarted() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isAsyncSupported() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public AsyncContext getAsyncContext() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public DispatcherType getDispatcherType() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getAuthType() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Cookie[] getCookies() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public long getDateHeader(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getHeader(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Enumeration<String> getHeaders(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Enumeration<String> getHeaderNames() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getIntHeader(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getMethod() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getPathInfo() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getPathTranslated() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getContextPath() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getQueryString() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getRemoteUser() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isUserInRole(String role) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Principal getUserPrincipal() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getRequestedSessionId() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getRequestURI() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public StringBuffer getRequestURL() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getServletPath() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public HttpSession getSession(boolean create) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public HttpSession getSession() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String changeSessionId() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isRequestedSessionIdValid() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isRequestedSessionIdFromCookie() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isRequestedSessionIdFromURL() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void login(String username, String password) throws ServletException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void logout() throws ServletException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Collection<Part> getParts() throws IOException, ServletException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Part getPart(String name) throws IOException, ServletException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {\n    throw new Error(\"not supported method\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/AbstractHttpServletResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport io.vertx.core.buffer.Buffer;\nimport jakarta.servlet.ServletOutputStream;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic abstract class AbstractHttpServletResponse extends BodyBufferSupportImpl implements HttpServletResponseEx {\n  private final Map<String, Object> attributes = new HashMap<>();\n\n  @Override\n  public String getCharacterEncoding() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getContentType() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public ServletOutputStream getOutputStream() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public PrintWriter getWriter() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setCharacterEncoding(String charset) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setContentLength(int len) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setContentLengthLong(long len) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setContentType(String type) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setBufferSize(int size) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getBufferSize() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void flushBuffer() throws IOException {\n    // for vert.x do noting\n  }\n\n  @Override\n  public void endResponse() throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void resetBuffer() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean isCommitted() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void reset() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setLocale(Locale loc) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Locale getLocale() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void addCookie(Cookie cookie) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public boolean containsHeader(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String encodeURL(String url) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String encodeRedirectURL(String url) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void sendError(int sc, String msg) throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void sendError(int sc) throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void sendRedirect(String location) throws IOException {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setDateHeader(String name, long date) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void addDateHeader(String name, long date) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setHeader(String name, String value) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void addHeader(String name, String value) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setIntHeader(String name, int value) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void addIntHeader(String name, int value) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setStatus(int sc) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public int getStatus() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public String getHeader(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Collection<String> getHeaders(String name) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public Collection<String> getHeaderNames() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public StatusType getStatusType() {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public void setAttribute(String key, Object value) {\n    this.attributes.put(key, value);\n  }\n\n  @Override\n  public Object getAttribute(String key) {\n    return this.attributes.get(key);\n  }\n\n  @Override\n  public CompletableFuture<Void> sendPart(Part body) {\n    throw new Error(\"not supported method\");\n  }\n\n  @Override\n  public CompletableFuture<Void> sendBuffer(Buffer buffer) {\n    throw new Error(\"not supported method\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/BodyBufferSupport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic interface BodyBufferSupport {\n  void setBodyBuffer(Buffer bodyBuffer);\n\n  Buffer getBodyBuffer();\n\n  // notice: byte[] maybe null, and length maybe bigger than body length\n  byte[] getBodyBytes();\n\n  int getBodyBytesLength();\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/BodyBufferSupportImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class BodyBufferSupportImpl implements BodyBufferSupport {\n  protected Buffer bodyBuffer;\n\n  private byte[] bodyBytes;\n\n  private int bodyLength;\n\n  @Override\n  public void setBodyBuffer(Buffer bodyBuffer) {\n    this.bodyBuffer = bodyBuffer;\n    this.bodyBytes = null;\n    this.bodyLength = 0;\n  }\n\n  private void prepare() {\n    if (bodyBytes == null && bodyBuffer != null) {\n      bodyLength = bodyBuffer.length();\n      bodyBytes = VertxUtils.getBytesFast(bodyBuffer);\n    }\n  }\n\n\n  @Override\n  public Buffer getBodyBuffer() {\n    return bodyBuffer;\n  }\n\n  @VisibleForTesting\n  void setBodyBytes(byte[] bodyBytes) {\n    this.bodyBytes = bodyBytes;\n  }\n\n  @Override\n  public byte[] getBodyBytes() {\n    prepare();\n    return bodyBytes;\n  }\n\n  @VisibleForTesting\n  void setBodyLength(int bodyLength) {\n    this.bodyLength = bodyLength;\n  }\n\n  @Override\n  public int getBodyBytesLength() {\n    prepare();\n    return bodyLength;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/DownloadUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\nimport org.apache.servicecomb.foundation.common.part.FilePartForSend;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.http.HttpHeaders;\n\n/**\n * internal api\n */\npublic final class DownloadUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DownloadUtils.class);\n\n  private DownloadUtils() {\n  }\n\n  public static void prepareDownloadHeader(HttpServletResponseEx responseEx, Part part) {\n    if (responseEx.getHeader(HttpHeaders.CONTENT_LENGTH.toString()) == null) {\n      responseEx.setChunked(true);\n    }\n    if (part == null) {\n      return;\n    }\n    if (responseEx.getHeader(HttpHeaders.CONTENT_TYPE.toString()) == null) {\n      if (responseEx.getContentType() != null) {\n        responseEx.setHeader(HttpHeaders.CONTENT_TYPE.toString(), responseEx.getContentType());\n      } else {\n        responseEx.setHeader(HttpHeaders.CONTENT_TYPE.toString(), part.getContentType());\n      }\n    }\n\n    if (responseEx.getHeader(jakarta.ws.rs.core.HttpHeaders.CONTENT_DISPOSITION) == null) {\n      // to support chinese and space filename in firefox\n      // must use \"filename*\", (https://tools.ietf.org/html/rtf6266)\n      String encodedFileName = HttpUtils.uriEncodePath(part.getSubmittedFileName());\n      responseEx.setHeader(jakarta.ws.rs.core.HttpHeaders.CONTENT_DISPOSITION,\n          \"attachment;filename=\" + encodedFileName + \";filename*=utf-8''\" + encodedFileName);\n    }\n  }\n\n  public static void clearPartResource(Part part) {\n    if (part == null) {\n      return;\n    }\n    if (part instanceof FilePartForSend && ((FilePartForSend) part).isDeleteAfterFinished()) {\n      try {\n        part.delete();\n      } catch (IOException e) {\n        LOGGER.error(\"Failed to delete temp file: {}.\", ((FilePartForSend) part).getAbsolutePath(), e);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/EmptyAsyncContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport jakarta.servlet.AsyncContext;\nimport jakarta.servlet.AsyncListener;\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.ServletRequest;\nimport jakarta.servlet.ServletResponse;\n\npublic class EmptyAsyncContext implements AsyncContext {\n  @Override\n  public ServletRequest getRequest() {\n    return null;\n  }\n\n  @Override\n  public ServletResponse getResponse() {\n    return null;\n  }\n\n  @Override\n  public boolean hasOriginalRequestAndResponse() {\n    return false;\n  }\n\n  @Override\n  public void dispatch() {\n\n  }\n\n  @Override\n  public void dispatch(String path) {\n\n  }\n\n  @Override\n  public void dispatch(ServletContext context, String path) {\n\n  }\n\n  @Override\n  public void complete() {\n\n  }\n\n  @Override\n  public void start(Runnable run) {\n\n  }\n\n  @Override\n  public void addListener(AsyncListener listener) {\n\n  }\n\n  @Override\n  public void addListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) {\n\n  }\n\n  @Override\n  public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException {\n    return null;\n  }\n\n  @Override\n  public void setTimeout(long timeout) {\n\n  }\n\n  @Override\n  public long getTimeout() {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/FileUploadPart.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.foundation.vertx.http;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.nio.file.Files;\r\n\r\nimport org.apache.commons.io.FileUtils;\r\nimport org.apache.servicecomb.foundation.common.part.AbstractPart;\r\n\r\nimport io.vertx.ext.web.FileUpload;\r\n\r\npublic class FileUploadPart extends AbstractPart {\r\n  private final FileUpload fileUpload;\r\n\r\n  public FileUploadPart(FileUpload fileUpload) {\r\n    this.fileUpload = fileUpload;\r\n  }\r\n\r\n  @Override\r\n  public InputStream getInputStream() throws IOException {\r\n    return Files.newInputStream(new File(fileUpload.uploadedFileName()).toPath());\r\n  }\r\n\r\n  @Override\r\n  public String getContentType() {\r\n    return fileUpload.contentType();\r\n  }\r\n\r\n  @Override\r\n  public String getName() {\r\n    return fileUpload.name();\r\n  }\r\n\r\n  @Override\r\n  public String getSubmittedFileName() {\r\n    return fileUpload.fileName();\r\n  }\r\n\r\n  @Override\r\n  public long getSize() {\r\n    return fileUpload.size();\r\n  }\r\n\r\n  @Override\r\n  public void write(String fileName) throws IOException {\r\n    FileUtils.copyFile(new File(fileUpload.uploadedFileName()), new File(fileName));\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/HttpServletRequestEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic interface HttpServletRequestEx extends HttpServletRequest, BodyBufferSupport {\n  default void setHeader(String name, String value) {\n\n  }\n\n  default void addHeader(String name, String value) {\n\n  }\n\n  default void setParameter(String name, String value) {\n\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/HttpServletResponseEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.concurrent.CompletableFuture;\n\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpHeaders;\nimport jakarta.servlet.ServletOutputStream;\nimport jakarta.servlet.http.HttpServletResponse;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic interface HttpServletResponseEx extends HttpServletResponse, BodyBufferSupport {\n  StatusType getStatusType();\n\n  void setAttribute(String key, Object value);\n\n  Object getAttribute(String key);\n\n  CompletableFuture<Void> sendPart(Part body);\n\n  CompletableFuture<Void> sendBuffer(Buffer buffer);\n\n  default void setChunked(boolean chunked) {\n    setHeader(HttpHeaders.TRANSFER_ENCODING.toString(), HttpHeaders.CHUNKED.toString());\n  }\n\n  void endResponse() throws IOException;\n\n  @Override\n  default ServletOutputStream getOutputStream() throws IOException {\n    throw new IOException(\"Not allowed\");\n  }\n\n  @Override\n  default PrintWriter getWriter() throws IOException {\n    throw new IOException(\"Not allowed\");\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/ReadStreamPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.File;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.function.Function;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\nimport org.apache.servicecomb.foundation.common.part.AbstractPart;\nimport org.apache.servicecomb.foundation.vertx.stream.PumpCommon;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Future;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.file.AsyncFile;\nimport io.vertx.core.file.OpenOptions;\nimport io.vertx.core.http.HttpClientResponse;\nimport io.vertx.core.streams.ReadStream;\nimport io.vertx.core.streams.WriteStream;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\n\n/**\n * this is not a really part type, all method extend from AbstractPart is undefined except:<br>\n * 1.getContentType<br>\n * 2.getSubmittedFileName<br>\n * extend from AbstractPart just because want to make it be Part type,\n * so that can be sent by\n * {@link org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse#sendPart(Part) VertxServerResponseToHttpServletResponse.sendPart}\n */\npublic class ReadStreamPart extends AbstractPart {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ReadStreamPart.class);\n\n  private final Context context;\n\n  private final ReadStream<Buffer> readStream;\n\n  public ReadStreamPart(Context context, HttpClientResponse httpClientResponse) {\n    this(context, (ReadStream<Buffer>) httpClientResponse);\n\n    setSubmittedFileName(\n        HttpUtils.parseFileNameFromHeaderValue(httpClientResponse.getHeader(HttpHeaders.CONTENT_DISPOSITION)));\n\n    String contentType = httpClientResponse.getHeader(HttpHeaders.CONTENT_TYPE);\n    if (StringUtils.isNotEmpty(contentType)) {\n      this.contentType(contentType);\n    }\n  }\n\n  public ReadStreamPart(Context context, ReadStream<Buffer> readStream) {\n    this.context = context;\n    this.readStream = readStream;\n\n    readStream.pause();\n  }\n\n  public Context getContext() {\n    return context;\n  }\n\n  public ReadStream<Buffer> getReadStream() {\n    return readStream;\n  }\n\n  /**\n   * @return future of save action<br>\n   *\n   * important: WriteStream did not provide endHandler, so we can not know when will really finished write.\n   * so the return future only means finished read from readStream.\n   */\n  public CompletableFuture<Void> saveToWriteStream(WriteStream<Buffer> writeStream) {\n    return new PumpCommon().pump(readStream, writeStream, null);\n  }\n\n  public CompletableFuture<byte[]> saveAsBytes() {\n    return saveAs(Buffer::getBytes);\n  }\n\n  public CompletableFuture<String> saveAsString() {\n    return saveAs(Buffer::toString);\n  }\n\n  public <T> CompletableFuture<T> saveAs(Function<Buffer, T> converter) {\n    CompletableFuture<T> future = new CompletableFuture<>();\n    Buffer buffer = Buffer.buffer();\n\n    // if readStream.resume() not run on correct eventloop, will:\n    //  1.create a context task to save last chunk data to buffer\n    //  2.activate connection to read new data\n    //  but maybe 2 will run before 1, that will cause lost data or get incorrect data\n    context.runOnContext(V -> {\n      readStream.exceptionHandler(future::completeExceptionally);\n      readStream.handler(buffer::appendBuffer);\n      readStream.endHandler(v -> future.complete(converter.apply(buffer)));\n      readStream.resume();\n    });\n\n    return future;\n  }\n\n  /**\n   * @return future of save to file, future complete means write to file finished\n   */\n  public CompletableFuture<File> saveToFile(String fileName) {\n    File file = new File(fileName);\n    file.getParentFile().mkdirs();\n    OpenOptions openOptions = new OpenOptions().setCreateNew(true);\n    return saveToFile(file, openOptions);\n  }\n\n  /**\n   * @return future of save to file, future complete means write to file finished\n   */\n  public CompletableFuture<File> saveToFile(File file, OpenOptions openOptions) {\n    CompletableFuture<File> future = new CompletableFuture<>();\n\n    context.runOnContext((v) -> {\n      Vertx vertx = context.owner();\n      Future<AsyncFile> openFuture = vertx.fileSystem().open(file.getAbsolutePath(), openOptions);\n      openFuture.onComplete((s, f) -> onFileOpened(file, s, f, future));\n    });\n\n    return future;\n  }\n\n  protected void onFileOpened(File file, AsyncFile asyncFile, Throwable failure, CompletableFuture<File> future) {\n    if (failure != null) {\n      future.completeExceptionally(failure);\n      return;\n    }\n\n    CompletableFuture<Void> saveFuture = saveToWriteStream(asyncFile);\n    saveFuture.whenComplete((v, saveException) -> {\n      Future<Void> result = asyncFile.close();\n      result.onComplete((s, f) -> {\n        if (f != null) {\n          LOGGER.error(\"Failed to close file {}.\", file);\n        }\n\n        // whatever close success or failed\n        // will not affect to result\n        // result just only related to write\n        if (saveException == null) {\n          future.complete(file);\n          return;\n        }\n\n        future.completeExceptionally(saveException);\n      });\n    });\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/StandardHttpServletRequestEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.http.NameValuePair;\nimport org.apache.http.client.utils.URLEncodedUtils;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.core.buffer.Buffer;\nimport jakarta.servlet.ServletInputStream;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletRequestWrapper;\nimport jakarta.ws.rs.HttpMethod;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class StandardHttpServletRequestEx extends HttpServletRequestWrapper implements HttpServletRequestEx {\n  private final BodyBufferSupport bodyBuffer = new BodyBufferSupportImpl();\n\n  private boolean cacheRequest;\n\n  private ServletInputStream inputStream;\n\n  // by servlet specification\n  // only parse application/x-www-form-urlencoded of post request automatically\n  // we will parse this even not post method\n  private Map<String, String[]> parameterMap;\n\n  public StandardHttpServletRequestEx(HttpServletRequest request) {\n    super(request);\n  }\n\n  public void setCacheRequest(boolean cacheRequest) {\n    this.cacheRequest = cacheRequest;\n  }\n\n  @VisibleForTesting\n  public boolean isCacheRequest() {\n    return cacheRequest;\n  }\n\n  @Override\n  public ServletInputStream getInputStream() throws IOException {\n    if (this.inputStream == null) {\n      if (cacheRequest) {\n        byte[] inputBytes = IOUtils.toByteArray(getRequest().getInputStream());\n        Buffer byteBuf = Buffer.buffer(inputBytes);\n        this.inputStream = new BufferInputStream(byteBuf);\n        setBodyBuffer(byteBuf);\n      } else {\n        this.inputStream = getRequest().getInputStream();\n      }\n    }\n    return this.inputStream;\n  }\n\n  @Override\n  public void setBodyBuffer(Buffer bodyBuffer) {\n    this.bodyBuffer.setBodyBuffer(bodyBuffer);\n  }\n\n  @Override\n  public Buffer getBodyBuffer() {\n    return bodyBuffer.getBodyBuffer();\n  }\n\n  @Override\n  public byte[] getBodyBytes() {\n    return bodyBuffer.getBodyBytes();\n  }\n\n  @Override\n  public int getBodyBytesLength() {\n    return bodyBuffer.getBodyBytesLength();\n  }\n\n  private Map<String, String[]> parseParameterMap() {\n    // 1.post method already parsed by servlet\n    // 2.not APPLICATION_FORM_URLENCODED, no need to enhance\n    if (getMethod().equalsIgnoreCase(HttpMethod.POST)\n        || !StringUtils.startsWithIgnoreCase(getContentType(), MediaType.APPLICATION_FORM_URLENCODED)) {\n      return super.getParameterMap();\n    }\n\n    Map<String, List<String>> listMap = parseUrlEncodedBody();\n    mergeParameterMaptoListMap(listMap);\n    return convertListMapToArrayMap(listMap);\n  }\n\n  private Map<String, String[]> convertListMapToArrayMap(Map<String, List<String>> listMap) {\n    Map<String, String[]> arrayMap = new HashMap<>();\n    for (Entry<String, List<String>> entry : listMap.entrySet()) {\n      arrayMap.put(entry.getKey(), entry.getValue().toArray(new String[0]));\n    }\n    return arrayMap;\n  }\n\n  private void mergeParameterMaptoListMap(Map<String, List<String>> listMap) {\n    for (Entry<String, String[]> entry : super.getParameterMap().entrySet()) {\n      List<String> values = listMap.computeIfAbsent(entry.getKey(), k -> new ArrayList<>());\n      // follow servlet behavior, inherited value first, and then body value\n      values.addAll(0, Arrays.asList(entry.getValue()));\n    }\n  }\n\n  private Map<String, List<String>> parseUrlEncodedBody() {\n    try (InputStream inputStream = getInputStream()) {\n      Map<String, List<String>> listMap = new HashMap<>();\n      String body = IOUtils.toString(inputStream, StandardCharsets.UTF_8);\n      List<NameValuePair> pairs = URLEncodedUtils\n          .parse(body, getCharacterEncoding() == null ? null : Charset.forName(getCharacterEncoding()));\n      for (NameValuePair pair : pairs) {\n        List<String> values = listMap.computeIfAbsent(pair.getName(), k -> new ArrayList<>());\n        values.add(pair.getValue());\n      }\n      return listMap;\n    } catch (IOException e) {\n      throw new IllegalStateException(\"\", e);\n    }\n  }\n\n  @Override\n  public String[] getParameterValues(String name) {\n    return getParameterMap().get(name);\n  }\n\n  @Override\n  public String getParameter(String name) {\n    String[] values = getParameterMap().get(name);\n    return values == null ? null : values[0];\n  }\n\n  @Override\n  public Enumeration<String> getParameterNames() {\n    return Collections.enumeration(getParameterMap().keySet());\n  }\n\n  @Override\n  public Map<String, String[]> getParameterMap() {\n    if (parameterMap == null) {\n      parameterMap = parseParameterMap();\n    }\n\n    return parameterMap;\n  }\n\n  @Override\n  public void setParameter(String name, String value) {\n    getParameterMap().put(name, new String[] {value});\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/StandardHttpServletResponseEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.foundation.vertx.stream.PumpFromPart;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.buffer.Buffer;\nimport jakarta.servlet.http.HttpServletResponse;\nimport jakarta.servlet.http.HttpServletResponseWrapper;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class StandardHttpServletResponseEx extends HttpServletResponseWrapper implements HttpServletResponseEx {\n  private final BodyBufferSupport bodyBuffer = new BodyBufferSupportImpl();\n\n  private final Map<String, Object> attributes = new HashMap<>();\n\n  private StatusType statusType;\n\n  public StandardHttpServletResponseEx(HttpServletResponse response) {\n    super(response);\n  }\n\n  @Override\n  public void setBodyBuffer(Buffer bodyBuffer) {\n    this.bodyBuffer.setBodyBuffer(bodyBuffer);\n  }\n\n  @Override\n  public Buffer getBodyBuffer() {\n    return bodyBuffer.getBodyBuffer();\n  }\n\n  @Override\n  public byte[] getBodyBytes() {\n    return bodyBuffer.getBodyBytes();\n  }\n\n  @Override\n  public int getBodyBytesLength() {\n    return bodyBuffer.getBodyBytesLength();\n  }\n\n  @Override\n  public void setStatus(int sc) {\n    super.setStatus(sc);\n    statusType = Status.fromStatusCode(sc);\n  }\n\n  @Override\n  public int getStatus() {\n    return statusType.getStatusCode();\n  }\n\n  @Override\n  public StatusType getStatusType() {\n    return statusType;\n  }\n\n  @Override\n  public void endResponse() throws IOException {\n    super.flushBuffer();\n  }\n\n  @Override\n  public void setAttribute(String key, Object value) {\n    this.attributes.put(key, value);\n  }\n\n  @Override\n  public Object getAttribute(String key) {\n    return this.attributes.get(key);\n  }\n\n  @Override\n  public CompletableFuture<Void> sendPart(Part part) {\n    if (part == null) {\n      return CompletableFuture.completedFuture(null);\n    }\n\n    DownloadUtils.prepareDownloadHeader(this, part);\n\n    OutputStream outputStream;\n    try {\n      outputStream = getOutputStream();\n    } catch (IOException e) {\n      CompletableFuture<Void> future = new CompletableFuture<>();\n      future.completeExceptionally(e);\n      return future;\n    }\n\n    // if context is null, then will switch to sync logic\n    Context context = Vertx.currentContext();\n    return new PumpFromPart(context, part).toOutputStream(outputStream, false);\n  }\n\n  @Override\n  public CompletableFuture<Void> sendBuffer(Buffer buffer) {\n    CompletableFuture<Void> future = new CompletableFuture<>();\n    try {\n      getOutputStream().write(buffer.getBytes(), 0, buffer.length());\n      future.complete(null);\n    } catch (IOException e) {\n      future.completeExceptionally(e);\n    }\n    return future;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxClientRequestToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.util.Collections;\nimport java.util.Enumeration;\n\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\n\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\nimport jakarta.ws.rs.core.HttpHeaders;\n\npublic class VertxClientRequestToHttpServletRequest extends AbstractHttpServletRequest {\n  private final HttpClientRequest clientRequest;\n\n  private String characterEncoding;\n\n  public VertxClientRequestToHttpServletRequest(HttpClientRequest clientRequest, Buffer bodyBuffer) {\n    this.clientRequest = clientRequest;\n    setBodyBuffer(bodyBuffer);\n  }\n\n  @Override\n  public String getRequestURI() {\n    return clientRequest.path();\n  }\n\n  @Override\n  public StringBuffer getRequestURL() {\n    return new StringBuffer(clientRequest.path());\n  }\n\n  @Override\n  public String getQueryString() {\n    return clientRequest.query();\n  }\n\n  @Override\n  public String getHeader(String name) {\n    return clientRequest.headers().get(name);\n  }\n\n  @Override\n  public Enumeration<String> getHeaders(String name) {\n    return Collections.enumeration(clientRequest.headers().getAll(name));\n  }\n\n  @Override\n  public Enumeration<String> getHeaderNames() {\n    return Collections.enumeration(clientRequest.headers().names());\n  }\n\n  @Override\n  public void setHeader(String name, String value) {\n    clientRequest.headers().set(name, value);\n  }\n\n  @Override\n  public void addHeader(String name, String value) {\n    clientRequest.headers().add(name, value);\n  }\n\n  @Override\n  public String getContextPath() {\n    return \"\";\n  }\n\n  @Override\n  public String getMethod() {\n    return clientRequest.getMethod().name();\n  }\n\n  @Override\n  public String getContentType() {\n    return clientRequest.headers().get(HttpHeaders.CONTENT_TYPE);\n  }\n\n  @Override\n  public String getCharacterEncoding() {\n    if (characterEncoding == null) {\n      characterEncoding = HttpUtils.getCharsetFromContentType(getContentType());\n    }\n\n    return characterEncoding;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxClientResponseToHttpServletResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.util.Collection;\n\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.foundation.common.http.HttpStatus;\n\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientResponse;\n\npublic class VertxClientResponseToHttpServletResponse extends AbstractHttpServletResponse {\n  private final HttpClientResponse clientResponse;\n\n  private StatusType statusType;\n\n  public VertxClientResponseToHttpServletResponse(HttpClientResponse clientResponse, Buffer bodyBuffer) {\n    this.clientResponse = clientResponse;\n    setBodyBuffer(bodyBuffer);\n  }\n\n  @Override\n  public int getStatus() {\n    return clientResponse.statusCode();\n  }\n\n  @Override\n  public StatusType getStatusType() {\n    if (statusType == null) {\n      statusType = new HttpStatus(clientResponse.statusCode(), clientResponse.statusMessage());\n    }\n    return statusType;\n  }\n\n  @Override\n  public String getContentType() {\n    return clientResponse.getHeader(HttpHeaders.CONTENT_TYPE);\n  }\n\n  @Override\n  public String getHeader(String name) {\n    return clientResponse.getHeader(name);\n  }\n\n  @Override\n  public Collection<String> getHeaders(String name) {\n    return clientResponse.headers().getAll(name);\n  }\n\n  @Override\n  public Collection<String> getHeaderNames() {\n    return clientResponse.headers().names();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerRequestToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.ext.web.FileUpload;\nimport io.vertx.ext.web.RoutingContext;\nimport io.vertx.ext.web.impl.RoutingContextInternal;\nimport jakarta.servlet.AsyncContext;\nimport jakarta.servlet.ServletInputStream;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\n\n// wrap vertx http request to Servlet http request\npublic class VertxServerRequestToHttpServletRequest extends AbstractHttpServletRequest {\n  private static final Logger LOGGER = LoggerFactory.getLogger(VertxServerRequestToHttpServletRequest.class);\n\n  private static final EmptyAsyncContext EMPTY_ASYNC_CONTEXT = new EmptyAsyncContext();\n\n  private final RoutingContext context;\n\n  private final HttpServerRequest vertxRequest;\n\n  private Cookie[] cookies;\n\n  private ServletInputStream inputStream;\n\n  private String path;\n\n  private final SocketAddress socketAddress;\n\n  // cache from convert vertx parameters to servlet parameters\n  private Map<String, String[]> parameterMap;\n\n  private String characterEncoding;\n\n  public VertxServerRequestToHttpServletRequest(RoutingContext context, String path) {\n    this(context);\n    this.path = path;\n  }\n\n  public VertxServerRequestToHttpServletRequest(RoutingContext context) {\n    this.context = context;\n    this.vertxRequest = context.request();\n    this.socketAddress = this.vertxRequest.remoteAddress();\n    super.setBodyBuffer(context.body().buffer());\n  }\n\n  @Override\n  public void setBodyBuffer(Buffer bodyBuffer) {\n    super.setBodyBuffer(bodyBuffer);\n    if (context instanceof RoutingContextInternal) {\n      RoutingContextInternal contextInternal = (RoutingContextInternal) context;\n      contextInternal.setBody(bodyBuffer);\n    }\n    this.inputStream = null;\n  }\n\n  @Override\n  public String getContentType() {\n    return this.vertxRequest.getHeader(HttpHeaders.CONTENT_TYPE);\n  }\n\n  @Override\n  public Cookie[] getCookies() {\n    if (cookies == null) {\n      Set<io.vertx.core.http.Cookie> cookieSet = context.request().cookies();\n      Cookie[] tmpCookies = new Cookie[cookieSet.size()];\n      int idx = 0;\n      for (io.vertx.core.http.Cookie vertxCookie : cookieSet) {\n        Cookie cookie = new Cookie(vertxCookie.getName(), vertxCookie.getValue());\n        tmpCookies[idx] = cookie;\n        idx++;\n      }\n      cookies = tmpCookies;\n    }\n    return cookies;\n  }\n\n  @Override\n  public String getParameter(String name) {\n    if (parameterMap != null) {\n      String[] values = parameterMap.get(name);\n      return values == null ? null : values[0];\n    }\n\n    return this.vertxRequest.getParam(name);\n  }\n\n  @Override\n  public Enumeration<String> getParameterNames() {\n    if (parameterMap != null) {\n      return Collections.enumeration(parameterMap.keySet());\n    }\n\n    return Collections.enumeration(this.vertxRequest.params().names());\n  }\n\n  @Override\n  public String[] getParameterValues(String name) {\n    if (parameterMap != null) {\n      return parameterMap.get(name);\n    }\n\n    List<String> paramList = this.vertxRequest.params().getAll(name);\n    return paramList.toArray(new String[0]);\n  }\n\n  @Override\n  public Map<String, String[]> getParameterMap() {\n    if (parameterMap == null) {\n      Map<String, String[]> paramMap = new HashMap<>();\n      MultiMap map = this.vertxRequest.params();\n      for (String name : map.names()) {\n        paramMap.put(name, map.getAll(name).toArray(new String[0]));\n      }\n      parameterMap = paramMap;\n    }\n\n    return parameterMap;\n  }\n\n  @Override\n  public void setParameter(String name, String value) {\n    if (parameterMap != null) {\n      parameterMap.put(name, new String[] {value});\n      return;\n    }\n\n    vertxRequest.params().set(name, value);\n  }\n\n  @Override\n  public String getScheme() {\n    return this.vertxRequest.scheme();\n  }\n\n  @Override\n  public String getRemoteAddr() {\n    return this.socketAddress.host();\n  }\n\n  @Override\n  public String getRemoteHost() {\n    return this.socketAddress.host();\n  }\n\n  @Override\n  public int getRemotePort() {\n    return this.socketAddress.port();\n  }\n\n  @Override\n  public String getLocalAddr() {\n    return this.vertxRequest.localAddress().host();\n  }\n\n  @Override\n  public int getLocalPort() {\n    return this.vertxRequest.localAddress().port();\n  }\n\n  @Override\n  public String getHeader(String name) {\n    return this.vertxRequest.getHeader(name);\n  }\n\n  @Override\n  public Enumeration<String> getHeaders(String name) {\n    return Collections.enumeration(this.vertxRequest.headers().getAll(name));\n  }\n\n  @Override\n  public Enumeration<String> getHeaderNames() {\n    return Collections.enumeration(vertxRequest.headers().names());\n  }\n\n  @Override\n  public int getIntHeader(String name) {\n    String header = this.vertxRequest.getHeader(name);\n    if (header == null) {\n      return -1;\n    }\n\n    return Integer.parseInt(header);\n  }\n\n  @Override\n  public String getMethod() {\n    return this.vertxRequest.method().name();\n  }\n\n  @Override\n  public String getPathInfo() {\n    return this.vertxRequest.path();\n  }\n\n  @Override\n  public String getQueryString() {\n    return this.vertxRequest.query();\n  }\n\n  @Override\n  public String getRequestURI() {\n    if (this.path == null) {\n      this.path = vertxRequest.path();\n    }\n    return this.path;\n  }\n\n  @Override\n  public StringBuffer getRequestURL() {\n    if (this.path == null) {\n      this.path = vertxRequest.path();\n    }\n    return new StringBuffer(this.path);\n  }\n\n  @Override\n  public String getServletPath() {\n    return this.getPathInfo();\n  }\n\n  @Override\n  public String getContextPath() {\n    return \"\";\n  }\n\n  @Override\n  public ServletInputStream getInputStream() {\n    if (inputStream != null) {\n      return inputStream;\n    }\n    if (context.body().buffer() == null) {\n      return null;\n    }\n    inputStream = new BufferInputStream(context.body().buffer());\n    return inputStream;\n  }\n\n  @Override\n  public AsyncContext getAsyncContext() {\n    return EMPTY_ASYNC_CONTEXT;\n  }\n\n  @Override\n  public Part getPart(String name) {\n    Optional<FileUpload> upload = context.fileUploads()\n        .stream()\n        .filter(fileUpload -> fileUpload.name().equals(name))\n        .findFirst();\n    if (!upload.isPresent()) {\n      LOGGER.debug(\"No such file with name: {}.\", name);\n      return null;\n    }\n\n    final FileUpload fileUpload = upload.get();\n    return new FileUploadPart(fileUpload);\n  }\n\n  @Override\n  public Collection<Part> getParts() {\n    return context.fileUploads().stream().map(FileUploadPart::new).collect(Collectors.toList());\n  }\n\n  public RoutingContext getContext() {\n    return context;\n  }\n\n  @Override\n  public String getCharacterEncoding() {\n    if (characterEncoding == null) {\n      characterEncoding = HttpUtils.getCharsetFromContentType(getContentType());\n    }\n\n    return characterEncoding;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.Objects;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.foundation.common.http.HttpStatus;\nimport org.apache.servicecomb.foundation.vertx.stream.PumpFromPart;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpServerResponse;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class VertxServerResponseToHttpServletResponse extends AbstractHttpServletResponse {\n  private final Context context;\n\n  private final HttpServerResponse serverResponse;\n\n  private StatusType statusType;\n\n  public VertxServerResponseToHttpServletResponse(HttpServerResponse serverResponse) {\n    this.context = Vertx.currentContext();\n    this.serverResponse = serverResponse;\n\n    Objects.requireNonNull(context, \"must run in vertx context.\");\n  }\n\n  @Override\n  public void setContentType(String type) {\n    serverResponse.headers().set(HttpHeaders.CONTENT_TYPE, type);\n  }\n\n  @Override\n  public void setContentLength(int len) {\n    serverResponse.headers().set(HttpHeaders.CONTENT_LENGTH, String.valueOf(len));\n  }\n\n\n  @Override\n  public void setStatus(int sc) {\n    serverResponse.setStatusCode(sc);\n  }\n\n  @Override\n  public StatusType getStatusType() {\n    if (statusType == null) {\n      statusType = new HttpStatus(serverResponse.getStatusCode(), serverResponse.getStatusMessage());\n    }\n    return statusType;\n  }\n\n  @Override\n  public void addHeader(String name, String value) {\n    serverResponse.headers().add(name, value);\n  }\n\n  @Override\n  public void setHeader(String name, String value) {\n    serverResponse.headers().set(name, value);\n  }\n\n  @Override\n  public int getStatus() {\n    return serverResponse.getStatusCode();\n  }\n\n  @Override\n  public String getContentType() {\n    return serverResponse.headers().get(HttpHeaders.CONTENT_TYPE);\n  }\n\n  @Override\n  public String getHeader(String name) {\n    return serverResponse.headers().get(name);\n  }\n\n  @Override\n  public Collection<String> getHeaders(String name) {\n    return serverResponse.headers().getAll(name);\n  }\n\n  @Override\n  public Collection<String> getHeaderNames() {\n    return serverResponse.headers().names();\n  }\n\n  @Override\n  public void endResponse() {\n    if (context == Vertx.currentContext()) {\n      internalFlushBuffer();\n      return;\n    }\n\n    context.runOnContext(V -> internalFlushBuffer());\n  }\n\n  public void internalFlushBuffer() {\n    if (serverResponse.closed()) {\n      return;\n    }\n    serverResponse.end();\n  }\n\n  @Override\n  public CompletableFuture<Void> sendPart(Part part) {\n    DownloadUtils.prepareDownloadHeader(this, part);\n    if (part == null) {\n      return CompletableFuture.completedFuture(null);\n    }\n    return new PumpFromPart(context, part).toWriteStream(serverResponse, null);\n  }\n\n  @Override\n  public CompletableFuture<Void> sendBuffer(Buffer buffer) {\n    if (serverResponse.closed()) {\n      return CompletableFuture.failedFuture(new IOException(\"Response is closed before sending any data. \"\n          + \"Maybe client is timeout or check idle connection timeout for provider is properly configured.\"));\n    }\n    CompletableFuture<Void> future = new CompletableFuture<>();\n    serverResponse.write(buffer).onComplete(result -> {\n      if (result.failed()) {\n        future.completeExceptionally(result.cause());\n      } else {\n        future.complete(null);\n      }\n    });\n    return future;\n  }\n\n  @Override\n  public void setChunked(boolean chunked) {\n    serverResponse.setChunked(chunked);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultClientMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport io.vertx.core.spi.metrics.ClientMetrics;\nimport io.vertx.core.spi.observability.HttpRequest;\nimport io.vertx.core.spi.observability.HttpResponse;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric;\n\npublic class DefaultClientMetrics implements\n    ClientMetrics<DefaultRequestMetric, HttpRequest, HttpResponse> {\n  private final DefaultClientEndpointMetric clientEndpointMetric;\n\n  public DefaultClientMetrics(DefaultClientEndpointMetric clientEndpointMetric) {\n    this.clientEndpointMetric = clientEndpointMetric;\n  }\n\n  public DefaultClientEndpointMetric getClientEndpointMetric() {\n    return this.clientEndpointMetric;\n  }\n\n  @Override\n  public DefaultRequestMetric requestBegin(String uri, HttpRequest request) {\n    DefaultRequestMetric requestMetric = new DefaultRequestMetric(this.clientEndpointMetric);\n    requestMetric.requestBegin();\n    return requestMetric;\n  }\n\n  @Override\n  public void requestEnd(DefaultRequestMetric requestMetric, long bytesWritten) {\n    requestMetric.requestEnd();\n  }\n\n  @Override\n  public void responseBegin(DefaultRequestMetric requestMetric, HttpResponse response) {\n    requestMetric.responseBegin();\n  }\n\n  @Override\n  public void responseEnd(DefaultRequestMetric requestMetric, long bytesRead) {\n    requestMetric.responseEnd();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\n\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.spi.metrics.HttpClientMetrics;\n\npublic class DefaultHttpClientMetrics implements\n    HttpClientMetrics<DefaultRequestMetric, Object, DefaultTcpSocketMetric> {\n  private static final String PROTOCOL = \"http://\";\n\n  private final DefaultClientEndpointMetricManager clientEndpointMetricManager;\n\n  public DefaultHttpClientMetrics(DefaultClientEndpointMetricManager clientEndpointMetricManager) {\n    this.clientEndpointMetricManager = clientEndpointMetricManager;\n  }\n\n  @Override\n  public DefaultClientMetrics createEndpointMetrics(\n      SocketAddress remoteAddress, int maxPoolSize) {\n    return new DefaultClientMetrics(\n        getOrCreateEndpointMetric(remoteAddress));\n  }\n\n  private DefaultClientEndpointMetric getOrCreateEndpointMetric(SocketAddress remoteAddress) {\n    return this.clientEndpointMetricManager\n        .getOrCreateEndpointMetric(PROTOCOL + remoteAddress.host() + \":\" + remoteAddress.port());\n  }\n\n  @Override\n  public DefaultTcpSocketMetric connected(SocketAddress remoteAddress, String remoteName) {\n    DefaultTcpSocketMetric socketMetric = new DefaultTcpSocketMetric(\n        getOrCreateEndpointMetric(remoteAddress));\n    socketMetric.onConnect();\n    return socketMetric;\n  }\n\n  @Override\n  public void disconnected(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress) {\n    socketMetric.onDisconnect();\n  }\n\n  @Override\n  public void bytesRead(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesRead(numberOfBytes);\n  }\n\n  @Override\n  public void bytesWritten(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesWritten(numberOfBytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\n\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.spi.metrics.HttpServerMetrics;\nimport io.vertx.core.spi.observability.HttpRequest;\nimport io.vertx.core.spi.observability.HttpResponse;\n\n/**\n * important: not singleton, every HttpServer instance relate to an HttpServerMetrics instance\n */\npublic class DefaultHttpServerMetrics implements\n    HttpServerMetrics<DefaultRequestMetric, Object, DefaultTcpSocketMetric> {\n  private final DefaultServerEndpointMetric endpointMetric;\n\n  public DefaultHttpServerMetrics(DefaultServerEndpointMetric endpointMetric) {\n    this.endpointMetric = endpointMetric;\n  }\n\n  public DefaultServerEndpointMetric getEndpointMetric() {\n    return endpointMetric;\n  }\n\n  @Override\n  public DefaultRequestMetric requestBegin(DefaultTcpSocketMetric socketMetric, HttpRequest request) {\n    DefaultRequestMetric requestMetric = new DefaultRequestMetric(socketMetric.getEndpointMetric());\n    requestMetric.requestBegin();\n    return requestMetric;\n  }\n\n  @Override\n  public void requestEnd(DefaultRequestMetric requestMetric, HttpRequest request, long bytesRead) {\n    requestMetric.requestEnd();\n  }\n\n  @Override\n  public void responseBegin(DefaultRequestMetric requestMetric, HttpResponse response) {\n    requestMetric.responseBegin();\n  }\n\n  @Override\n  public void responseEnd(DefaultRequestMetric requestMetric, HttpResponse response, long bytesWritten) {\n    requestMetric.responseEnd();\n  }\n\n  @Override\n  public DefaultTcpSocketMetric connected(SocketAddress remoteAddress, String remoteName) {\n    DefaultTcpSocketMetric socketMetric = new DefaultTcpSocketMetric(endpointMetric);\n    socketMetric.onConnect();\n    return socketMetric;\n  }\n\n  @Override\n  public void disconnected(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress) {\n    socketMetric.onDisconnect();\n  }\n\n  @Override\n  public void bytesRead(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesRead(numberOfBytes);\n  }\n\n  @Override\n  public void bytesWritten(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesWritten(numberOfBytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpClientMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\n\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.spi.metrics.TCPMetrics;\n\n/**\n * important: not singleton, every NetClient instance relate to a TCPMetrics instance\n */\npublic class DefaultTcpClientMetrics implements TCPMetrics<DefaultTcpSocketMetric> {\n  private static final String PROTOCOL = \"tcp://\";\n\n  private final DefaultClientEndpointMetricManager clientEndpointMetricManager;\n\n  public DefaultTcpClientMetrics(DefaultClientEndpointMetricManager clientEndpointMetricManager) {\n    this.clientEndpointMetricManager = clientEndpointMetricManager;\n  }\n\n  @Override\n  public DefaultTcpSocketMetric connected(SocketAddress remoteAddress, String remoteName) {\n    DefaultClientEndpointMetric endpointMetric = this.clientEndpointMetricManager\n        .getOrCreateEndpointMetric(PROTOCOL + remoteAddress.toString());\n    DefaultTcpSocketMetric socketMetric = new DefaultTcpSocketMetric(endpointMetric);\n    socketMetric.onConnect();\n    return socketMetric;\n  }\n\n  @Override\n  public void disconnected(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress) {\n    socketMetric.onDisconnect();\n  }\n\n  @Override\n  public void bytesRead(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesRead(numberOfBytes);\n  }\n\n  @Override\n  public void bytesWritten(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesWritten(numberOfBytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpServerMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\n\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.spi.metrics.TCPMetrics;\n\n/**\n * important: not singleton, every NetServer instance relate to a TcpServerMetrics instance\n */\npublic class DefaultTcpServerMetrics implements TCPMetrics<DefaultTcpSocketMetric> {\n  private final DefaultServerEndpointMetric endpointMetric;\n\n  public DefaultTcpServerMetrics(DefaultServerEndpointMetric endpointMetric) {\n    this.endpointMetric = endpointMetric;\n  }\n\n  public DefaultServerEndpointMetric getEndpointMetric() {\n    return endpointMetric;\n  }\n\n  @Override\n  public DefaultTcpSocketMetric connected(SocketAddress remoteAddress, String remoteName) {\n    DefaultTcpSocketMetric socketMetric = new DefaultTcpSocketMetric(endpointMetric);\n    socketMetric.onConnect();\n    return socketMetric;\n  }\n\n  @Override\n  public void disconnected(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress) {\n    socketMetric.onDisconnect();\n  }\n\n  @Override\n  public void bytesRead(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesRead(numberOfBytes);\n  }\n\n  @Override\n  public void bytesWritten(DefaultTcpSocketMetric socketMetric, SocketAddress remoteAddress, long numberOfBytes) {\n    socketMetric.getEndpointMetric().addBytesWritten(numberOfBytes);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport java.util.Map;\n\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.HttpServerOptions;\nimport io.vertx.core.net.NetClientOptions;\nimport io.vertx.core.net.NetServerOptions;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.spi.metrics.HttpClientMetrics;\nimport io.vertx.core.spi.metrics.HttpServerMetrics;\nimport io.vertx.core.spi.metrics.TCPMetrics;\nimport io.vertx.core.spi.metrics.VertxMetrics;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric;\n\npublic class DefaultVertxMetrics implements VertxMetrics {\n  // to support listen multiple addresses, must use a map to manage the metric\n  private final Map<String, DefaultServerEndpointMetric> serverEndpointMetricMap = new ConcurrentHashMapEx<>();\n\n  private final DefaultClientEndpointMetricManager clientEndpointMetricManager;\n\n  public DefaultVertxMetrics(VertxOptions vertxOptions) {\n    this.clientEndpointMetricManager = new DefaultClientEndpointMetricManager(\n        (MetricsOptionsEx) vertxOptions.getMetricsOptions());\n  }\n\n  public DefaultClientEndpointMetricManager getClientEndpointMetricManager() {\n    return clientEndpointMetricManager;\n  }\n\n  public Map<String, DefaultServerEndpointMetric> getServerEndpointMetricMap() {\n    return serverEndpointMetricMap;\n  }\n\n  @Override\n  public HttpServerMetrics<?, ?, ?> createHttpServerMetrics(HttpServerOptions options, SocketAddress localAddress) {\n    DefaultServerEndpointMetric endpointMetric = serverEndpointMetricMap\n        .computeIfAbsent(localAddress.toString(), DefaultServerEndpointMetric::new);\n    return new DefaultHttpServerMetrics(endpointMetric);\n  }\n\n  @Override\n  public HttpClientMetrics<?, ?, ?> createHttpClientMetrics(HttpClientOptions options) {\n    return new DefaultHttpClientMetrics(clientEndpointMetricManager);\n  }\n\n  @Override\n  public TCPMetrics<?> createNetServerMetrics(NetServerOptions options, SocketAddress localAddress) {\n    DefaultServerEndpointMetric endpointMetric = serverEndpointMetricMap\n        .computeIfAbsent(localAddress.toString(), DefaultServerEndpointMetric::new);\n    return new DefaultTcpServerMetrics(endpointMetric);\n  }\n\n  @Override\n  public TCPMetrics<?> createNetClientMetrics(NetClientOptions options) {\n    return new DefaultTcpClientMetrics(clientEndpointMetricManager);\n  }\n\n  @Override\n  public boolean isMetricsEnabled() {\n    return true;\n  }\n\n  public void setVertx(Vertx vertx) {\n    clientEndpointMetricManager.setVertx(vertx);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.json.JsonObject;\nimport io.vertx.core.metrics.MetricsOptions;\nimport io.vertx.core.spi.VertxMetricsFactory;\nimport io.vertx.core.spi.metrics.VertxMetrics;\n\n/**\n * <pre>\n * only for one vertx instance\n * DO NOT inject to vertx by SPI\n * typical usage:\n *     DefaultVertxMetricsFactory factory = new DefaultVertxMetricsFactory();\n *     MetricsOptionsEx metricsOptionsEx = (MetricsOptionsEx) factory.newOptions();\n *\n *     VertxOptions vertxOptions = new VertxOptions();\n *     vertxOptions.setMetricsOptions(metricsOptionsEx);\n *\n *     Vertx vertx = Vertx.vertx(vertxOptions);\n * </pre>\n */\npublic class DefaultVertxMetricsFactory implements VertxMetricsFactory {\n  private DefaultVertxMetrics vertxMetrics;\n\n  public DefaultVertxMetrics getVertxMetrics() {\n    return vertxMetrics;\n  }\n\n  @Override\n  public synchronized VertxMetrics metrics(VertxOptions options) {\n    if (vertxMetrics == null) {\n      vertxMetrics = new DefaultVertxMetrics(options);\n    }\n    return vertxMetrics;\n  }\n\n  @Override\n  public MetricsOptions newOptions() {\n    MetricsOptionsEx metricsOptions = new MetricsOptionsEx();\n    metricsOptions.setEnabled(true);\n    return metricsOptions;\n  }\n\n  @Override\n  public MetricsOptions newOptions(JsonObject jsonObject) {\n    return new MetricsOptionsEx(jsonObject);\n  }\n\n  @Override\n  public MetricsOptions newOptions(MetricsOptions options) {\n    return newOptions(options.toJson());\n  }\n\n  public void setVertx(Vertx vertx, VertxOptions options) {\n    if (vertxMetrics == null) {\n      vertxMetrics = new DefaultVertxMetrics(options);\n    }\n    vertxMetrics.setVertx(vertx);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/MetricsOptionsEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport java.util.concurrent.TimeUnit;\n\nimport io.vertx.core.json.JsonObject;\nimport io.vertx.core.metrics.MetricsOptions;\n\npublic class MetricsOptionsEx extends MetricsOptions {\n  private long checkClientEndpointMetricIntervalInMilliseconds = TimeUnit.MINUTES.toMillis(1);\n\n  private long checkClientEndpointMetricExpiredInNano = TimeUnit.MINUTES.toNanos(15);\n\n  public MetricsOptionsEx() {\n    super();\n  }\n\n  public MetricsOptionsEx(JsonObject json) {\n    super(json);\n  }\n\n  public long getCheckClientEndpointMetricIntervalInMilliseconds() {\n    return checkClientEndpointMetricIntervalInMilliseconds;\n  }\n\n  public void setCheckClientEndpointMetricIntervalInMinute(long minute) {\n    this.checkClientEndpointMetricIntervalInMilliseconds = TimeUnit.MINUTES.toMillis(minute);\n  }\n\n  public long getCheckClientEndpointMetricExpiredInNano() {\n    return checkClientEndpointMetricExpiredInNano;\n  }\n\n  public void setCheckClientEndpointMetricExpiredInNano(long nanoTime) {\n    this.checkClientEndpointMetricExpiredInNano = nanoTime;\n  }\n\n  public void setCheckClientEndpointMetricExpiredInMinute(long minute) {\n    this.checkClientEndpointMetricExpiredInNano = TimeUnit.MINUTES.toNanos(minute);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\nimport java.util.concurrent.atomic.LongAdder;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n * for one listen address, include multiple httpClient or httpServer\n */\npublic class DefaultClientEndpointMetric extends DefaultEndpointMetric {\n  private final LongAdder queue = new LongAdder();\n\n  // control if the metric instance will be expired\n  // all invoker about incRefCount/isExpired, must lock: DefaultClientEndpointMetricManager\n  // decRefCount no need to lock, because that only cause to be expired later.\n  private volatile long lastNanoTime = System.nanoTime();\n\n  public DefaultClientEndpointMetric(String address) {\n    super(address);\n  }\n\n  @VisibleForTesting\n  public long getLastNanoTime() {\n    return lastNanoTime;\n  }\n\n  @Override\n  public void onDisconnect() {\n    super.onDisconnect();\n    lastNanoTime = System.nanoTime();\n  }\n\n  public long getQueueCount() {\n    return queue.longValue();\n  }\n\n  public void enqueueRequest() {\n    queue.increment();\n  }\n\n  public void dequeueRequest() {\n    queue.decrement();\n  }\n\n  public boolean isExpired(long nsTimeout) {\n    return getCurrentConnectionCount() == 0\n        && (System.nanoTime() - lastNanoTime) > nsTimeout;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\nimport java.util.Map;\nimport java.util.concurrent.locks.ReadWriteLock;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.vertx.metrics.MetricsOptionsEx;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.core.Vertx;\n\npublic class DefaultClientEndpointMetricManager {\n  private final MetricsOptionsEx metricsOptionsEx;\n\n  // to avoid save too many endpoint that not exist any more\n  // must check expired periodically\n  private final Map<String, DefaultClientEndpointMetric> clientEndpointMetricMap = new ConcurrentHashMapEx<>();\n\n  // clientEndpointMetricMap is thread safe\n  // but get/isExpired/remove is not safe\n  //  1.isExpired\n  //  2.get\n  //  3.remove\n  // will get a removed instance\n  // so must lock the logic\n  private final ReadWriteLock rwlock = new ReentrantReadWriteLock();\n\n  public DefaultClientEndpointMetricManager(MetricsOptionsEx metricsOptionsEx) {\n    this.metricsOptionsEx = metricsOptionsEx;\n  }\n\n  public DefaultClientEndpointMetric getOrCreateEndpointMetric(String address) {\n    rwlock.readLock().lock();\n    try {\n      if (clientEndpointMetricMap.get(address) == null) {\n        clientEndpointMetricMap.put(address, new DefaultClientEndpointMetric(address));\n      }\n      return clientEndpointMetricMap.get(address);\n    } finally {\n      rwlock.readLock().unlock();\n    }\n  }\n\n  @VisibleForTesting\n  public DefaultClientEndpointMetric getClientEndpointMetric(String serverAddress) {\n    return clientEndpointMetricMap.get(serverAddress);\n  }\n\n  public Map<String, DefaultClientEndpointMetric> getClientEndpointMetricMap() {\n    return clientEndpointMetricMap;\n  }\n\n  @VisibleForTesting\n  public void onCheckClientEndpointMetricExpired(long periodic) {\n    for (DefaultClientEndpointMetric metric : clientEndpointMetricMap.values()) {\n      if (metric.isExpired(metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano())) {\n        rwlock.writeLock().lock();\n        try {\n          if (metric.isExpired(metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano())) {\n            clientEndpointMetricMap.remove(metric.getAddress());\n          }\n        } finally {\n          rwlock.writeLock().unlock();\n        }\n      }\n    }\n  }\n\n  public void setVertx(Vertx vertx) {\n    vertx.setPeriodic(metricsOptionsEx.getCheckClientEndpointMetricIntervalInMilliseconds(),\n        this::onCheckClientEndpointMetricExpired);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientTaskMetric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\npublic class DefaultClientTaskMetric {\n  private final DefaultClientEndpointMetric endpointMetric;\n\n  public DefaultClientTaskMetric(DefaultClientEndpointMetric endpointMetric) {\n    this.endpointMetric = endpointMetric;\n  }\n\n  public void enqueueRequest() {\n    endpointMetric.enqueueRequest();\n  }\n\n  public void dequeueRequest() {\n    endpointMetric.dequeueRequest();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultEndpointMetric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\nimport java.util.concurrent.atomic.LongAdder;\n\n/**\n * for one listen address, include multiple httpClient or httpServer\n */\npublic class DefaultEndpointMetric {\n  private final String address;\n\n  // summary of connect times from boot\n  // by this, we can know how many new connections connected recently\n  private final LongAdder connectCount = new LongAdder();\n\n  // summary of disconnect times from boot\n  // by this, we can know how many connections disconnected recently\n  private final LongAdder disconnectCount = new LongAdder();\n\n  private final LongAdder bytesRead = new LongAdder();\n\n  private final LongAdder bytesWritten = new LongAdder();\n\n  private final LongAdder requests = new LongAdder();\n\n  private final LongAdder latency = new LongAdder();\n\n  public DefaultEndpointMetric(String address) {\n    this.address = address;\n  }\n\n  public String getAddress() {\n    return address;\n  }\n\n  public long getConnectCount() {\n    return connectCount.longValue();\n  }\n\n  public long getDisconnectCount() {\n    return disconnectCount.longValue();\n  }\n\n  public long getCurrentConnectionCount() {\n    return connectCount.longValue() - disconnectCount.longValue();\n  }\n\n  public void onConnect() {\n    connectCount.increment();\n  }\n\n  public void onDisconnect() {\n    disconnectCount.increment();\n  }\n\n  public long getBytesRead() {\n    return bytesRead.longValue();\n  }\n\n  public void addBytesRead(long bytes) {\n    bytesRead.add(bytes);\n  }\n\n  public long getBytesWritten() {\n    return bytesWritten.longValue();\n  }\n\n  public void addBytesWritten(long bytes) {\n    bytesWritten.add(bytes);\n  }\n\n  public void incrementRequests() {\n    requests.increment();\n  }\n\n  public long getRequests() {\n    return requests.longValue();\n  }\n\n  public void addLatency(long delta) {\n    latency.add(delta);\n  }\n\n  public long getLatency() {\n    return latency.longValue();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultRequestMetric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\npublic class DefaultRequestMetric {\n  private long requestBeginTime;\n\n  private long requestEndTime;\n\n  private long responseBeginTime;\n\n  private long responseEndTime;\n\n  private final DefaultEndpointMetric endpointMetric;\n\n  public DefaultRequestMetric(DefaultEndpointMetric endpointMetric) {\n    this.endpointMetric = endpointMetric;\n  }\n\n  public long getRequestBeginTime() {\n    return requestBeginTime != 0 ? requestBeginTime : System.nanoTime();\n  }\n\n  public long getRequestEndTime() {\n    return requestEndTime != 0 ? requestEndTime : System.nanoTime();\n  }\n\n  public long getResponseBeginTime() {\n    return responseBeginTime != 0 ? responseBeginTime : System.nanoTime();\n  }\n\n  public long getResponseEndTime() {\n    return responseEndTime != 0 ? responseEndTime : System.nanoTime();\n  }\n\n  public void requestBegin() {\n    this.requestBeginTime = System.nanoTime();\n  }\n\n  public void requestEnd() {\n    this.requestEndTime = System.nanoTime();\n  }\n\n  public void responseBegin() {\n    this.responseBeginTime = System.nanoTime();\n  }\n\n  public void responseEnd() {\n    this.responseEndTime = System.nanoTime();\n    this.endpointMetric.incrementRequests();\n    this.endpointMetric.addLatency(System.nanoTime() - this.requestBeginTime);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultServerEndpointMetric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\nimport java.util.concurrent.atomic.LongAdder;\n\npublic class DefaultServerEndpointMetric extends DefaultEndpointMetric {\n  private final LongAdder rejectByConnectionLimitCount = new LongAdder();\n\n  public DefaultServerEndpointMetric(String address) {\n    super(address);\n  }\n\n  public long getRejectByConnectionLimitCount() {\n    return rejectByConnectionLimitCount.longValue();\n  }\n\n  public void onRejectByConnectionLimit() {\n    rejectByConnectionLimitCount.increment();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultTcpSocketMetric.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics.metric;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class DefaultTcpSocketMetric {\n  protected DefaultEndpointMetric endpointMetric;\n\n  protected boolean connected = true;\n\n  protected long connectedTime = System.nanoTime();\n\n  public DefaultTcpSocketMetric(DefaultEndpointMetric endpointMetric) {\n    this.endpointMetric = endpointMetric;\n  }\n\n  public DefaultEndpointMetric getEndpointMetric() {\n    return endpointMetric;\n  }\n\n  @VisibleForTesting\n  public boolean isConnected() {\n    return connected;\n  }\n\n  public void onConnect() {\n    endpointMetric.onConnect();\n    this.connected = true;\n  }\n\n  public void onDisconnect() {\n    endpointMetric.onDisconnect();\n    this.connected = false;\n  }\n\n  @VisibleForTesting\n  public long getConnectedTime() {\n    return connectedTime;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpBufferHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.server;\n\nimport io.vertx.core.buffer.Buffer;\n\n/**\n * TcpBufferHandler\n *\n *\n */\npublic interface TcpBufferHandler {\n  void handle(long msgId, Buffer headerBuffer, Buffer bodyBuffer);\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.server;\n\nimport java.nio.charset.StandardCharsets;\n\nimport io.vertx.core.Handler;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.parsetools.RecordParser;\n\npublic class TcpParser implements Handler<Buffer> {\n  public static final byte[] TCP_MAGIC;\n\n  public static final int TCP_HEADER_LENGTH = 23;\n\n  static {\n    TCP_MAGIC = \"CSE.TCP\".getBytes(StandardCharsets.UTF_8);\n  }\n\n  enum ParseStatus {\n    TCP_HEADER,\n    TCP_PAYLOAD\n  }\n\n  private final TcpBufferHandler outputHandler;\n\n  private RecordParser parser;\n\n  private ParseStatus status;\n\n  private long msgId;\n\n  // 仅仅是header + body，不包括headerLen本身\n  private int totalLen;\n\n  private int headerLen;\n\n  public TcpParser(TcpBufferHandler output) {\n    this.outputHandler = output;\n\n    reset();\n  }\n\n  /**\n   * 在解析出错时，通过重新创建parser对象，将整个缓冲区重置\n   */\n  protected void reset() {\n    parser = RecordParser.newFixed(TCP_HEADER_LENGTH, this::onParse);\n    status = ParseStatus.TCP_HEADER;\n\n    parser.handle(Buffer.buffer(0));\n  }\n\n  public boolean firstNEqual(byte[] a, byte[] b, int n) {\n    assert a.length >= n && b.length >= n;\n\n    for (int i = 0; i < n; i++) {\n      if (a[i] != b[i]) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  protected void onParse(Buffer buffer) {\n    switch (status) {\n      case TCP_HEADER:\n        if (!firstNEqual(TCP_MAGIC, buffer.getBytes(), TCP_MAGIC.length)) {\n          reset();\n          return;\n        }\n\n        int index = TCP_MAGIC.length;\n        msgId = buffer.getLong(index);\n        index = index + 8;\n        totalLen = buffer.getInt(index);\n        index = index + 4;\n        headerLen = buffer.getInt(index);\n        if (headerLen > totalLen || headerLen <= 0) {\n          throw new IllegalStateException(\"possibly attack.\");\n        }\n\n        if (totalLen == 0) {\n          onReadOnePackage(null, null);\n          return;\n        }\n\n        parser.fixedSizeMode(totalLen);\n        status = ParseStatus.TCP_PAYLOAD;\n        break;\n\n      case TCP_PAYLOAD:\n        Buffer headerBuffer = buffer.slice(0, headerLen);\n        Buffer bodyBuffer = buffer.slice(headerLen, buffer.length());\n        onReadOnePackage(headerBuffer, bodyBuffer);\n        break;\n\n      default:\n        break;\n    }\n  }\n\n  private void onReadOnePackage(Buffer headerBuffer, Buffer bodyBuffer) {\n    outputHandler.handle(msgId, headerBuffer, bodyBuffer);\n\n    parser.fixedSizeMode(TCP_HEADER_LENGTH);\n    status = ParseStatus.TCP_HEADER;\n  }\n\n  public void handle(Buffer buf) {\n    parser.handle(buf);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.server;\n\nimport java.net.InetSocketAddress;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.ssl.SSLOptionFactory;\nimport org.apache.servicecomb.foundation.vertx.AsyncResultCallback;\nimport org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;\nimport org.apache.servicecomb.foundation.vertx.metrics.DefaultTcpServerMetrics;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.net.NetServer;\nimport io.vertx.core.net.NetServerOptions;\nimport io.vertx.core.net.impl.NetSocketImpl;\n\npublic class TcpServer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TcpServer.class);\n\n  private final URIEndpointObject endpointObject;\n\n  public TcpServer(URIEndpointObject endpointObject) {\n    this.endpointObject = endpointObject;\n  }\n\n  public void init(Vertx vertx, String sslKey, AsyncResultCallback<InetSocketAddress> callback) {\n    NetServer netServer;\n    if (endpointObject.isSslEnabled()) {\n      SSLOptionFactory factory =\n          SSLOptionFactory.createSSLOptionFactory(sslKey, LegacyPropertyFactory.getEnvironment());\n      SSLOption sslOption;\n      if (factory == null) {\n        sslOption = SSLOption.build(sslKey, LegacyPropertyFactory.getEnvironment());\n      } else {\n        sslOption = factory.createSSLOption();\n      }\n      SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass());\n      NetServerOptions serverOptions = new NetServerOptions();\n      VertxTLSBuilder.buildNetServerOptions(sslOption, sslCustom, serverOptions);\n      netServer = vertx.createNetServer(serverOptions);\n    } else {\n      netServer = vertx.createNetServer();\n    }\n\n    netServer.connectHandler(netSocket -> {\n      DefaultTcpServerMetrics serverMetrics = (DefaultTcpServerMetrics) ((NetSocketImpl) netSocket).metrics();\n      DefaultServerEndpointMetric endpointMetric = serverMetrics.getEndpointMetric();\n      long connectedCount = endpointMetric.getCurrentConnectionCount();\n      int connectionLimit = getConnectionLimit();\n      if (connectedCount > connectionLimit) {\n        netSocket.close();\n        endpointMetric.onRejectByConnectionLimit();\n        return;\n      }\n\n      TcpServerConnection connection = createTcpServerConnection();\n      connection.init(netSocket);\n    });\n    netServer.exceptionHandler(\n        e -> LOGGER.error(\"Unexpected error in server.\", e));\n    InetSocketAddress socketAddress = endpointObject.getSocketAddress();\n    Future<NetServer> result = netServer.listen(socketAddress.getPort(), socketAddress.getHostString());\n    result.onComplete((s, f) -> {\n      if (f == null) {\n        callback.success(socketAddress);\n        return;\n      }\n\n      // 监听失败\n      String msg = String.format(\"listen failed, address=%s\", socketAddress);\n      callback.fail(new Exception(msg, f));\n    });\n  }\n\n  protected int getConnectionLimit() {\n    return Integer.MAX_VALUE;\n  }\n\n  protected TcpServerConnection createTcpServerConnection() {\n    return new TcpServerConnection();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpServerConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.server;\n\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpConnection;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.net.NetSocket;\nimport io.vertx.core.net.impl.NetSocketImpl;\n\npublic class TcpServerConnection extends TcpConnection {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TcpServerConnection.class);\n\n  protected TcpParser splitter;\n\n  public void init(NetSocket netSocket) {\n    // currently, socket always be NetSocketImpl\n    this.initNetSocket((NetSocketImpl) netSocket);\n\n    String remoteAddress = netSocket.remoteAddress().toString();\n    LOGGER.info(\"connect from {}, in thread {}\",\n        remoteAddress,\n        Thread.currentThread().getName());\n    netSocket.exceptionHandler(e -> LOGGER.error(\"disconnected from {}, in thread {}, cause {}\",\n        remoteAddress,\n        Thread.currentThread().getName(),\n        e.getMessage()));\n    netSocket.closeHandler(Void -> LOGGER.info(\"disconnected from {}, in thread {}\",\n        remoteAddress,\n        Thread.currentThread().getName()));\n\n    netSocket.handler(splitter);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/BufferInputStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\n\nimport io.vertx.core.buffer.Buffer;\nimport jakarta.servlet.ReadListener;\nimport jakarta.servlet.ServletInputStream;\n\npublic class BufferInputStream extends ServletInputStream {\n  private int readIndex = 0;\n\n  private final Buffer byteBuf;\n\n  public BufferInputStream(Buffer buffer) {\n    this.byteBuf = buffer;\n  }\n\n  @Override\n  public long skip(long len) {\n    int skipLen = Math.min((int) len, available());\n    this.readIndex += skipLen;\n    return skipLen;\n  }\n\n  public byte readByte() {\n    int index = readIndex;\n    readIndex = index + 1;\n    return byteBuf.getByte(index);\n  }\n\n  @Override\n  public int read() {\n    return this.readByte() & 255;\n  }\n\n  public boolean readBoolean() {\n    return this.readByte() != 0;\n  }\n\n  public short readShort() {\n    int index = readIndex;\n    readIndex = index + 2;\n    return byteBuf.getShort(index);\n  }\n\n  public int readInt() {\n    int index = readIndex;\n    readIndex = index + 4;\n    return byteBuf.getInt(index);\n  }\n\n  public long readLong() {\n    int index = readIndex;\n    readIndex = index + 8;\n    return byteBuf.getLong(index);\n  }\n\n  public int getIndex() {\n    return readIndex;\n  }\n\n  public String readString() {\n    int length = readInt();\n    byte[] bytes = new byte[length];\n    int index = readIndex;\n    readIndex = index + length;\n    byteBuf.getBytes(index, readIndex, bytes);\n    return new String(bytes, StandardCharsets.UTF_8);\n  }\n\n  @Override\n  public int read(byte[] b) {\n    return read(b, 0, b.length);\n  }\n\n  @Override\n  public int read(byte[] b, int off, int len) {\n    int avail = available();\n    if (avail <= 0) {\n      return -1;\n    }\n\n    if (len == 0) {\n      return 0;\n    }\n\n    if (len > avail) {\n      len = avail;\n    }\n\n    int index = readIndex;\n    readIndex = index + len;\n\n    byteBuf.getBytes(index, readIndex, b);\n    return len;\n  }\n\n  @Override\n  public int available() {\n    return byteBuf.length() - readIndex;\n  }\n\n  @Override\n  public void close() {\n    // nothing to do\n  }\n\n  @Override\n  public void reset() throws IOException {\n    readIndex = 0;\n  }\n\n  public Buffer getByteBuf() {\n    return byteBuf;\n  }\n\n  @Override\n  public boolean isFinished() {\n    return byteBuf.length() > readIndex;\n  }\n\n  @Override\n  public boolean isReady() {\n    return true;\n  }\n\n  @Override\n  public void setReadListener(ReadListener readListener) {\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/BufferOutputStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.io.OutputStream;\nimport java.nio.charset.StandardCharsets;\n\nimport io.vertx.core.buffer.Buffer;\n\n/**\n * BufferOutputStream.\n *\n * Notice: will not release the underlining ByteBuffer, the user is responsible to release it.\n */\npublic class BufferOutputStream extends OutputStream {\n  private static final int DIRECT_BUFFER_SIZE = 1024;\n\n  protected Buffer byteBuf;\n\n  public BufferOutputStream() {\n    this(Buffer.buffer(DIRECT_BUFFER_SIZE));\n  }\n\n  public BufferOutputStream(Buffer buffer) {\n    this.byteBuf = buffer;\n  }\n\n  public Buffer getBuffer() {\n    return byteBuf;\n  }\n\n  public int length() {\n    return byteBuf.length();\n  }\n\n  public void writeByte(byte value) {\n    byteBuf.appendByte(value);\n  }\n\n  // 实际是写byte\n  @Override\n  public void write(int byteValue) {\n    byteBuf.appendByte((byte) byteValue);\n  }\n\n  public void write(boolean value) {\n    byteBuf.appendByte(value ? (byte) 1 : (byte) 0);\n  }\n\n  public void writeInt(int pos, int value) {\n    byteBuf.setInt(pos, value);\n  }\n\n  public void writeShort(short value) {\n    byteBuf.appendShort(value);\n  }\n\n  public void writeInt(int value) {\n    byteBuf.appendInt(value);\n  }\n\n  public void writeLong(long value) {\n    byteBuf.appendLong(value);\n  }\n\n  public void writeString(String value) {\n    writeInt(value.length());\n    byteBuf.appendString(value, StandardCharsets.UTF_8.toString());\n  }\n\n  @Override\n  public void write(byte[] b) {\n    write(b, 0, b.length);\n  }\n\n  @Override\n  public void write(byte[] bytes, int offset, int len) {\n    byteBuf.appendBytes(bytes, offset, len);\n  }\n\n  @Override\n  public void close() {\n    // Do no release byteBuf, the target BufferedInputStream will release it.\n  }\n\n  public int writerIndex() {\n    return byteBuf.length();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/InputStreamToReadStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Arrays;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Handler;\nimport io.vertx.core.Promise;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.streams.ReadStream;\n\npublic class InputStreamToReadStream implements ReadStream<Buffer> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(InputStreamToReadStream.class);\n\n  public static final int DEFAULT_READ_BUFFER_SIZE = 1024 * 1024;\n\n  private final Context context;\n\n  private final InputStream inputStream;\n\n  private volatile boolean closed;\n\n  private boolean paused;\n\n  private boolean readInProgress;\n\n  private int readBufferSize = DEFAULT_READ_BUFFER_SIZE;\n\n  private Handler<Throwable> exceptionHandler = this::unhandledException;\n\n  private Handler<Buffer> dataHandler;\n\n  private Handler<Void> endHandler;\n\n  private final boolean autoCloseInputStream;\n\n  public InputStreamToReadStream(Context context, InputStream inputStream,\n      boolean autoCloseInputStream) {\n    this.context = context;\n    this.inputStream = inputStream;\n    this.autoCloseInputStream = autoCloseInputStream;\n  }\n\n\n  public synchronized InputStreamToReadStream readBufferSize(int readBufferSize) {\n    this.readBufferSize = readBufferSize;\n    return this;\n  }\n\n  private void check() {\n    if (closed) {\n      throw new IllegalStateException(\"inputStream is closed\");\n    }\n  }\n\n  private void unhandledException(Throwable t) {\n    LOGGER.error(\"Unhandled exception\", t);\n  }\n\n  @Override\n  public synchronized InputStreamToReadStream exceptionHandler(Handler<Throwable> handler) {\n    check();\n    this.exceptionHandler = handler;\n    return this;\n  }\n\n  @Override\n  public synchronized InputStreamToReadStream handler(Handler<Buffer> handler) {\n    check();\n    this.dataHandler = handler;\n    if (dataHandler != null && !paused && !closed) {\n      doRead();\n    }\n    return this;\n  }\n\n  class ReadResult {\n    int read;\n\n    byte[] bytes = new byte[readBufferSize];\n\n    void doRead() throws IOException {\n      read = inputStream.read(bytes);\n    }\n\n    Buffer toBuffer() {\n      return Buffer.buffer(Arrays.copyOf(bytes, read));\n    }\n  }\n\n  private synchronized void doRead() {\n    if (!readInProgress) {\n      readInProgress = true;\n      Promise<ReadResult> future = Promise.promise();\n      context.executeBlocking(() -> {\n            readInWorker(future);\n            return null;\n          },\n          true);\n      future.future().onComplete(this::afterReadInEventloop);\n    }\n  }\n\n  private synchronized void readInWorker(Promise<ReadResult> future) {\n    try {\n      ReadResult readResult = new ReadResult();\n      readResult.doRead();\n      future.complete(readResult);\n    } catch (Throwable e) {\n      future.fail(e);\n    }\n  }\n\n  public void handleException(Throwable e) {\n    closeInputStream();\n    exceptionHandler.handle(e);\n  }\n\n  private synchronized void afterReadInEventloop(ReadResult readResult, Throwable failure) {\n    if (failure != null) {\n      handleException(failure);\n      return;\n    }\n\n    readInProgress = false;\n    if (readResult.read < 0) {\n      handleEnd();\n      return;\n    }\n\n    handleData(readResult.toBuffer());\n    if (!paused && dataHandler != null) {\n      doRead();\n    }\n  }\n\n  @Override\n  public synchronized InputStreamToReadStream pause() {\n    check();\n    paused = true;\n    return this;\n  }\n\n  @Override\n  public synchronized InputStreamToReadStream resume() {\n    check();\n    if (paused && !closed) {\n      paused = false;\n      if (dataHandler != null) {\n        doRead();\n      }\n    }\n    return this;\n  }\n\n  private synchronized void handleData(Buffer buffer) {\n    if (dataHandler != null) {\n      dataHandler.handle(buffer);\n    }\n  }\n\n  private synchronized void handleEnd() {\n    dataHandler = null;\n    closeInputStream();\n    if (endHandler != null) {\n      endHandler.handle(null);\n    }\n  }\n\n  private void closeInputStream() {\n    if (closed) {\n      return;\n    }\n\n    closed = true;\n    if (!autoCloseInputStream) {\n      return;\n    }\n\n    try {\n      inputStream.close();\n    } catch (IOException e) {\n      LOGGER.error(\"failed to close inputSteam.\", e);\n    }\n  }\n\n  @Override\n  public ReadStream<Buffer> endHandler(Handler<Void> handler) {\n    check();\n    this.endHandler = handler;\n    return this;\n  }\n\n  @Override\n  public ReadStream<Buffer> fetch(long amount) {\n    return this;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/OutputStreamToWriteStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.util.Queue;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ConcurrentLinkedQueue;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.common.io.AsyncCloseable;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.Promise;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.streams.WriteStream;\n\n/**\n * for pump from a readStream\n */\npublic class OutputStreamToWriteStream implements WriteStream<Buffer>, AsyncCloseable<Void> {\n  private static final int DEFAULT_MAX_BUFFERS = 4;\n\n  private static final int SMALLEST_MAX_BUFFERS = 2;\n\n  private final OutputStream outputStream;\n\n  private final Context context;\n\n  private final boolean autoCloseOutputStream;\n\n  private Handler<Throwable> exceptionHandler;\n\n  // resume readStream\n  private Handler<Void> drainHandler;\n\n  // when invoke close, but outputStream not write all data, must put close logic to closedDeferred\n  private Runnable closedDeferred;\n\n  private boolean closed;\n\n  // buffers.size() need to loop all node, and maybe result is not correct in concurrent condition\n  // we just need to flow control by pump, so use another size\n  private final Queue<Buffer> buffers = new ConcurrentLinkedQueue<>();\n\n  private final AtomicInteger currentBufferCount = new AtomicInteger();\n\n  // just indicate if buffers is full, not control add logic\n  // must >= SMALLEST_MAX_BUFFERS\n  // if < SMALLEST_MAX_BUFFERS, then maxBuffers will be SMALLEST_MAX_BUFFERS\n  private int maxBuffers = DEFAULT_MAX_BUFFERS;\n\n  // if currentBufferCount <= drainMark, will invoke drainHandler to resume readStream\n  private int drainMark = maxBuffers / 2;\n\n  public OutputStreamToWriteStream(Context context, OutputStream outputStream,\n      boolean autoCloseOutputStream) {\n    this.context = context;\n    this.outputStream = outputStream;\n    this.autoCloseOutputStream = autoCloseOutputStream;\n  }\n\n  @Override\n  public WriteStream<Buffer> exceptionHandler(Handler<Throwable> handler) {\n    this.exceptionHandler = handler;\n    return this;\n  }\n\n  private void handleException(Throwable t) {\n    if (exceptionHandler != null) {\n      exceptionHandler.handle(t);\n    }\n  }\n\n  @Override\n  public synchronized Future<Void> write(Buffer data) {\n    Promise<Void> result = Promise.<Void>promise();\n    write(data, result);\n    return result.future();\n  }\n\n  private void write(Buffer data, Promise<Void> future) {\n    currentBufferCount.incrementAndGet();\n    buffers.add(data);\n    context.executeBlocking(\n        () -> {\n          writeInWorker(future);\n          return null;\n        },\n        true\n    );\n  }\n\n  protected void writeInWorker(Promise<Void> future) {\n    while (true) {\n      Buffer buffer = buffers.poll();\n      if (buffer == null) {\n        future.complete();\n        return;\n      }\n\n      try {\n        outputStream.write(buffer.getBytes());\n\n        synchronized (OutputStreamToWriteStream.this) {\n          currentBufferCount.decrementAndGet();\n          Runnable action = (currentBufferCount.get() == 0 && closedDeferred != null)\n              ? closedDeferred : this::checkDrained;\n          action.run();\n        }\n      } catch (IOException e) {\n        currentBufferCount.decrementAndGet();\n        future.fail(e);\n        return;\n      }\n    }\n  }\n\n  @Override\n  public Future<Void> end() {\n    return Future.fromCompletionStage(close());\n  }\n\n  @Override\n  public WriteStream<Buffer> setWriteQueueMaxSize(int maxSize) {\n    this.maxBuffers = Math.max(maxSize, SMALLEST_MAX_BUFFERS);\n    this.drainMark = maxBuffers / 2;\n    return this;\n  }\n\n  @Override\n  public synchronized boolean writeQueueFull() {\n    return currentBufferCount.get() >= maxBuffers;\n  }\n\n  @Override\n  public synchronized WriteStream<Buffer> drainHandler(Handler<Void> handler) {\n    this.drainHandler = handler;\n    return this;\n  }\n\n  private synchronized void checkDrained() {\n    if (drainHandler != null && currentBufferCount.get() <= drainMark) {\n      Handler<Void> handler = drainHandler;\n      drainHandler = null;\n      handler.handle(null);\n    }\n  }\n\n  @Override\n  public CompletableFuture<Void> close() {\n    return closeInternal();\n  }\n\n  private void check() {\n    checkClosed();\n  }\n\n  private void checkClosed() {\n    if (closed) {\n      throw new IllegalStateException(this.getClass().getName() + \" is closed\");\n    }\n  }\n\n  private synchronized CompletableFuture<Void> closeInternal() {\n    check();\n\n    closed = true;\n\n    CompletableFuture<Void> future = new CompletableFuture<>();\n    if (currentBufferCount.get() == 0) {\n      doClose(future);\n    } else {\n      closedDeferred = () -> doClose(future);\n    }\n    return future;\n  }\n\n  private void doClose(CompletableFuture<Void> future) {\n    if (autoCloseOutputStream) {\n      try {\n        outputStream.close();\n      } catch (IOException e) {\n        future.completeExceptionally(new IllegalStateException(\"failed to close outputStream.\", e));\n        return;\n      }\n    }\n\n    future.complete(null);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpCommon.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.foundation.common.io.AsyncCloseable;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientResponse;\nimport io.vertx.core.streams.ReadStream;\nimport io.vertx.core.streams.WriteStream;\nimport io.vertx.core.streams.impl.PipeImpl;\n\npublic class PumpCommon {\n  /**\n   * @return future of save action<br>\n   * <p>important:\n   * <p>  if writeStream is AsyncCloseable, future means write complete\n   * <p>  if writeStream is not AsyncCloseable, future only means read complete\n   */\n  @SuppressWarnings(\"unchecked\")\n  public CompletableFuture<Void> pump(ReadStream<Buffer> readStream, WriteStream<Buffer> writeStream,\n      Handler<Throwable> throwableHandler) {\n    CompletableFuture<Void> readFuture = new CompletableFuture<>();\n\n    writeStream.exceptionHandler(e -> {\n      // consumer -> producer\n      // 3rd consumer -> edge -> producer\n      // when download not finished, consumer stop download\n      // producer should stop download logic at once\n      if (readStream instanceof InputStreamToReadStream) {\n        ((InputStreamToReadStream) readStream).handleException(e);\n      } else if (readStream instanceof HttpClientResponse) {\n        // can not find a way to cancel/terminate request\n        // so can only close the connection.\n        ((HttpClientResponse) readStream).request().connection().close();\n      }\n      if (throwableHandler != null) {\n        throwableHandler.handle(e);\n      }\n      readFuture.completeExceptionally(e);\n    });\n    readStream.exceptionHandler(readFuture::completeExceptionally);\n\n    Future<Void> pipeResult = new PipeImpl<>(readStream).endOnComplete(false).to(writeStream);\n\n    pipeResult.onComplete((s) -> readFuture.complete(null),\n        (f) -> {\n          if (throwableHandler != null) {\n            throwableHandler.handle(f);\n          }\n          readFuture.completeExceptionally(f);\n        });\n\n    if (!(writeStream instanceof AsyncCloseable)) {\n      return readFuture;\n    }\n\n    return closeWriteStream((AsyncCloseable<Void>) writeStream, readFuture);\n  }\n\n  protected CompletableFuture<Void> closeWriteStream(AsyncCloseable<Void> writeStream,\n      CompletableFuture<Void> readFuture) {\n    CompletableFuture<Void> writeFuture = new CompletableFuture<>();\n    readFuture.whenComplete((v, e) ->\n        writeStream.close().whenComplete((wv, we) -> {\n          if (we != null) {\n            writeFuture.completeExceptionally(we);\n            return;\n          }\n\n          writeFuture.complete(null);\n        })\n    );\n\n    return CompletableFuture.allOf(readFuture, writeFuture);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpFromPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.concurrent.CompletableFuture;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.foundation.vertx.http.DownloadUtils;\nimport org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Handler;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.streams.ReadStream;\nimport io.vertx.core.streams.WriteStream;\n\npublic class PumpFromPart {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PumpFromPart.class);\n\n  private final Context context;\n\n  private final Part part;\n\n  public PumpFromPart(Context context, Part part) {\n    this.context = context;\n    this.part = part;\n  }\n\n  private CompletableFuture<ReadStream<Buffer>> prepareReadStream() {\n    CompletableFuture<ReadStream<Buffer>> future = new CompletableFuture<>();\n\n    if (ReadStreamPart.class.isInstance(part)) {\n      future.complete(((ReadStreamPart) part).getReadStream());\n      return future;\n    }\n\n    try {\n      InputStream inputStream = part.getInputStream();\n      InputStreamToReadStream inputStreamToReadStream = new InputStreamToReadStream(context, inputStream, true);\n      inputStreamToReadStream.pause();\n      future.complete(inputStreamToReadStream);\n    } catch (IOException e) {\n      future.completeExceptionally(e);\n    }\n\n    return future;\n  }\n\n  public CompletableFuture<Void> toWriteStream(WriteStream<Buffer> writeStream, Handler<Throwable> throwableHandler) {\n    return prepareReadStream()\n        .thenCompose(readStream -> new PumpCommon().pump(readStream, writeStream, throwableHandler))\n        .whenComplete((v, e) -> {\n          if (e != null) {\n            LOGGER.error(\"to write stream failed.\", e);\n          }\n          DownloadUtils.clearPartResource(part);\n          // PumpImpl will add drainHandler to writeStream,\n          // in order to support write multiple files to same writeStream,\n          // need reset after one stream is successful.\n          writeStream.drainHandler(null);\n        });\n  }\n\n  public CompletableFuture<Void> toOutputStream(OutputStream outputStream, boolean autoCloseOutputStream) {\n    if (context == null) {\n      return toOutputStreamSync(outputStream, autoCloseOutputStream);\n    }\n\n    return toOutputStreamAsync(outputStream, autoCloseOutputStream);\n  }\n\n  private CompletableFuture<Void> toOutputStreamAsync(OutputStream outputStream, boolean autoCloseOutputStream) {\n    OutputStreamToWriteStream outputStreamToWriteStream = new OutputStreamToWriteStream(context, outputStream,\n        autoCloseOutputStream);\n    return toWriteStream(outputStreamToWriteStream, null);\n  }\n\n  // DO NOT use a mocked sync context to unify the pump logic\n  // otherwise when pump big stream, will cause stack overflow\n  private CompletableFuture<Void> toOutputStreamSync(OutputStream outputStream, boolean autoCloseOutputStream) {\n    CompletableFuture<Void> future = new CompletableFuture<>();\n    future.whenComplete((v, e) -> DownloadUtils.clearPartResource(part));\n\n    try (InputStream inputStream = part.getInputStream()) {\n      IOUtils.copyLarge(inputStream, outputStream);\n    } catch (Throwable e) {\n      future.completeExceptionally(e);\n    }\n\n    if (autoCloseOutputStream) {\n      try {\n        outputStream.close();\n      } catch (Throwable e) {\n        future.completeExceptionally(e);\n      }\n    }\n\n    future.complete(null);\n    return future;\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.tcp;\n\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentLinkedQueue;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.net.NetSocket;\nimport io.vertx.core.net.impl.NetSocketImpl;\n\npublic class TcpConnection {\n  protected String protocol;\n\n  // 压缩算法名字\n  protected String zipName;\n\n  protected NetSocket netSocket;\n\n  // context of netSocket\n  protected Context context;\n\n  // vertx's wrap for netty is ugly: write always lock first\n  // so we save buf in a CAS queue, and notify eventloop thread to do the real write\n  //\n  // netty:\n  // if write caller is not in network IO thread\n  // always wrap the write as a task, and put it to IO thread queue(MPSC queue)\n  //\n  // so this optimization:\n  // 1.avoid vertx's lock\n  // 2.reduce netty's task schedule\n  private final Queue<Buffer> writeQueue = new ConcurrentLinkedQueue<>();\n\n  private final AtomicLong writeQueueSize = new AtomicLong();\n\n  public String getProtocol() {\n    return protocol;\n  }\n\n  public void setProtocol(String protocol) {\n    this.protocol = protocol;\n  }\n\n  public String getZipName() {\n    return zipName;\n  }\n\n  public void setZipName(String zipName) {\n    this.zipName = zipName;\n  }\n\n  public void setContext(Context context) {\n    this.context = context;\n  }\n\n  public NetSocket getNetSocket() {\n    return netSocket;\n  }\n\n  public void initNetSocket(NetSocketImpl netSocket) {\n    this.netSocket = netSocket;\n\n    this.context = netSocket.context();\n  }\n\n  public void write(Buffer buf) {\n    writeQueue.add(buf);\n    long oldSize = writeQueueSize.getAndIncrement();\n    if (oldSize == 0) {\n      scheduleWrite();\n    }\n  }\n\n  // notify context thread to write\n  protected void scheduleWrite() {\n    context.runOnContext(v -> writeInContext());\n  }\n\n  protected void writeInContext() {\n    for (; ; ) {\n      Buffer buf = writeQueue.poll();\n      if (buf == null) {\n        break;\n      }\n\n      writeQueueSize.decrementAndGet();\n\n      netSocket.write(buf);\n    }\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.tcp;\n\npublic final class TcpConst {\n  private TcpConst() {\n  }\n\n  public static final String LOGIN = \"login\";\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpOutputStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.tcp;\n\nimport org.apache.servicecomb.foundation.vertx.server.TcpParser;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;\n\n/**\n * TcpOutputStream\n *\n *\n */\npublic class TcpOutputStream extends BufferOutputStream {\n  private final long msgId;\n\n  public TcpOutputStream(long msgId) {\n    super();\n\n    this.msgId = msgId;\n    write(TcpParser.TCP_MAGIC);\n    writeLong(msgId);\n  }\n\n  public long getMsgId() {\n    return msgId;\n  }\n\n  public void writeLength(int totalLen, int headerLen) {\n    writeInt(totalLen);\n    writeInt(headerLen);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSharedVertxFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.impl.SysProps;\n\npublic class TestSharedVertxFactory {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n\n  @Test\n  public void getTransportVertx() {\n    Assertions.assertNotNull(SharedVertxFactory.getSharedVertx(environment));\n    Assertions.assertSame(SharedVertxFactory.getSharedVertx(environment),\n        SharedVertxFactory.getSharedVertx(environment));\n\n    SharedVertxFactory.getSharedVertx(environment).close();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSimpleBodyHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.ext.web.impl.RoutingContextInternal;\n\npublic class TestSimpleBodyHandler {\n\n  private SimpleBodyHandler instance;\n\n  private RoutingContextInternal context;\n\n  @Before\n  public void setUp() throws Exception {\n    context = Mockito.mock(RoutingContextInternal.class);\n    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);\n    Mockito.when(context.request()).thenReturn(request);\n    MultiMap multiMap = Mockito.mock(MultiMap.class);\n    Mockito.when(request.headers()).thenReturn(multiMap);\n    HttpServerResponse response = Mockito.mock(HttpServerResponse.class);\n    Mockito.when(response.setStatusCode(Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode())).thenReturn(response);\n    Mockito.when(context.response()).thenReturn(response);\n  }\n\n  @After\n  public void tearDown() throws Exception {\n    instance = null;\n    context = null;\n  }\n\n  @Test\n  public void testValidContentType() {\n    instance = new SimpleBodyHandler() {\n      @Override\n      protected boolean contentTypeSupported(String contentType) {\n        return true;\n      }\n    };\n    instance.handle(context);\n    Assertions.assertTrue(instance.checkContentType(context));\n  }\n\n  @Test\n  public void testInvalidContentType() {\n    instance = new SimpleBodyHandler() {\n      @Override\n      protected boolean contentTypeSupported(String contentType) {\n        return false;\n      }\n    };\n    instance.handle(context);\n    Assertions.assertFalse(instance.checkContentType(context));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSimpleJsonObject.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestSimpleJsonObject {\n  @Test\n  public void testPutObject() {\n    Object value = new Object();\n\n    SimpleJsonObject json = new SimpleJsonObject();\n    json.put(\"k\", value);\n    Assertions.assertSame(value, json.getValue(\"k\"));\n  }\n\n  @Test\n  public void testCopy() {\n    SimpleJsonObject json = new SimpleJsonObject();\n    Assertions.assertSame(json, json.copy());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class TestStream {\n\n  private static final int DIRECT_BUFFER_SIZE = 1024;\n\n  @Test\n  public void testBufferInputStream() {\n    Buffer obuf = Buffer.buffer(DIRECT_BUFFER_SIZE);\n    obuf.appendBytes((\"tests1\").getBytes());\n    @SuppressWarnings(\"resource\")\n    BufferInputStream oBufferInputStream = new BufferInputStream(obuf);\n\n    byte test = oBufferInputStream.readByte();\n    Assertions.assertEquals((byte) 't', test);\n    Assertions.assertEquals((byte) 'e', oBufferInputStream.read());\n\n    Assertions.assertEquals(2, oBufferInputStream.skip(2));\n    Assertions.assertEquals((byte) 's', oBufferInputStream.read());\n    Assertions.assertTrue(oBufferInputStream.readBoolean());\n\n    Assertions.assertEquals(6, oBufferInputStream.getIndex());\n    Assertions.assertEquals(0, oBufferInputStream.available());\n  }\n\n  @Test\n  public void testBufferOutputStream() {\n    @SuppressWarnings({\"resource\"})\n    BufferOutputStream oBufferOutputStream = new BufferOutputStream();\n    oBufferOutputStream.writeString(\"test\");\n    oBufferOutputStream.write(1);\n    oBufferOutputStream.write(true);\n    Assertions.assertTrue((1 < oBufferOutputStream.length()));\n\n    @SuppressWarnings(\"resource\")\n    BufferInputStream oBufferInputStream = new BufferInputStream(oBufferOutputStream.getBuffer());\n    Assertions.assertEquals(\"test\", oBufferInputStream.readString());\n    Assertions.assertEquals(1, oBufferInputStream.readByte());\n    Assertions.assertTrue(oBufferInputStream.readBoolean());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxTLSBuilder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.ssl.SSLOptionFactory;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.http.ClientAuth;\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.HttpServerOptions;\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class TestVertxTLSBuilder {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testBuildHttpServerOptions() {\n    SSLOption option = SSLOption.build(\"rest.provider\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpServerOptions serverOptions = new HttpServerOptions();\n    VertxTLSBuilder.buildNetServerOptions(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertEquals(serverOptions.getClientAuth(), ClientAuth.REQUEST);\n  }\n\n  @Test\n  public void testBuildHttpClientOptions_sslKey_noFactory() {\n    HttpClientOptions clientOptions = new HttpClientOptions();\n    VertxTLSBuilder.buildHttpClientOptions(\"notExist\", clientOptions);\n    Assertions.assertTrue(clientOptions.isSsl());\n  }\n\n  public static class SSLOptionFactoryForTest implements SSLOptionFactory {\n    static SSLOption sslOption = new SSLOption();\n\n    static {\n      sslOption.setEngine(\"openssl\");\n      sslOption.setProtocols(\"\");\n      sslOption.setCiphers(SSLOption.DEFAULT_CIPHERS);\n      sslOption.setCheckCNHost(true);\n    }\n\n    @Override\n    public SSLOption createSSLOption() {\n      return sslOption;\n    }\n  }\n\n  @Test\n  public void testBuildHttpClientOptions_ssl_withFactory() {\n    Mockito.when(environment.getProperty(\"ssl.exist.sslOptionFactory\"))\n        .thenReturn(SSLOptionFactoryForTest.class.getName());\n    HttpClientOptions clientOptions = new HttpClientOptions();\n    VertxTLSBuilder.buildHttpClientOptions(\"exist\", clientOptions);\n    Assertions.assertTrue(clientOptions.isSsl());\n    Assertions.assertTrue(clientOptions.isVerifyHost());\n  }\n\n  @Test\n  public void testBuildHttpClientOptions() {\n    SSLOption option = SSLOption.build(\"rest.consumer\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpClientOptions serverOptions = new HttpClientOptions();\n    VertxTLSBuilder.buildHttpClientOptions(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertTrue(serverOptions.isTrustAll());\n  }\n\n  @Test\n  public void testBuildClientOptionsBase() {\n    SSLOption option = SSLOption.build(\"rest.consumer\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpClientOptions serverOptions = new HttpClientOptions();\n    VertxTLSBuilder.buildClientOptionsBase(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertTrue(serverOptions.isTrustAll());\n  }\n\n  @Test\n  public void testBuildClientOptionsBaseFileNull() {\n    SSLOption option = SSLOption.build(\"rest.consumer\", environment);\n    option.setKeyStore(null);\n    option.setTrustStore(null);\n    option.setCrl(null);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpClientOptions serverOptions = new HttpClientOptions();\n    VertxTLSBuilder.buildClientOptionsBase(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertTrue(serverOptions.isTrustAll());\n  }\n\n  @Test\n  public void testBuildClientOptionsBaseAuthPeerFalse() {\n    SSLOption option = SSLOption.build(\"rest.consumer\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpClientOptions serverOptions = new HttpClientOptions();\n    new MockUp<SSLOption>() {\n\n      @Mock\n      public boolean isAuthPeer() {\n        return false;\n      }\n    };\n    VertxTLSBuilder.buildClientOptionsBase(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertTrue(serverOptions.isTrustAll());\n  }\n\n  @Test\n  public void testBuildClientOptionsBaseSTORE_JKS() {\n    SSLOption option = SSLOption.build(\"rest.consumer\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpClientOptions serverOptions = new HttpClientOptions();\n    new MockUp<SSLOption>() {\n\n      @Mock\n      public String getKeyStoreType() {\n        return \"JKS\";\n      }\n    };\n    VertxTLSBuilder.buildClientOptionsBase(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertTrue(serverOptions.isTrustAll());\n  }\n\n  @Test\n  public void testBuildClientOptionsBaseSTORE_PKCS12() {\n    SSLOption option = SSLOption.build(\"rest.consumer\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpClientOptions serverOptions = new HttpClientOptions();\n    new MockUp<SSLOption>() {\n\n      @Mock\n      public String getTrustStoreType() {\n        return \"PKCS12\";\n      }\n    };\n    VertxTLSBuilder.buildClientOptionsBase(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertTrue(serverOptions.isTrustAll());\n  }\n\n  @Test\n  public void testBuildHttpServerOptionsRequest() {\n    SSLOption option = SSLOption.build(\"rest.provider\", environment);\n    SSLCustom custom = SSLCustom.createSSLCustom(option.getSslCustomClass());\n    HttpServerOptions serverOptions = new HttpServerOptions();\n\n    new MockUp<SSLOption>() {\n\n      @Mock\n      public boolean isAuthPeer() {\n        return false;\n      }\n    };\n    VertxTLSBuilder.buildNetServerOptions(option, custom, serverOptions);\n    Assertions.assertEquals(serverOptions.getEnabledSecureTransportProtocols().toArray().length, 1);\n    Assertions.assertEquals(serverOptions.getClientAuth(), ClientAuth.REQUEST);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.concurrent.CountDownLatch;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.netty.buffer.ByteBuf;\nimport io.netty.buffer.Unpooled;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.impl.SysProps;\n\npublic class TestVertxUtils {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testGetOrCreateVertx() throws InterruptedException {\n    Vertx vertx = VertxUtils.getOrCreateVertxByName(\"ut\", null, null);\n\n    Holder<String> name = new Holder<>();\n    CountDownLatch latch = new CountDownLatch(1);\n    vertx.runOnContext(v -> {\n      name.value = Thread.currentThread().getName();\n      latch.countDown();\n    });\n    latch.await();\n\n    Assertions.assertEquals(name.value, \"ut-vert.x-eventloop-thread-0\");\n    VertxUtils.blockCloseVertxByName(\"ut\");\n  }\n\n  @Test\n  public void testCreateVertxWithFileCPResolving() {\n    // create .vertx folder\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(false);\n    deleteCacheFile();\n    VertxUtils.getOrCreateVertxByName(\"testCreateVertxWithFileCPResolvingFalse\", null, null);\n    Assertions.assertTrue(isCacheFileExists());\n    VertxUtils.blockCloseVertxByName(\"testCreateVertxWithFileCPResolvingFalse\");\n\n    // don't create .vertx folder\n    deleteCacheFile();\n    Assertions.assertFalse(isCacheFileExists());\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    VertxUtils.getOrCreateVertxByName(\"testCreateVertxWithFileCPResolvingTrue\", null, null);\n    Assertions.assertFalse(isCacheFileExists());\n    VertxUtils.blockCloseVertxByName(\"testCreateVertxWithFileCPResolvingTrue\");\n  }\n\n  private void deleteCacheFile() {\n    String cacheDirBase = System.getProperty(SysProps.FILE_CACHE_DIR.name,\n        System.getProperty(\"java.io.tmpdir\", \".\"));\n    File folder = new File(cacheDirBase);\n    File[] files = folder.listFiles();\n    for (File f : files) {\n      if (f.getName().startsWith(\"vertx-cache\")) {\n        FileUtils.deleteQuietly(f);\n      }\n    }\n  }\n\n  private boolean isCacheFileExists() {\n    String cacheDirBase = System.getProperty(SysProps.FILE_CACHE_DIR.name,\n        System.getProperty(\"java.io.tmpdir\", \".\"));\n    File folder = new File(cacheDirBase);\n    File[] files = folder.listFiles();\n    for (File f : files) {\n      if (f.getName().startsWith(\"vertx-cache\")) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  @Test\n  public void testVertxUtilsInitNullOptions() {\n    Vertx vertx = VertxUtils.init(null, null, null);\n    Assertions.assertNotEquals(null, vertx);\n    VertxUtils.blockCloseVertx(vertx);\n  }\n\n  @Test\n  public void testVertxUtilsInitWithOptions() {\n    VertxOptions oOptions = new VertxOptions();\n\n    Vertx vertx = VertxUtils.init(null, oOptions, null);\n    Assertions.assertNotEquals(null, vertx);\n    VertxUtils.blockCloseVertx(vertx);\n  }\n\n  @Test\n  public void testgetBytesFastBufferInputStream() throws IOException {\n    byte[] bytes = new byte[] {1};\n    Buffer byteBuf = Buffer.buffer(bytes);\n\n    try (BufferInputStream inputStream = new BufferInputStream(byteBuf)) {\n      byte[] result = VertxUtils.getBytesFast(inputStream);\n      Assertions.assertEquals(bytes.length, result.length);\n      Assertions.assertEquals(bytes[0], result[0]);\n    }\n  }\n\n  @Test\n  public void testgetBytesFastNormalInputStream() throws IOException {\n    byte[] bytes = new byte[] {1};\n\n    try (InputStream inputStream = new ByteArrayInputStream(bytes)) {\n      byte[] result = VertxUtils.getBytesFast(inputStream);\n      Assertions.assertEquals(1, result[0]);\n    }\n  }\n\n  @Test\n  public void testgetBytesFastBuffer() {\n    Buffer buffer = Buffer.buffer();\n    buffer.appendByte((byte) 1);\n\n    byte[] result = VertxUtils.getBytesFast(buffer);\n    Assertions.assertEquals(1, result[0]);\n  }\n\n  @Test\n  public void testgetBytesFastByteBufHasArray() {\n    byte[] bytes = new byte[] {1};\n    ByteBuf byteBuf = Unpooled.wrappedBuffer(bytes);\n\n    byte[] result = VertxUtils.getBytesFast(byteBuf);\n    Assertions.assertSame(bytes, result);\n  }\n\n  @Test\n  public void testgetBytesFastByteBufCopy() {\n    ByteBuf byteBuf = Unpooled.directBuffer();\n    byteBuf.writeByte(1);\n    Assertions.assertFalse(byteBuf.hasArray());\n\n    byte[] result = VertxUtils.getBytesFast(byteBuf);\n    Assertions.assertEquals(1, result[0]);\n\n    byteBuf.release();\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/TestClientPoolManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.impl.VertxImpl;\nimport mockit.Deencapsulation;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestClientPoolManager {\n  @Mocked\n  Vertx vertx;\n\n  @Mocked\n  ClientPoolFactory<HttpClientWithContext> factory;\n\n  ClientPoolManager<HttpClientWithContext> poolMgr;\n\n  String id;\n\n  List<HttpClientWithContext> pools;\n\n  Map<Object, Object> contextMap = new HashMap<>();\n\n  @Mocked\n  Context context;\n\n  @Before\n  public void setup() {\n    poolMgr = new ClientPoolManager<>(vertx, factory);\n    id = Deencapsulation.getField(poolMgr, \"id\");\n    pools = Deencapsulation.getField(poolMgr, \"pools\");\n    new MockUp<Context>(context) {\n      @Mock\n      void put(Object key, Object value) {\n        contextMap.put(key, value);\n      }\n\n      @SuppressWarnings(\"unchecked\")\n      @Mock\n      <T> T get(Object key) {\n        return (T) contextMap.get(key);\n      }\n\n      @Mock\n      Vertx owner() {\n        return vertx;\n      }\n\n      @Mock\n      boolean isEventLoopContext() {\n        return true;\n      }\n    };\n  }\n\n  @Test\n  public void createClientPool(@Mocked HttpClientWithContext pool) {\n    new Expectations(VertxImpl.class) {\n      {\n        factory.createClientPool(context);\n        result = pool;\n      }\n    };\n\n    Assertions.assertSame(pool, poolMgr.createClientPool(context));\n    Assertions.assertSame(pool, context.get(id));\n    MatcherAssert.assertThat(pools, Matchers.contains(pool));\n  }\n\n  @Test\n  public void findClientPool_sync(@Mocked HttpClientWithContext pool1, @Mocked HttpClientWithContext pool2) {\n    new Expectations(poolMgr) {\n      {\n        poolMgr.findThreadBindClientPool();\n        result = pool1;\n        poolMgr.findByContext(null);\n        result = pool2;\n      }\n    };\n\n    Assertions.assertSame(pool1, poolMgr.findClientPool(true));\n    Assertions.assertSame(pool2, poolMgr.findClientPool(false));\n  }\n\n  @Test\n  public void findThreadBindClientPool(@Mocked HttpClientWithContext pool1, @Mocked HttpClientWithContext pool2) {\n    pools.add(pool1);\n    pools.add(pool2);\n\n    new MockUp<Thread>() {\n      @Mock\n      long getId() {\n        return 0;\n      }\n    };\n\n    Assertions.assertSame(pool1, poolMgr.findThreadBindClientPool());\n    // find again, get the same result\n    Assertions.assertSame(pool1, poolMgr.findThreadBindClientPool());\n\n    new MockUp<Thread>() {\n      @Mock\n      long getId() {\n        return 1;\n      }\n    };\n\n    Assertions.assertSame(pool2, poolMgr.findThreadBindClientPool());\n    // find again, get the same result\n    Assertions.assertSame(pool2, poolMgr.findThreadBindClientPool());\n  }\n\n  @Test\n  public void findByContext_reactive() {\n    HttpClientWithContext notMatchPool1 = new HttpClientWithContext(null, null);\n    HttpClientWithContext notMatchPool2 = new HttpClientWithContext(null, null);\n    pools.add(notMatchPool1);\n    pools.add(notMatchPool2);\n\n    new Expectations() {\n      {\n        Vertx.currentContext();\n        result = context;\n      }\n    };\n    context.put(id, notMatchPool2);\n\n    Assertions.assertSame(notMatchPool2, poolMgr.findByContext());\n    // find again, get the same result\n    Assertions.assertSame(notMatchPool2, poolMgr.findByContext());\n  }\n\n  @Test\n  public void findByContext_wrongContext_reverse() {\n    HttpClientWithContext pool1 = new HttpClientWithContext(null, null);\n    HttpClientWithContext pool2 = new HttpClientWithContext(null, null);\n    pools.add(pool1);\n    pools.add(pool2);\n\n    new Expectations() {\n      {\n        Vertx.currentContext();\n        result = null;\n      }\n    };\n\n    AtomicInteger reactiveNextIndex = Deencapsulation.getField(poolMgr, \"reactiveNextIndex\");\n    reactiveNextIndex.set(Integer.MAX_VALUE);\n    // each time invoke find, reactiveNextIndex will inc 1\n    Assertions.assertSame(pool2, poolMgr.findByContext());\n    Assertions.assertSame(pool1, poolMgr.findByContext());\n    Assertions.assertSame(pool2, poolMgr.findByContext());\n    Assertions.assertSame(pool1, poolMgr.findByContext());\n  }\n\n  @Test\n  public void findByContext_normalThread() {\n    HttpClientWithContext pool = new HttpClientWithContext(null, null);\n    pools.add(pool);\n\n    new Expectations() {\n      {\n        Vertx.currentContext();\n        result = null;\n      }\n    };\n\n    Assertions.assertSame(pool, poolMgr.findByContext());\n  }\n\n  @Test\n  public void findByContext_otherVertx(@Mocked VertxImpl otherVertx, @Mocked Context otherContext) {\n    HttpClientWithContext pool = new HttpClientWithContext(null, null);\n    pools.add(pool);\n\n    new Expectations() {\n      {\n        Vertx.currentContext();\n        result = otherContext;\n        otherContext.owner();\n        result = otherVertx;\n      }\n    };\n\n    Assertions.assertSame(pool, poolMgr.findByContext());\n  }\n\n  @Test\n  public void findByContext_worker(@Mocked Context workerContext) {\n    HttpClientWithContext pool = new HttpClientWithContext(null, null);\n    pools.add(pool);\n\n    new Expectations() {\n      {\n        Vertx.currentContext();\n        result = workerContext;\n        workerContext.owner();\n        result = vertx;\n        workerContext.isEventLoopContext();\n        result = false;\n      }\n    };\n\n    Assertions.assertSame(pool, poolMgr.findByContext());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/TestClientVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.vertx.SimpleJsonObject;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;\nimport org.junit.Test;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.json.JsonObject;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestClientVerticle {\n  ClientVerticle<HttpClientWithContext> clientVerticle = new ClientVerticle<>();\n\n  @Test\n  public void start(@Mocked Context context) throws Exception {\n    AtomicInteger count = new AtomicInteger();\n    ClientPoolManager<HttpClientWithContext> clientMgr = new MockUp<ClientPoolManager<HttpClientWithContext>>() {\n      @Mock\n      HttpClientWithContext createClientPool(Context context) {\n        count.incrementAndGet();\n        return null;\n      }\n    }.getMockInstance();\n    clientVerticle.init(null, context);\n\n    JsonObject config = new SimpleJsonObject();\n    config.put(ClientVerticle.CLIENT_MGR, clientMgr);\n    new Expectations() {\n      {\n        context.config();\n        result = config;\n      }\n    };\n\n    clientVerticle.start();\n\n    Assertions.assertEquals(1, count.get());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestAbstractTcpClientPoolFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport org.junit.jupiter.api.Assertions;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestAbstractTcpClientPoolFactory {\n  private final TcpClientConfig normalClientConfig = new TcpClientConfig();\n\n  private final TcpClientConfig sslClientConfig = new TcpClientConfig();\n\n  TcpClientPoolFactory factory = new TcpClientPoolFactory(normalClientConfig, sslClientConfig);\n\n  @Test\n  public void createClientPool() {\n    Vertx vertx = Mockito.mock(Vertx.class);\n    Context context = Mockito.mock(Context.class);\n    Mockito.when(context.owner()).thenReturn(vertx);\n    TcpClientConnectionPool pool = factory.createClientPool(context);\n\n    Assertions.assertSame(normalClientConfig, pool.netClientWrapper.getClientConfig(false));\n    Assertions.assertSame(sslClientConfig, pool.netClientWrapper.getClientConfig(true));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestTcpClientConfig {\n  @Test\n  public void testTcpClientConfig() {\n    TcpClientConfig config = new TcpClientConfig();\n    Assertions.assertEquals(config.getMsLoginTimeout(), 30000);\n    Assertions.assertFalse(config.isSsl());\n    config.setMsLoginTimeout(500);\n    Assertions.assertEquals(config.getMsLoginTimeout(), 500);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.client.tcp;\n\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConnection.Status;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.netty.buffer.ByteBuf;\nimport io.vertx.core.Context;\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.Promise;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.net.NetSocket;\nimport io.vertx.core.net.impl.NetSocketImpl;\nimport mockit.Deencapsulation;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestTcpClientConnection {\n  @Mocked\n  Context context;\n\n  @Mocked\n  NetClientWrapper netClientWrapper;\n\n  String strEndpoint = \"rest://localhost:8080\";\n\n  TcpClientConnection tcpClientConnection;\n\n  Map<Long, TcpRequest> requestMap;\n\n  Queue<ByteBuf> writeQueue;\n\n  Queue<AbstractTcpClientPackage> packageQueue;\n\n  @Before\n  public void setup() {\n    tcpClientConnection = new TcpClientConnection(context, netClientWrapper, strEndpoint);\n    requestMap = Deencapsulation.getField(tcpClientConnection, \"requestMap\");\n    packageQueue = Deencapsulation.getField(tcpClientConnection, \"packageQueue\");\n    writeQueue = Deencapsulation.getField(tcpClientConnection, \"writeQueue\");\n  }\n\n  @Test\n  public void localSupportLogin() {\n    Assertions.assertFalse(tcpClientConnection.isLocalSupportLogin());\n\n    tcpClientConnection.setLocalSupportLogin(true);\n    Assertions.assertTrue(tcpClientConnection.isLocalSupportLogin());\n  }\n\n  @Test\n  public void createLogin() {\n    Assertions.assertNull(tcpClientConnection.createLogin());\n  }\n\n  @Test\n  public void onLoginResponse_buffer() {\n    Assertions.assertTrue(tcpClientConnection.onLoginResponse(null));\n  }\n\n  @Test\n  public void send_inWorkingStatus(@Mocked AbstractTcpClientPackage tcpClientPackage,\n      @Mocked TcpOutputStream tcpOutputStream) {\n    Deencapsulation.setField(tcpClientConnection, \"status\", Status.WORKING);\n\n    long msgId = 1;\n    Buffer byteBuf = Buffer.buffer();\n    new Expectations(tcpClientConnection) {\n      {\n        tcpClientPackage.getMsgId();\n        result = msgId;\n        tcpClientPackage.createStream();\n        result = tcpOutputStream;\n        tcpOutputStream.getBuffer();\n        result = byteBuf;\n      }\n    };\n\n    new MockUp<Context>(context) {\n      @Mock\n      void runOnContext(Handler<Void> action) {\n      }\n    };\n    tcpClientConnection.send(tcpClientPackage, ar -> {\n    });\n\n    Assertions.assertSame(byteBuf, writeQueue.poll());\n    Assertions.assertNull(writeQueue.poll());\n    Assertions.assertEquals(Status.WORKING, Deencapsulation.getField(tcpClientConnection, \"status\"));\n  }\n\n  @Test\n  public void send_inDisconnectedStatus(@Mocked AbstractTcpClientPackage tcpClientPackage,\n      @Mocked TcpOutputStream tcpOutputStream) {\n    long msgId = 1;\n    new Expectations(tcpClientConnection) {\n      {\n        tcpClientPackage.getMsgId();\n        result = msgId;\n      }\n    };\n    new MockUp<Context>(context) {\n      @Mock\n      void runOnContext(Handler<Void> action) {\n        action.handle(null);\n      }\n    };\n    tcpClientConnection.send(tcpClientPackage, ar -> {\n    });\n\n    Assertions.assertSame(tcpClientPackage, packageQueue.poll());\n    Assertions.assertNull(packageQueue.poll());\n    Assertions.assertEquals(Status.CONNECTING, Deencapsulation.getField(tcpClientConnection, \"status\"));\n  }\n\n  @Test\n  public void send_disconnectedToTryLogin(@Mocked AbstractTcpClientPackage tcpClientPackage,\n      @Mocked TcpOutputStream tcpOutputStream) {\n    long msgId = 1;\n    new Expectations(tcpClientConnection) {\n      {\n        tcpClientPackage.getMsgId();\n        result = msgId;\n      }\n    };\n    new MockUp<Context>(context) {\n      @Mock\n      void runOnContext(Handler<Void> action) {\n        Deencapsulation.setField(tcpClientConnection, \"status\", Status.TRY_LOGIN);\n        action.handle(null);\n      }\n    };\n    tcpClientConnection.send(tcpClientPackage, ar -> {\n    });\n\n    Assertions.assertSame(tcpClientPackage, packageQueue.poll());\n    Assertions.assertNull(packageQueue.poll());\n    Assertions.assertEquals(Status.TRY_LOGIN, Deencapsulation.getField(tcpClientConnection, \"status\"));\n  }\n\n  @Test\n  public void send_disconnectedToWorking(@Mocked AbstractTcpClientPackage tcpClientPackage,\n      @Mocked TcpOutputStream tcpOutputStream) {\n    long msgId = 1;\n    new Expectations(tcpClientConnection) {\n      {\n        tcpClientPackage.getMsgId();\n        result = msgId;\n        tcpClientConnection.write((Buffer) any);\n      }\n    };\n    new MockUp<Context>(context) {\n      @Mock\n      void runOnContext(Handler<Void> action) {\n        Deencapsulation.setField(tcpClientConnection, \"status\", Status.WORKING);\n        action.handle(null);\n      }\n    };\n    tcpClientConnection.send(tcpClientPackage, ar -> {\n    });\n\n    Assertions.assertNull(writeQueue.poll());\n    Assertions.assertNull(packageQueue.poll());\n    Assertions.assertEquals(Status.WORKING, Deencapsulation.getField(tcpClientConnection, \"status\"));\n  }\n\n  @Test\n  public void connect_success(@Mocked NetSocketImpl netSocket) {\n    Promise<NetSocket> promise = Promise.promise();\n    new MockUp<NetClientWrapper>(netClientWrapper) {\n      @Mock\n      public Future<NetSocket> connect(boolean ssl, int port, String host) {\n        promise.complete(netSocket);\n        return promise.future();\n      }\n    };\n\n    tcpClientConnection.connect();\n\n    Assertions.assertSame(netSocket, tcpClientConnection.getNetSocket());\n    Assertions.assertEquals(Status.WORKING, Deencapsulation.getField(tcpClientConnection, \"status\"));\n  }\n\n  @Test\n  public void connect_failed() {\n    requestMap.put(10L, new TcpRequest(10, ar -> {\n    }));\n\n    Promise<NetSocket> promise = Promise.promise();\n    RuntimeException error = new RuntimeExceptionWithoutStackTrace();\n    new MockUp<NetClientWrapper>(netClientWrapper) {\n      @Mock\n      public Future<NetSocket> connect(boolean ssl, int port, String host) {\n        promise.fail(error);\n        return promise.future();\n      }\n    };\n\n    tcpClientConnection.connect();\n\n    Assertions.assertEquals(Status.DISCONNECTED, Deencapsulation.getField(tcpClientConnection, \"status\"));\n    Assertions.assertEquals(0, requestMap.size());\n  }\n\n  @Test\n  public void onClosed(@Mocked NetSocketImpl netSocket) {\n    requestMap.put(10L, new TcpRequest(10, ar -> {\n    }));\n    tcpClientConnection.initNetSocket(netSocket);\n\n    tcpClientConnection.onClosed(null);\n    Assertions.assertEquals(Status.DISCONNECTED, Deencapsulation.getField(tcpClientConnection, \"status\"));\n    Assertions.assertEquals(0, requestMap.size());\n  }\n\n  @Test\n  public void onReply_notExist() {\n    // should not throw exception\n    tcpClientConnection.onReply(1, null, null);\n  }\n\n  @Test\n  public void on_exist() {\n    long msgId = 1L;\n    AtomicInteger count = new AtomicInteger();\n    requestMap.put(msgId, new TcpRequest(10, ar -> count.incrementAndGet()));\n\n    tcpClientConnection.onReply(msgId, null, null);\n    Assertions.assertEquals(1, count.get());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestAbstractHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.util.Collections;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\npublic class TestAbstractHttpServletRequest {\n  HttpServletRequest request = new AbstractHttpServletRequest() {\n  };\n\n  @Test\n  public void testAttribute() {\n    String key = \"a1\";\n    String value = \"abc\";\n    request.setAttribute(key, value);\n    Assertions.assertSame(value, request.getAttribute(key));\n    MatcherAssert.assertThat(Collections.list(request.getAttributeNames()), Matchers.contains(key));\n\n    request.setAttribute(\"a2\", \"v\");\n    MatcherAssert.assertThat(Collections.list(request.getAttributeNames()), Matchers.containsInAnyOrder(key, \"a2\"));\n\n    request.removeAttribute(key);\n    Assertions.assertNull(request.getAttribute(key));\n  }\n\n  private void checkError(Error error) {\n    Assertions.assertEquals(\"not supported method\", error.getMessage());\n  }\n\n  @Test\n  public void testGetCharacterEncoding() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getCharacterEncoding());\n    checkError(error);\n  }\n\n  @Test\n  public void testSetCharacterEncoding() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.setCharacterEncoding(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetContentLength() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getContentLength());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetContentLengthLong() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getContentLengthLong());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetContentType() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getContentType());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetInputStream() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getInputStream());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetParameter() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getParameter(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetParameterNames() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getParameterNames());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetParameterValues() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getParameterValues(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetParameterMap() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getParameterMap());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetProtocol() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getProtocol());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetScheme() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getScheme());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetServerName() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getServerName());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetServerPort() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getServerPort());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetReader() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getReader());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRemoteAddr() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRemoteAddr());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRemoteHost() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRemoteHost());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetLocale() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getLocale());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetLocales() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getLocales());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsSecure() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isSecure());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRequestDispatcher() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRequestDispatcher(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRemotePort() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRemotePort());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetLocalName() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getLocalName());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetLocalAddr() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getLocalAddr());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetLocalPort() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getLocalPort());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetServletContext() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getServletContext());\n    checkError(error);\n  }\n\n  @Test\n  public void testStartAsync() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.startAsync());\n    checkError(error);\n  }\n\n  @Test\n  public void testStartAsyncWithParam() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.startAsync(null, null));\n    checkError(error);\n  }\n\n  @Test\n  public void testIsAsyncStarted() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isAsyncStarted());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsAsyncSupported() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isAsyncSupported());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetAsyncContext() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getAsyncContext());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetDispatcherType() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getDispatcherType());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetAuthType() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getAuthType());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetCookies() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getCookies());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetDateHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getDateHeader(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getHeader(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetHeaders() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getHeaders(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetHeaderNames() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getHeaderNames());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetIntHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getIntHeader(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetMethod() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getMethod());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetPathInfo() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getPathInfo());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetPathTranslated() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getPathTranslated());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetContextPath() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getContextPath());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetQueryString() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getQueryString());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRemoteUser() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRemoteUser());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsUserInRole() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isUserInRole(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetUserPrincipal() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getUserPrincipal());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRequestedSessionId() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRequestedSessionId());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRequestURI() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRequestURI());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetRequestURL() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getRequestURL());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetServletPath() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getServletPath());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetSessionWithParam() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getSession(true));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetSession() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getSession());\n    checkError(error);\n  }\n\n  @Test\n  public void testChangeSessionId() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.changeSessionId());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsRequestedSessionIdValid() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isRequestedSessionIdValid());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsRequestedSessionIdFromCookie() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isRequestedSessionIdFromCookie());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsRequestedSessionIdFromURL() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.isRequestedSessionIdFromURL());\n    checkError(error);\n  }\n\n  @Test\n  public void testAuthenticate() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.authenticate(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testLogin() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.login(null, null));\n    checkError(error);\n  }\n\n  @Test\n  public void testLogout() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.logout());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetParts() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getParts());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetPart() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.getPart(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testUpgrade() {\n    Error error = Assertions.assertThrows(Error.class, () -> request.upgrade(null));\n    checkError(error);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestAbstractHttpServletResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestAbstractHttpServletResponse {\n\n  HttpServletResponseEx response = new AbstractHttpServletResponse() {\n  };\n\n  private void checkError(Error error) {\n    Assertions.assertEquals(\"not supported method\", error.getMessage());\n  }\n\n  @Test\n  public void testGetCharacterEncoding() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getCharacterEncoding());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetContentType() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getContentType());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetOutputStream() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getOutputStream());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetWriter() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getWriter());\n    checkError(error);\n  }\n\n  @Test\n  public void testSetCharacterEncoding() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setCharacterEncoding(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetContentLength() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setContentLength(0));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetContentLengthLong() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setContentLengthLong(0));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetContentType() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setContentType(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetBufferSize() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setBufferSize(0));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetBufferSize() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getBufferSize());\n    checkError(error);\n  }\n\n  @Test\n  public void testFlushBuffer() {\n    Assertions.assertDoesNotThrow(() -> response.flushBuffer());\n  }\n\n  @Test\n  public void testResetBuffer() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.resetBuffer());\n    checkError(error);\n  }\n\n  @Test\n  public void testIsCommitted() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.isCommitted());\n    checkError(error);\n  }\n\n  @Test\n  public void testReset() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.reset());\n    checkError(error);\n  }\n\n  @Test\n  public void testSetLocale() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setLocale(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetLocale() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getLocale());\n    checkError(error);\n  }\n\n  @Test\n  public void testAddCookie() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.addCookie(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testContainsHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.containsHeader(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testEncodeURL() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.encodeURL(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testEncodeRedirectURL() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.encodeRedirectURL(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testSendErrorScAndMsg() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.sendError(0, null));\n    checkError(error);\n  }\n\n  @Test\n  public void testSendErrorSc() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.sendError(0));\n    checkError(error);\n  }\n\n  @Test\n  public void testSendRedirect() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.sendRedirect(null));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetDateHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setDateHeader(null, 0));\n    checkError(error);\n  }\n\n  @Test\n  public void testAddDateHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.addDateHeader(null, 0));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setHeader(null, null));\n    checkError(error);\n  }\n\n  @Test\n  public void testAddHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.addHeader(null, null));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetIntHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setIntHeader(null, 0));\n    checkError(error);\n  }\n\n  @Test\n  public void testAddIntHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.addIntHeader(null, 0));\n    checkError(error);\n  }\n\n  @Test\n  public void testSetStatusSc() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.setStatus(0));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetStatus() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getStatus());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetHeader() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getHeader(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetHeaders() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getHeaders(\"\"));\n    checkError(error);\n  }\n\n  @Test\n  public void testGetHeaderNames() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getHeaderNames());\n    checkError(error);\n  }\n\n  @Test\n  public void testGetStatusType() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.getStatusType());\n    checkError(error);\n  }\n\n  @Test\n  public void attribute() {\n    response.setAttribute(\"k\", \"v\");\n    Assertions.assertEquals(\"v\", response.getAttribute(\"k\"));\n  }\n\n  @Test\n  public void sendPart() {\n    Error error = Assertions.assertThrows(Error.class, () -> response.sendPart(null));\n    checkError(error);\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestBodyBufferSupportImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport io.vertx.core.buffer.Buffer;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestBodyBufferSupportImpl {\n  BodyBufferSupportImpl impl = new BodyBufferSupportImpl();\n\n  @Test\n  public void testSetBodyBuffer() {\n    impl.setBodyBytes(new byte[] {});\n    impl.setBodyLength(10);\n\n    Assertions.assertNotNull(impl.getBodyBytes());\n    Assertions.assertEquals(10, impl.getBodyBytesLength());\n\n    impl.setBodyBuffer(null);\n\n    Assertions.assertNull(impl.getBodyBytes());\n    Assertions.assertEquals(0, impl.getBodyBytesLength());\n  }\n\n  @Test\n  public void testGetBodyBuffer() {\n    Assertions.assertNull(impl.getBodyBuffer());\n\n    Buffer bodyBuffer = Buffer.buffer();\n    impl.setBodyBuffer(bodyBuffer);\n\n    Assertions.assertSame(bodyBuffer, impl.getBodyBuffer());\n  }\n\n  @Test\n  public void testGetBodyBytes() {\n    Assertions.assertNull(impl.getBodyBytes());\n\n    byte[] bytes = new byte[] {1, 2, 3};\n    Buffer bodyBuffer = Buffer.buffer(bytes);\n    impl.setBodyBuffer(bodyBuffer);\n\n    Assertions.assertArrayEquals(bytes, impl.getBodyBytes());\n  }\n\n  @Test\n  public void testGetBodyBytesLength() {\n    Assertions.assertEquals(0, impl.getBodyBytesLength());\n\n    byte[] bytes = new byte[] {1, 2, 3};\n    Buffer bodyBuffer = Buffer.buffer(bytes);\n    impl.setBodyBuffer(bodyBuffer);\n\n    Assertions.assertEquals(3, impl.getBodyBytesLength());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestFileUploadPart.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.foundation.vertx.http;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.Files;\r\nimport java.util.UUID;\r\n\r\nimport org.apache.commons.io.FileUtils;\r\nimport org.apache.commons.io.IOUtils;\r\n\r\nimport io.vertx.ext.web.FileUpload;\r\nimport org.junit.jupiter.api.AfterEach;\r\nimport org.junit.jupiter.api.Assertions;\r\nimport org.junit.jupiter.api.BeforeAll;\r\nimport org.junit.jupiter.api.BeforeEach;\r\nimport org.junit.jupiter.api.Test;\r\nimport org.mockito.Mockito;\r\n\r\npublic class TestFileUploadPart {\r\n\r\n  FileUpload fileUpload;\r\n\r\n  FileUploadPart part;\r\n\r\n  static File file;\r\n\r\n  static String content = \"fileContent\";\r\n\r\n  @BeforeAll\r\n  public static void classSetup() throws IOException {\r\n    file = Files.createTempFile(\"upload\", \".txt\").toFile();\r\n    file.deleteOnExit();\r\n    FileUtils.writeStringToFile(file, content, StandardCharsets.UTF_8, false);\r\n  }\r\n\r\n  @BeforeEach\r\n  public void setup() {\r\n    fileUpload = Mockito.mock(FileUpload.class);\r\n    part = new FileUploadPart(fileUpload);\r\n  }\r\n\r\n  @AfterEach\r\n  public void after() {\r\n    Mockito.reset(fileUpload);\r\n  }\r\n\r\n  @Test\r\n  public void getInputStream() throws IOException {\r\n    Mockito.when(fileUpload.uploadedFileName()).thenReturn(file.getAbsolutePath());\r\n    try (InputStream is = part.getInputStream()) {\r\n      Assertions.assertEquals(content, IOUtils.toString(is, StandardCharsets.UTF_8));\r\n    }\r\n  }\r\n\r\n  @Test\r\n  public void getContentType() {\r\n    String contentType = \"type\";\r\n    Mockito.when(fileUpload.contentType()).thenReturn(contentType);\r\n\r\n    Assertions.assertEquals(contentType, part.getContentType());\r\n  }\r\n\r\n  @Test\r\n  public void getName() {\r\n    String name = \"pName\";\r\n    Mockito.when(fileUpload.name()).thenReturn(name);\r\n\r\n    Assertions.assertEquals(name, part.getName());\r\n  }\r\n\r\n  @Test\r\n  public void getSubmittedFileName() {\r\n    String clientName = \"clientName\";\r\n    Mockito.when(fileUpload.fileName()).thenReturn(clientName);\r\n\r\n    Assertions.assertEquals(clientName, part.getSubmittedFileName());\r\n  }\r\n\r\n  @Test\r\n  public void getSize() {\r\n    long fileSize = 10;\r\n    Mockito.when(fileUpload.size()).thenReturn(fileSize);\r\n\r\n    Assertions.assertEquals(fileSize, part.getSize());\r\n  }\r\n\r\n  @Test\r\n  public void write() throws IOException {\r\n    Mockito.when(fileUpload.uploadedFileName()).thenReturn(file.getAbsolutePath());\r\n\r\n    File targetFile = new File(UUID.randomUUID().toString());\r\n    targetFile.deleteOnExit();\r\n    part.write(targetFile.getAbsolutePath());\r\n    Assertions.assertEquals(content, FileUtils.readFileToString(targetFile, StandardCharsets.UTF_8));\r\n  }\r\n}\r\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestStandardHttpServletRequestEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\nimport jakarta.servlet.ServletInputStream;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.ws.rs.HttpMethod;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport io.vertx.core.buffer.Buffer;\nimport mockit.Deencapsulation;\nimport mockit.Expectations;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestStandardHttpServletRequestEx {\n  @Mocked\n  HttpServletRequest request;\n\n  StandardHttpServletRequestEx requestEx;\n\n  @Before\n  public void setup() {\n    requestEx = new StandardHttpServletRequestEx(request);\n  }\n\n  @Test\n  public void setBodyBuffer() {\n    Buffer bodyBuffer = Buffer.buffer();\n    bodyBuffer.appendString(\"abc\");\n\n    requestEx.setBodyBuffer(bodyBuffer);\n    Assertions.assertSame(bodyBuffer, requestEx.getBodyBuffer());\n    Assertions.assertArrayEquals(\"abc\".getBytes(), Arrays.copyOf(requestEx.getBodyBytes(), requestEx.getBodyBytesLength()));\n  }\n\n  @Test\n  public void getInputStreamNotCache() throws IOException {\n    ServletInputStream inputStream = request.getInputStream();\n\n    Assertions.assertSame(inputStream, requestEx.getInputStream());\n  }\n\n  @Test\n  public void getInputStreamCache() throws IOException {\n    requestEx.setCacheRequest(true);\n\n    ServletInputStream inputStream = request.getInputStream();\n    new Expectations(IOUtils.class) {\n      {\n        IOUtils.toByteArray(inputStream);\n        result = \"abc\".getBytes();\n      }\n    };\n\n    ServletInputStream cachedInputStream = requestEx.getInputStream();\n    Assertions.assertEquals(\"abc\", IOUtils.toString(cachedInputStream, StandardCharsets.UTF_8));\n    Assertions.assertEquals(\"abc\", requestEx.getBodyBuffer().toString());\n    // do not create another one\n    Assertions.assertSame(cachedInputStream, requestEx.getInputStream());\n  }\n\n  @Test\n  public void parameterMap_inherited() {\n    Map<String, String[]> inherited = new HashMap<>();\n    String[] v1 = new String[] {\"v1-1\", \"v1-2\"};\n    inherited.put(\"p1\", v1);\n    new Expectations() {\n      {\n        request.getParameterMap();\n        result = inherited;\n        request.getMethod();\n        result = HttpMethod.POST;\n      }\n    };\n\n    Assertions.assertSame(inherited, requestEx.getParameterMap());\n    MatcherAssert.assertThat(Collections.list(requestEx.getParameterNames()), Matchers.contains(\"p1\"));\n    Assertions.assertSame(v1, requestEx.getParameterValues(\"p1\"));\n    Assertions.assertEquals(\"v1-1\", requestEx.getParameter(\"p1\"));\n  }\n\n  @Test\n  public void parameterMap_merge() throws IOException {\n    Map<String, String[]> inherited = new HashMap<>();\n    String[] v1 = new String[] {\"v1-1\", \"v1-2\"};\n    inherited.put(\"p1\", v1);\n\n    Buffer buffer = Buffer.buffer(\"p1=v1-3;p2=v2\");\n    BufferInputStream inputStream = new BufferInputStream(buffer);\n    new Expectations() {\n      {\n        request.getParameterMap();\n        result = inherited;\n        request.getMethod();\n        result = HttpMethod.PUT;\n        request.getContentType();\n        result = MediaType.APPLICATION_FORM_URLENCODED.toUpperCase(Locale.US) + \";abc\";\n        request.getInputStream();\n        result = inputStream;\n      }\n    };\n\n    MatcherAssert.assertThat(Collections.list(requestEx.getParameterNames()), Matchers.containsInAnyOrder(\"p1\", \"p2\"));\n    MatcherAssert.assertThat(requestEx.getParameterValues(\"p1\"), Matchers.arrayContaining(\"v1-1\", \"v1-2\", \"v1-3\"));\n    Assertions.assertEquals(\"v1-1\", requestEx.getParameter(\"p1\"));\n  }\n\n  @Test\n  public void setParameter() {\n    Map<String, String[]> parameterMap = new HashMap<>();\n    Deencapsulation.setField(requestEx, \"parameterMap\", parameterMap);\n\n    requestEx.setParameter(\"k1\", \"v1\");\n    requestEx.setParameter(\"k2\", \"v2\");\n\n    Assertions.assertEquals(\"v1\", requestEx.getParameter(\"k1\"));\n    Assertions.assertEquals(\"v2\", requestEx.getParameter(\"k2\"));\n\n    Assertions.assertSame(parameterMap, requestEx.getParameterMap());\n\n    MatcherAssert.assertThat(Collections.list(requestEx.getParameterNames()), Matchers.containsInAnyOrder(\"k1\", \"k2\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestStandardHttpServletResponseEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport org.apache.commons.lang3.RandomStringUtils;\nimport org.apache.servicecomb.foundation.common.part.InputStreamPart;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.buffer.Buffer;\nimport jakarta.servlet.ServletOutputStream;\nimport jakarta.servlet.WriteListener;\nimport jakarta.servlet.http.HttpServletResponse;\nimport jakarta.servlet.http.Part;\n\n\npublic class TestStandardHttpServletResponseEx {\n  HttpServletResponse response;\n\n  StandardHttpServletResponseEx responseEx;\n\n  @Before\n  public void setup() {\n    response = Mockito.mock(HttpServletResponse.class);\n    responseEx = new StandardHttpServletResponseEx(response);\n  }\n\n  @Test\n  public void setBodyBuffer() {\n    Assertions.assertNull(responseEx.getBodyBuffer());\n\n    Buffer bodyBuffer = Buffer.buffer();\n    bodyBuffer.appendString(\"abc\");\n    responseEx.setBodyBuffer(bodyBuffer);\n    Assertions.assertEquals(\"abc\", responseEx.getBodyBuffer().toString());\n  }\n\n  @Test\n  public void getBodyBytes() {\n    Buffer bodyBuffer = Buffer.buffer();\n    bodyBuffer.appendString(\"abc\");\n    responseEx.setBodyBuffer(bodyBuffer);\n    Assertions.assertEquals(\"abc\", new String(responseEx.getBodyBytes(), 0, responseEx.getBodyBytesLength()));\n  }\n\n  @Test\n  public void getBodyBytesLength() {\n    Buffer bodyBuffer = Buffer.buffer();\n    bodyBuffer.appendString(\"abc\");\n    responseEx.setBodyBuffer(bodyBuffer);\n    Assertions.assertEquals(3, responseEx.getBodyBytesLength());\n  }\n\n  @Test\n  public void flushBuffer() throws IOException {\n    Buffer buffer = Buffer.buffer();\n    ServletOutputStream output = new ServletOutputStream() {\n      @Override\n      public boolean isReady() {\n        return true;\n      }\n\n      @Override\n      public void setWriteListener(WriteListener writeListener) {\n\n      }\n\n      @Override\n      public void write(int b) {\n        buffer.appendByte((byte) b);\n      }\n    };\n\n    Mockito.when(response.getOutputStream()).thenReturn(output);\n    responseEx = new StandardHttpServletResponseEx(response);\n\n    // no body\n    responseEx.flushBuffer();\n    Assertions.assertEquals(0, buffer.length());\n\n    Buffer body = Buffer.buffer().appendString(\"body\");\n    responseEx.setBodyBuffer(body);\n    responseEx.flushBuffer();\n    Assertions.assertEquals(0, buffer.length());\n  }\n\n  @Test\n  public void attribute() {\n    responseEx.setAttribute(\"k\", \"v\");\n    Assertions.assertEquals(\"v\", responseEx.getAttribute(\"k\"));\n  }\n\n  @Test\n  public void sendPart_succ() throws Throwable {\n    String src = RandomStringUtils.random(100, true, true);\n    InputStream inputStream = new ByteArrayInputStream(src.getBytes());\n    Part part = new InputStreamPart(\"name\", inputStream);\n    Buffer buffer = Buffer.buffer();\n\n    ServletOutputStream outputStream = new ServletOutputStream() {\n      @Override\n      public boolean isReady() {\n        return false;\n      }\n\n      @Override\n      public void setWriteListener(WriteListener writeListener) {\n\n      }\n\n      @Override\n      public void write(int b) {\n        buffer.appendByte((byte) b);\n      }\n    };\n    Mockito.when(response.getOutputStream()).thenReturn(outputStream);\n\n    responseEx.sendPart(part).get();\n\n    Assertions.assertEquals(src, buffer.toString());\n  }\n\n  @Test\n  public void sendPart_failed() throws Throwable {\n    Part part = Mockito.mock(Part.class);\n    RuntimeException error = new RuntimeExceptionWithoutStackTrace();\n    Mockito.when(response.getOutputStream()).thenThrow(error);\n\n    Assertions.assertThrows(RuntimeException.class, () -> responseEx.sendPart(part).get());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxClientRequestToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.util.Collections;\n\nimport jakarta.ws.rs.core.HttpHeaders;\n\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpMethod;\nimport mockit.Expectations;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestVertxClientRequestToHttpServletRequest {\n  HttpClientRequest clientRequest;\n\n  Buffer bodyBuffer = Buffer.buffer();\n\n  VertxClientRequestToHttpServletRequest request;\n\n  @BeforeEach\n  public void setup() {\n    clientRequest = Mockito.mock(HttpClientRequest.class);\n    request = new VertxClientRequestToHttpServletRequest(clientRequest, bodyBuffer);\n  }\n\n  @AfterEach\n  public void after() {\n    Mockito.reset(clientRequest);\n  }\n\n  @Test\n  public void testGetRequestURI() {\n    Mockito.when(clientRequest.path()).thenReturn(\"/path\");\n\n    Assertions.assertEquals(\"/path\", request.getRequestURI());\n  }\n\n  @Test\n  public void testGetQueryString() {\n    Mockito.when(clientRequest.query()).thenReturn(\"a=1&b=2\");\n\n    Assertions.assertEquals(\"a=1&b=2\", request.getQueryString());\n  }\n\n  @Test\n  public void testGetHeader() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"name\", \"value\");\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    Assertions.assertEquals(\"value\", request.getHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetHeaders() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"name\", \"value\");\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    MatcherAssert.assertThat(Collections.list(request.getHeaders(\"name\")), Matchers.contains(\"value\"));\n  }\n\n  @Test\n  public void testGetHeaderNames() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"name\", \"value\");\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    MatcherAssert.assertThat(Collections.list(request.getHeaderNames()), Matchers.contains(\"name\"));\n  }\n\n  @Test\n  public void testSetHeader() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    request.setHeader(\"name\", \"v1\");\n    request.setHeader(\"name\", \"v2\");\n    MatcherAssert.assertThat(headers.getAll(\"name\"), Matchers.contains(\"v2\"));\n  }\n\n  @Test\n  public void testAddHeader() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    request.addHeader(\"name\", \"v1\");\n    request.addHeader(\"name\", \"v2\");\n    MatcherAssert.assertThat(headers.getAll(\"name\"), Matchers.contains(\"v1\", \"v2\"));\n  }\n\n  @Test\n  public void testGetContextPath() {\n    Assertions.assertEquals(\"\", request.getContextPath());\n  }\n\n  @Test\n  public void getMethod() {\n    Mockito.when(clientRequest.getMethod()).thenReturn(HttpMethod.GET);\n\n    Assertions.assertEquals(\"GET\", request.getMethod());\n  }\n\n  @Test\n  public void getContentType() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    request.addHeader(HttpHeaders.CONTENT_TYPE, \"ct\");\n\n    Assertions.assertEquals(\"ct\", request.getContentType());\n  }\n\n  @Test\n  public void getCharacterEncoding() {\n    String contentType = \"ct\";\n    String characterEncoding = \"ce\";\n\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    new Expectations(HttpUtils.class) {\n      {\n        HttpUtils.getCharsetFromContentType(contentType);\n        result = characterEncoding;\n      }\n    };\n    Mockito.when(clientRequest.headers()).thenReturn(headers);\n\n    request.addHeader(HttpHeaders.CONTENT_TYPE, contentType);\n\n    Assertions.assertEquals(\"ce\", request.getCharacterEncoding());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxClientResponseToHttpServletResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientResponse;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestVertxClientResponseToHttpServletResponse {\n  HttpClientResponse clientResponse;\n\n  Buffer bodyBuffer = Buffer.buffer();\n\n  VertxClientResponseToHttpServletResponse response;\n\n  @BeforeEach\n  public void setup() {\n    clientResponse = Mockito.mock(HttpClientResponse.class);\n    response = new VertxClientResponseToHttpServletResponse(clientResponse, bodyBuffer);\n  }\n\n  @AfterEach\n  public void after() {\n    Mockito.reset(clientResponse);\n  }\n\n  @Test\n  public void getStatus() {\n    Mockito.when(clientResponse.statusCode()).thenReturn(123);\n\n    Assertions.assertEquals(123, response.getStatus());\n  }\n\n  @Test\n  public void getStatusType() {\n    Mockito.when(clientResponse.statusCode()).thenReturn(123);\n    Mockito.when(clientResponse.statusMessage()).thenReturn(\"test\");\n\n    StatusType type = response.getStatusType();\n    Assertions.assertSame(type, response.getStatusType());\n    Assertions.assertEquals(123, type.getStatusCode());\n    Assertions.assertEquals(\"test\", type.getReasonPhrase());\n  }\n\n  @Test\n  public void getContentType() {\n    Mockito.when(clientResponse.getHeader(HttpHeaders.CONTENT_TYPE)).thenReturn(\"json\");\n\n    Assertions.assertEquals(\"json\", response.getContentType());\n  }\n\n  @Test\n  public void getHeader() {\n    Mockito.when(clientResponse.getHeader(\"name\")).thenReturn(\"value\");\n\n    Assertions.assertEquals(\"value\", response.getHeader(\"name\"));\n  }\n\n  @Test\n  public void getHeaders() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"name\", \"v1\");\n    headers.add(\"name\", \"v2\");\n    Mockito.when(clientResponse.headers()).thenReturn(headers);\n\n    MatcherAssert.assertThat(response.getHeaders(\"name\"), Matchers.contains(\"v1\", \"v2\"));\n  }\n\n  @Test\n  public void getHeaderNames() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"n1\", \"v1\");\n    headers.add(\"n2\", \"v2\");\n    Mockito.when(clientResponse.headers()).thenReturn(headers);\n\n    MatcherAssert.assertThat(response.getHeaderNames(), Matchers.contains(\"n1\", \"n2\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerRequestToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.http;\n\nimport java.io.IOException;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\nimport jakarta.servlet.AsyncContext;\nimport jakarta.servlet.ServletInputStream;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.ws.rs.core.HttpHeaders;\n\nimport io.vertx.ext.web.RequestBody;\nimport io.vertx.ext.web.impl.RoutingContextInternal;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.common.http.HttpUtils;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.ext.web.RoutingContext;\nimport mockit.Deencapsulation;\nimport mockit.Expectations;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\npublic class TestVertxServerRequestToHttpServletRequest {\n  @Mocked\n  RoutingContext context;\n\n  @Mocked\n  HttpServerRequest vertxRequest;\n\n  @Mocked\n  SocketAddress socketAddress;\n\n  RequestBody mockRequestBody;\n\n  RoutingContextInternal mockContext;\n\n  HttpServerRequest mockHttpServerRequest;\n\n  SocketAddress mockSocketAddress;\n\n  VertxServerRequestToHttpServletRequest request;\n\n  @Before\n  public void setup() {\n    new Expectations() {\n      {\n        context.request();\n        result = vertxRequest;\n        vertxRequest.remoteAddress();\n        result = socketAddress;\n      }\n    };\n\n    mockRequestBody = Mockito.mock(RequestBody.class);\n    mockContext = Mockito.mock(RoutingContextInternal.class);\n    mockHttpServerRequest = Mockito.mock(HttpServerRequest.class);\n    mockSocketAddress = Mockito.mock(SocketAddress.class);\n    // init mocks\n    Mockito.when(mockHttpServerRequest.remoteAddress()).thenReturn(mockSocketAddress);\n    Mockito.when(mockContext.body()).thenReturn(mockRequestBody);\n    Mockito.when(mockContext.request()).thenReturn(mockHttpServerRequest);\n\n    request = new VertxServerRequestToHttpServletRequest(context);\n  }\n\n  @After\n  public void clean() {\n    Mockito.reset(mockRequestBody);\n    Mockito.reset(mockContext);\n  }\n\n  @Test\n  public void constructWithPath() {\n    request = new VertxServerRequestToHttpServletRequest(context, \"/path\");\n\n    Assertions.assertEquals(\"/path\", request.getRequestURI());\n  }\n\n  @Test\n  public void setBodyBuffer() {\n    Holder<Buffer> bodyHolder = new Holder<>();\n    Mockito.doAnswer(invocation -> {\n      bodyHolder.value = invocation.getArgument(0);\n      return null;\n    }).when(mockContext).setBody(Mockito.any());\n    request = new VertxServerRequestToHttpServletRequest(mockContext);\n\n    Buffer bodyBuffer = Buffer.buffer();\n    request.setBodyBuffer(bodyBuffer);\n\n    Assertions.assertSame(bodyBuffer, bodyHolder.value);\n    Assertions.assertSame(bodyBuffer, request.getBodyBuffer());\n  }\n\n  @Test\n  public void testGetContentType() {\n    VertxServerRequestToHttpServletRequest request = new VertxServerRequestToHttpServletRequest(mockContext);\n    Mockito.when(mockHttpServerRequest.getHeader(HttpHeaders.CONTENT_TYPE)).thenReturn(\"json\");\n    Assertions.assertEquals(\"json\", request.getContentType());\n  }\n\n  @Test\n  public void testGetCookies() {\n    Set<io.vertx.core.http.Cookie> vertxCookies = new HashSet<>();\n    vertxCookies.add(io.vertx.core.http.Cookie.cookie(\"c1\", \"c1v\"));\n    vertxCookies.add(io.vertx.core.http.Cookie.cookie(\"c2\", \"c2v\"));\n    new Expectations() {\n      {\n        context.request().cookies();\n        result = vertxCookies;\n      }\n    };\n\n    Cookie[] cookies = request.getCookies();\n    // we can't ensure the sequence when set to list\n    if (cookies[0].getName().equals(\"c1\")) {\n      Assertions.assertEquals(\"c1\", cookies[0].getName());\n      Assertions.assertEquals(\"c1v\", cookies[0].getValue());\n      Assertions.assertEquals(\"c2\", cookies[1].getName());\n      Assertions.assertEquals(\"c2v\", cookies[1].getValue());\n    } else {\n      Assertions.assertEquals(\"c2\", cookies[0].getName());\n      Assertions.assertEquals(\"c2v\", cookies[0].getValue());\n      Assertions.assertEquals(\"c1\", cookies[1].getName());\n      Assertions.assertEquals(\"c1v\", cookies[1].getValue());\n    }\n  }\n\n  @Test\n  public void testGetParameter() {\n    new Expectations() {\n      {\n        vertxRequest.getParam(\"name\");\n        result = \"value\";\n      }\n    };\n\n    Assertions.assertEquals(\"value\", request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterValuesNull() {\n    Assertions.assertEquals(0, request.getParameterValues(\"name\").length);\n  }\n\n  @Test\n  public void testGetParameterValuesNormal() {\n    MultiMap params = MultiMap.caseInsensitiveMultiMap();\n    params.add(\"name\", \"value\");\n\n    new Expectations() {\n      {\n        vertxRequest.params();\n        result = params;\n      }\n    };\n\n    MatcherAssert.assertThat(request.getParameterValues(\"name\"), Matchers.arrayContaining(\"value\"));\n  }\n\n  @Test\n  public void testGetParameterMap() {\n    MultiMap params = MultiMap.caseInsensitiveMultiMap();\n    params.add(\"name\", \"value\");\n\n    new Expectations() {\n      {\n        vertxRequest.params();\n        result = params;\n      }\n    };\n\n    Map<String, String[]> result = request.getParameterMap();\n    MatcherAssert.assertThat(result.keySet(), Matchers.contains(\"name\"));\n    MatcherAssert.assertThat(result.get(\"name\"), Matchers.arrayContaining(\"value\"));\n    Assertions.assertSame(result, request.getParameterMap());\n  }\n\n  @Test\n  public void testScheme() {\n    new Expectations() {\n      {\n        vertxRequest.scheme();\n        result = \"abc\";\n      }\n    };\n\n    Assertions.assertEquals(\"abc\", request.getScheme());\n  }\n\n  @Test\n  public void testGetRemoteAddr() {\n    new Expectations() {\n      {\n        socketAddress.host();\n        result = \"host\";\n      }\n    };\n\n    Assertions.assertEquals(\"host\", request.getRemoteAddr());\n  }\n\n  @Test\n  public void testGetRemoteAddrNull() {\n    new Expectations() {\n      {\n        socketAddress.host();\n        result = null;\n      }\n    };\n    Assertions.assertNull(request.getRemoteAddr());\n  }\n\n  @Test\n  public void testGetRemoteHost() {\n    new Expectations() {\n      {\n        socketAddress.host();\n        result = \"host\";\n      }\n    };\n\n    Assertions.assertEquals(\"host\", request.getRemoteHost());\n  }\n\n  @Test\n  public void testGetRemotePort() {\n    new Expectations() {\n      {\n        socketAddress.port();\n        result = 1234;\n      }\n    };\n\n    Assertions.assertEquals(1234, request.getRemotePort());\n  }\n\n  @Test\n  public void testGetgetLocalAddr(@Mocked SocketAddress sa) {\n    new Expectations() {\n      {\n        sa.host();\n        result = \"host\";\n        vertxRequest.localAddress();\n        result = sa;\n      }\n    };\n\n    Assertions.assertEquals(\"host\", request.getLocalAddr());\n  }\n\n  @Test\n  public void testGetLocalPort(@Mocked SocketAddress sa) {\n    new Expectations() {\n      {\n        sa.port();\n        result = 1234;\n        vertxRequest.localAddress();\n        result = sa;\n      }\n    };\n\n    Assertions.assertEquals(1234, request.getLocalPort());\n  }\n\n  @Test\n  public void testGetHeader() {\n    new Expectations() {\n      {\n        vertxRequest.getHeader(\"key\");\n        result = \"value\";\n      }\n    };\n\n    Assertions.assertEquals(\"value\", request.getHeader(\"key\"));\n  }\n\n  @Test\n  public void testGetHeaders() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"name\", \"value\");\n    new Expectations() {\n      {\n        vertxRequest.headers();\n        result = headers;\n      }\n    };\n\n    MatcherAssert.assertThat(Collections.list(request.getHeaders(\"name\")), Matchers.contains(\"value\"));\n  }\n\n  @Test\n  public void testGetHeaderNames() {\n    MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n    headers.add(\"name\", \"value\");\n    new Expectations() {\n      {\n        vertxRequest.headers();\n        result = headers;\n      }\n    };\n\n    MatcherAssert.assertThat(Collections.list(request.getHeaderNames()), Matchers.contains(\"name\"));\n  }\n\n  @Test\n  public void testGetIntHeaderNotExist() {\n    Assertions.assertEquals(-1, request.getIntHeader(\"key\"));\n  }\n\n  @Test\n  public void testGetIntHeaderNotNumber() {\n    new Expectations() {\n      {\n        vertxRequest.getHeader(\"key\");\n        result = \"value\";\n      }\n    };\n\n    try {\n      request.getIntHeader(\"key\");\n      Assertions.fail(\"must throw exception\");\n    } catch (NumberFormatException e) {\n      Assertions.assertEquals(\"For input string: \\\"value\\\"\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testGetIntHeaderNormal() {\n    new Expectations() {\n      {\n        vertxRequest.getHeader(\"key\");\n        result = \"1\";\n      }\n    };\n\n    Assertions.assertEquals(1, request.getIntHeader(\"key\"));\n  }\n\n  @Test\n  public void testGetMethod() {\n    new Expectations() {\n      {\n        vertxRequest.method();\n        result = HttpMethod.GET;\n      }\n    };\n\n    Assertions.assertEquals(\"GET\", request.getMethod());\n  }\n\n  @Test\n  public void testGetPathInfo() {\n    new Expectations() {\n      {\n        vertxRequest.path();\n        result = \"/path\";\n      }\n    };\n\n    Assertions.assertEquals(\"/path\", request.getPathInfo());\n  }\n\n  @Test\n  public void testGetQueryString() {\n    new Expectations() {\n      {\n        vertxRequest.query();\n        result = \"k1=v1&k2=v2\";\n      }\n    };\n\n    Assertions.assertEquals(\"k1=v1&k2=v2\", request.getQueryString());\n  }\n\n  @Test\n  public void testGetRequestURI() {\n    new Expectations() {\n      {\n        vertxRequest.path();\n        result = \"/path\";\n      }\n    };\n\n    Assertions.assertEquals(\"/path\", request.getRequestURI());\n  }\n\n  @Test\n  public void testGetServletPath() {\n    new Expectations() {\n      {\n        vertxRequest.path();\n        result = \"/path\";\n      }\n    };\n\n    Assertions.assertEquals(\"/path\", request.getServletPath());\n  }\n\n  @Test\n  public void testGetContextPath() {\n    Assertions.assertEquals(\"\", request.getContextPath());\n  }\n\n  @Test\n  public void testGetInputStream() throws IOException {\n    Buffer body = Buffer.buffer();\n    body.appendByte((byte) 1);\n\n    Mockito.when(mockRequestBody.buffer()).thenReturn(body);\n    Mockito.when(mockContext.request()).thenReturn(vertxRequest);\n    Mockito.when(mockContext.body()).thenReturn(mockRequestBody);\n\n    VertxServerRequestToHttpServletRequest request = new VertxServerRequestToHttpServletRequest(mockContext);\n    ServletInputStream is1 = request.getInputStream();\n    Assertions.assertSame(is1, request.getInputStream());\n    int value = is1.read();\n    is1.close();\n    Assertions.assertEquals(1, value);\n    Assertions.assertSame(is1, request.getInputStream());\n\n    request.setBodyBuffer(Buffer.buffer().appendByte((byte) 2));\n    ServletInputStream is2 = request.getInputStream();\n    Assertions.assertNotSame(is1, is2);\n  }\n\n  @Test\n  public void testGetAsyncContext() {\n    AsyncContext asyncContext =\n        Deencapsulation.getField(VertxServerRequestToHttpServletRequest.class, \"EMPTY_ASYNC_CONTEXT\");\n\n    Assertions.assertSame(asyncContext, request.getAsyncContext());\n  }\n\n  @Test\n  public void getCharacterEncoding() {\n    new Expectations(HttpUtils.class) {\n      {\n        vertxRequest.getHeader(HttpHeaders.CONTENT_TYPE);\n        result = \"ct\";\n        HttpUtils.getCharsetFromContentType(\"ct\");\n        result = \"ce\";\n      }\n    };\n\n    Assertions.assertEquals(\"ce\", request.getCharacterEncoding());\n  }\n\n\n  @Test\n  public void setParameter() {\n    Map<String, String[]> parameterMap = new HashMap<>();\n    Deencapsulation.setField(request, \"parameterMap\", parameterMap);\n\n    request.setParameter(\"k1\", \"v1\");\n    request.setParameter(\"k2\", \"v2\");\n\n    Assertions.assertEquals(\"v1\", request.getParameter(\"k1\"));\n    Assertions.assertEquals(\"v2\", request.getParameter(\"k2\"));\n\n    Assertions.assertSame(parameterMap, request.getParameterMap());\n\n    MatcherAssert.assertThat(Collections.list(request.getParameterNames()), Matchers.containsInAnyOrder(\"k1\", \"k2\"));\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.http.HttpClient;\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.net.impl.SocketAddressImpl;\nimport io.vertx.core.spi.observability.HttpRequest;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestDefaultHttpClientMetrics {\n  @Mocked\n  Vertx vertx;\n\n  VertxOptions vertxOptions = new VertxOptions();\n\n  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();\n\n  @Mocked\n  HttpClient anyHttpClient;\n\n  HttpClientOptions options = new HttpClientOptions();\n\n  DefaultVertxMetrics defaultVertxMetrics;\n\n  DefaultHttpClientMetrics clientMetrics_a;\n\n  DefaultHttpClientMetrics clientMetrics_b;\n\n  String host = \"host\";\n\n  int port1 = 1;\n\n  int port2 = 2;\n\n  SocketAddress address1 = new SocketAddressImpl(port1, host);\n\n  SocketAddress address2 = new SocketAddressImpl(port2, host);\n\n  DefaultClientMetrics clientMetrics_a_1;\n\n  DefaultEndpointMetric endpointMetric_a_1;\n\n  DefaultTcpSocketMetric socketMetric_a_1;\n\n  DefaultClientMetrics clientMetrics_a_2;\n\n  DefaultEndpointMetric endpointMetric_a_2;\n\n  DefaultTcpSocketMetric socketMetric_a_2;\n\n  DefaultClientMetrics clientMetrics_b_1;\n\n  DefaultEndpointMetric endpointMetric_b_1;\n\n  DefaultTcpSocketMetric socketMetric_b_1;\n\n  DefaultClientMetrics clientMetrics_b_2;\n\n  DefaultEndpointMetric endpointMetric_b_2;\n\n  DefaultTcpSocketMetric socketMetric_b_2;\n\n  static long nanoTime;\n\n  @BeforeClass\n  public static void classSetup() {\n    new MockUp<System>() {\n      @Mock\n      long nanoTime() {\n        return nanoTime;\n      }\n    };\n  }\n\n  private static DefaultTcpSocketMetric initSocketMetric(DefaultClientMetrics clientMetrics,\n      DefaultHttpClientMetrics metrics,\n      SocketAddress address) {\n    DefaultTcpSocketMetric socketMetric = metrics.connected(address, address.toString());\n    metrics.endpointConnected(clientMetrics);\n    return socketMetric;\n  }\n\n  @Before\n  public void setup() {\n    vertxOptions.setMetricsOptions(metricsOptionsEx);\n    defaultVertxMetrics = new DefaultVertxMetrics(vertxOptions);\n    defaultVertxMetrics.setVertx(vertx);\n    clientMetrics_a = (DefaultHttpClientMetrics) defaultVertxMetrics.createHttpClientMetrics(options);\n    clientMetrics_b = (DefaultHttpClientMetrics) defaultVertxMetrics.createHttpClientMetrics(options);\n\n    nanoTime = 1;\n\n    clientMetrics_a_1 = clientMetrics_a.createEndpointMetrics(address1, 0);\n    socketMetric_a_1 = initSocketMetric(clientMetrics_a_1, clientMetrics_a, address1);\n    endpointMetric_a_1 = socketMetric_a_1.getEndpointMetric();\n\n    clientMetrics_a_2 = clientMetrics_a.createEndpointMetrics(address2, 0);\n    socketMetric_a_2 = initSocketMetric(clientMetrics_a_2, clientMetrics_a, address2);\n    endpointMetric_a_2 = socketMetric_a_2.getEndpointMetric();\n\n    clientMetrics_b_1 = clientMetrics_b.createEndpointMetrics(address1, 0);\n    socketMetric_b_1 = initSocketMetric(clientMetrics_b_1, clientMetrics_b, address1);\n    endpointMetric_b_1 = socketMetric_b_1.getEndpointMetric();\n\n    clientMetrics_b_2 = clientMetrics_b.createEndpointMetrics(address2, 0);\n    socketMetric_b_2 = initSocketMetric(clientMetrics_b_2, clientMetrics_b, address2);\n    endpointMetric_b_2 = socketMetric_b_2.getEndpointMetric();\n  }\n\n  @Test\n  public void createMetrics() {\n    Assertions.assertNotSame(clientMetrics_a, clientMetrics_b);\n  }\n\n  @Test\n  public void createEndpoint() {\n    Assertions.assertSame(endpointMetric_a_1, endpointMetric_b_1);\n    Assertions.assertNotSame(endpointMetric_a_1, endpointMetric_a_2);\n\n    Assertions.assertNotSame(endpointMetric_a_2, endpointMetric_b_1);\n    Assertions.assertSame(endpointMetric_a_2, endpointMetric_b_2);\n\n    Assertions.assertEquals(2, endpointMetric_a_1.getCurrentConnectionCount());\n    Assertions.assertEquals(2, endpointMetric_a_2.getCurrentConnectionCount());\n  }\n\n  @Test\n  public void expire() {\n    metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);\n\n    nanoTime = 2;\n    clientMetrics_a.disconnected(socketMetric_a_1, null);\n    clientMetrics_a.disconnected(socketMetric_a_2, null);\n\n    nanoTime = 13;\n    defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"http://\" + address1.toString()));\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"http://\" + address2.toString()));\n\n    clientMetrics_b.disconnected(socketMetric_b_1, null);\n    clientMetrics_b.disconnected(socketMetric_b_2, null);\n\n    nanoTime = 23;\n    defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"http://\" + address1.toString()));\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"http://\" + address2.toString()));\n\n    nanoTime = 24;\n    defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);\n    Assertions\n        .assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1.toString()));\n    Assertions\n        .assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2.toString()));\n  }\n\n  @Test\n  public void connect() {\n    {\n      Assertions.assertSame(endpointMetric_a_1, socketMetric_a_1.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_a_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(0, socketMetric_a_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(2, socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 2;\n      clientMetrics_a.disconnected(socketMetric_a_1, null);\n\n      Assertions.assertEquals(2, ((DefaultClientEndpointMetric) endpointMetric_a_1).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_a_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_a_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());\n    }\n\n    {\n      Assertions.assertSame(endpointMetric_a_2, socketMetric_a_2.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_a_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(0, socketMetric_a_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(2, socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 4;\n      clientMetrics_a.disconnected(socketMetric_a_2, null);\n\n      Assertions.assertEquals(4, ((DefaultClientEndpointMetric) endpointMetric_a_2).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_a_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_a_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());\n    }\n\n    {\n      Assertions.assertSame(endpointMetric_b_1, socketMetric_b_1.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_b_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_b_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 6;\n      clientMetrics_b.disconnected(socketMetric_b_1, null);\n\n      Assertions.assertEquals(6, ((DefaultClientEndpointMetric) endpointMetric_b_1).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_b_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(2, socketMetric_b_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(0, socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());\n    }\n\n    {\n      Assertions.assertSame(endpointMetric_b_2, socketMetric_b_2.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_b_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_b_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 7;\n      clientMetrics_b.disconnected(socketMetric_b_2, null);\n\n      Assertions.assertEquals(7, ((DefaultClientEndpointMetric) endpointMetric_b_2).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_b_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(2, socketMetric_b_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(0, socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());\n    }\n  }\n\n  @Test\n  public void bytesReadAndWritten() {\n    DefaultTcpSocketMetric socketMetric = clientMetrics_a.connected(address1, host);\n    clientMetrics_a.endpointConnected(clientMetrics_a_1);\n    clientMetrics_a.bytesRead(socketMetric, address1, 1);\n    clientMetrics_a.bytesWritten(socketMetric, address1, 1);\n\n    socketMetric = clientMetrics_a.connected(address2, host);\n    clientMetrics_a.endpointConnected(clientMetrics_a_2);\n    clientMetrics_a.bytesRead(socketMetric, address2, 1);\n    clientMetrics_a.bytesWritten(socketMetric, address2, 1);\n\n    socketMetric = clientMetrics_b.connected(address1, host);\n    clientMetrics_b.endpointConnected(clientMetrics_b_1);\n    clientMetrics_b.bytesRead(socketMetric, address1, 1);\n    clientMetrics_b.bytesWritten(socketMetric, address1, 1);\n\n    socketMetric = clientMetrics_b.connected(address2, host);\n    clientMetrics_b.endpointConnected(clientMetrics_b_2);\n    clientMetrics_b.bytesRead(socketMetric, address2, 1);\n    clientMetrics_b.bytesWritten(socketMetric, address2, 1);\n\n    Assertions.assertEquals(2, endpointMetric_a_1.getBytesRead());\n    Assertions.assertEquals(2, endpointMetric_a_2.getBytesRead());\n    Assertions.assertEquals(2, endpointMetric_a_1.getBytesWritten());\n    Assertions.assertEquals(2, endpointMetric_a_2.getBytesWritten());\n  }\n\n  @Test\n  public void requestBegin(@Mocked HttpRequest request) {\n    DefaultTcpSocketMetric socketMetric = clientMetrics_a.connected(address1, host);\n\n    nanoTime = 2;\n    DefaultRequestMetric requestMetric = clientMetrics_a_1.requestBegin(\"/ui\", request);\n    nanoTime = 3;\n    clientMetrics_a_1.requestEnd(requestMetric);\n\n    Assertions.assertEquals(2, requestMetric.getRequestBeginTime());\n    Assertions.assertEquals(3, requestMetric.getRequestEndTime());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport java.util.IdentityHashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.http.HttpServerOptions;\nimport io.vertx.core.net.SocketAddress;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestDefaultHttpServerMetrics {\n\n  VertxOptions vertxOptions = new VertxOptions();\n\n  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();\n\n  DefaultVertxMetrics defaultVertxMetrics;\n\n  @Mocked\n  SocketAddress listen1_addr;\n\n  @Mocked\n  SocketAddress listen2_addr;\n\n  @Mocked\n  HttpServerOptions options;\n\n  @Mocked\n  SocketAddress anyRemoteAddr;\n\n  DefaultHttpServerMetrics metrics_listen1_server1;\n\n  DefaultHttpServerMetrics metrics_listen1_server2;\n\n  DefaultEndpointMetric endpointMetric1;\n\n  DefaultHttpServerMetrics metrics_listen2_server1;\n\n  DefaultHttpServerMetrics metrics_listen2_server2;\n\n  DefaultEndpointMetric endpointMetric2;\n\n  String remoteName = \"remote\";\n\n  DefaultTcpSocketMetric socketMetric_listen1_1;\n\n  DefaultTcpSocketMetric socketMetric_listen1_2;\n\n  DefaultTcpSocketMetric socketMetric_listen2_1;\n\n  DefaultTcpSocketMetric socketMetric_listen2_2;\n\n  DefaultTcpSocketMetric socketMetric_listen2_3;\n\n  @Before\n  public void setup() {\n    vertxOptions.setMetricsOptions(metricsOptionsEx);\n    defaultVertxMetrics = new DefaultVertxMetrics(vertxOptions);\n\n    metrics_listen1_server1 = (DefaultHttpServerMetrics) defaultVertxMetrics\n        .createHttpServerMetrics(options, listen1_addr);\n    metrics_listen1_server2 = (DefaultHttpServerMetrics) defaultVertxMetrics\n        .createHttpServerMetrics(options, listen1_addr);\n    endpointMetric1 = metrics_listen1_server1.getEndpointMetric();\n\n    metrics_listen2_server1 = (DefaultHttpServerMetrics) defaultVertxMetrics\n        .createHttpServerMetrics(options, listen2_addr);\n    metrics_listen2_server2 = (DefaultHttpServerMetrics) defaultVertxMetrics\n        .createHttpServerMetrics(options, listen2_addr);\n    endpointMetric2 = metrics_listen2_server1.getEndpointMetric();\n\n    socketMetric_listen1_1 = metrics_listen1_server1.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen1_2 = metrics_listen1_server2.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen2_1 = metrics_listen2_server1.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen2_2 = metrics_listen2_server2.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen2_3 = metrics_listen2_server2.connected(anyRemoteAddr, remoteName);\n  }\n\n  @Test\n  public void createMetrics() {\n    Map<Object, Object> instances = new IdentityHashMap<>();\n    instances.put(metrics_listen1_server1, null);\n    instances.put(metrics_listen1_server2, null);\n    instances.put(metrics_listen2_server1, null);\n    instances.put(metrics_listen2_server2, null);\n    Assertions.assertEquals(4, instances.size());\n\n    Assertions.assertSame(metrics_listen1_server1.getEndpointMetric(), metrics_listen1_server2.getEndpointMetric());\n    Assertions.assertNotSame(metrics_listen1_server1.getEndpointMetric(), metrics_listen2_server1.getEndpointMetric());\n    Assertions.assertSame(metrics_listen2_server1.getEndpointMetric(), metrics_listen2_server2.getEndpointMetric());\n  }\n\n  @Test\n  public void connectionCount() {\n    Map<Object, Object> instances = new IdentityHashMap<>();\n    instances.put(socketMetric_listen1_1, null);\n    instances.put(socketMetric_listen1_2, null);\n    instances.put(socketMetric_listen2_1, null);\n    instances.put(socketMetric_listen2_2, null);\n    instances.put(socketMetric_listen2_3, null);\n    Assertions.assertEquals(5, instances.size());\n\n    Assertions.assertTrue(socketMetric_listen1_1.isConnected());\n    Assertions.assertTrue(socketMetric_listen1_2.isConnected());\n    Assertions.assertTrue(socketMetric_listen2_1.isConnected());\n    Assertions.assertTrue(socketMetric_listen2_2.isConnected());\n    Assertions.assertTrue(socketMetric_listen2_3.isConnected());\n\n    Assertions.assertEquals(2, endpointMetric1.getCurrentConnectionCount());\n    Assertions.assertEquals(3, endpointMetric2.getCurrentConnectionCount());\n\n    // disconnect\n    metrics_listen1_server1.disconnected(socketMetric_listen1_1, anyRemoteAddr);\n    metrics_listen1_server2.disconnected(socketMetric_listen1_2, anyRemoteAddr);\n    metrics_listen2_server1.disconnected(socketMetric_listen2_1, anyRemoteAddr);\n    metrics_listen2_server2.disconnected(socketMetric_listen2_2, anyRemoteAddr);\n    metrics_listen2_server2.disconnected(socketMetric_listen2_3, anyRemoteAddr);\n\n    Assertions.assertFalse(socketMetric_listen1_1.isConnected());\n    Assertions.assertFalse(socketMetric_listen1_2.isConnected());\n    Assertions.assertFalse(socketMetric_listen2_1.isConnected());\n    Assertions.assertFalse(socketMetric_listen2_2.isConnected());\n    Assertions.assertFalse(socketMetric_listen2_3.isConnected());\n\n    Assertions.assertEquals(0, endpointMetric1.getCurrentConnectionCount());\n    Assertions.assertEquals(0, endpointMetric2.getCurrentConnectionCount());\n  }\n\n  @Test\n  public void bytesRead() {\n    metrics_listen1_server1.bytesRead(socketMetric_listen1_1, anyRemoteAddr, 1);\n    metrics_listen1_server2.bytesRead(socketMetric_listen1_2, anyRemoteAddr, 2);\n    metrics_listen2_server1.bytesRead(socketMetric_listen2_1, anyRemoteAddr, 3);\n    metrics_listen2_server2.bytesRead(socketMetric_listen2_2, anyRemoteAddr, 4);\n    metrics_listen2_server2.bytesRead(socketMetric_listen2_3, anyRemoteAddr, 5);\n\n    Assertions.assertEquals(3, endpointMetric1.getBytesRead());\n    Assertions.assertEquals(12, endpointMetric2.getBytesRead());\n  }\n\n  @Test\n  public void bytesWritten() {\n    metrics_listen1_server1.bytesWritten(socketMetric_listen1_1, anyRemoteAddr, 1);\n    metrics_listen1_server2.bytesWritten(socketMetric_listen1_2, anyRemoteAddr, 2);\n    metrics_listen2_server1.bytesWritten(socketMetric_listen2_1, anyRemoteAddr, 3);\n    metrics_listen2_server2.bytesWritten(socketMetric_listen2_2, anyRemoteAddr, 4);\n    metrics_listen2_server2.bytesWritten(socketMetric_listen2_3, anyRemoteAddr, 5);\n\n    Assertions.assertEquals(3, endpointMetric1.getBytesWritten());\n    Assertions.assertEquals(12, endpointMetric2.getBytesWritten());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpClientMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.net.NetClientOptions;\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.net.impl.SocketAddressImpl;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestDefaultTcpClientMetrics {\n  @Mocked\n  Vertx vertx;\n\n  VertxOptions vertxOptions = new VertxOptions();\n\n  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();\n\n  NetClientOptions options = new NetClientOptions();\n\n  DefaultVertxMetrics defaultVertxMetrics;\n\n  DefaultTcpClientMetrics clientMetrics_a;\n\n  DefaultTcpClientMetrics clientMetrics_b;\n\n  String host = \"host\";\n\n  int port1 = 1;\n\n  int port2 = 2;\n\n  SocketAddress address1 = new SocketAddressImpl(port1, host);\n\n  SocketAddress address2 = new SocketAddressImpl(port2, host);\n\n  DefaultEndpointMetric endpointMetric_a_1;\n\n  DefaultTcpSocketMetric socketMetric_a_1;\n\n  DefaultEndpointMetric endpointMetric_a_2;\n\n  DefaultTcpSocketMetric socketMetric_a_2;\n\n  DefaultEndpointMetric endpointMetric_b_1;\n\n  DefaultTcpSocketMetric socketMetric_b_1;\n\n  DefaultEndpointMetric endpointMetric_b_2;\n\n  DefaultTcpSocketMetric socketMetric_b_2;\n\n  static long nanoTime;\n\n  @BeforeClass\n  public static void classSetup() {\n    new MockUp<System>() {\n      @Mock\n      long nanoTime() {\n        return nanoTime;\n      }\n    };\n  }\n\n  private static DefaultTcpSocketMetric initSocketMetric(DefaultTcpClientMetrics metrics,\n      SocketAddress address) {\n    return metrics.connected(address, address.toString());\n  }\n\n  @Before\n  public void setup() {\n    vertxOptions.setMetricsOptions(metricsOptionsEx);\n    defaultVertxMetrics = new DefaultVertxMetrics(vertxOptions);\n    defaultVertxMetrics.setVertx(vertx);\n    clientMetrics_a = (DefaultTcpClientMetrics) defaultVertxMetrics.createNetClientMetrics(options);\n    clientMetrics_b = (DefaultTcpClientMetrics) defaultVertxMetrics.createNetClientMetrics(options);\n\n    nanoTime = 1;\n\n    socketMetric_a_1 = initSocketMetric(clientMetrics_a, address1);\n    endpointMetric_a_1 = socketMetric_a_1.getEndpointMetric();\n    socketMetric_a_2 = initSocketMetric(clientMetrics_a, address2);\n    endpointMetric_a_2 = socketMetric_a_2.getEndpointMetric();\n\n    socketMetric_b_1 = initSocketMetric(clientMetrics_b, address1);\n    endpointMetric_b_1 = socketMetric_b_1.getEndpointMetric();\n    socketMetric_b_2 = initSocketMetric(clientMetrics_b, address2);\n    endpointMetric_b_2 = socketMetric_b_2.getEndpointMetric();\n  }\n\n  @Test\n  public void createMetrics() {\n    Assertions.assertNotSame(clientMetrics_a, clientMetrics_b);\n  }\n\n  @Test\n  public void createEndpoint() {\n    Assertions.assertSame(endpointMetric_a_1, endpointMetric_b_1);\n    Assertions.assertNotSame(endpointMetric_a_1, endpointMetric_a_2);\n\n    Assertions.assertNotSame(endpointMetric_a_2, endpointMetric_b_1);\n    Assertions.assertSame(endpointMetric_a_2, endpointMetric_b_2);\n\n    Assertions.assertEquals(2, endpointMetric_a_1.getCurrentConnectionCount());\n    Assertions.assertEquals(2, endpointMetric_a_2.getCurrentConnectionCount());\n  }\n\n  @Test\n  public void expire() {\n    metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);\n\n    nanoTime = 2;\n    clientMetrics_a.disconnected(socketMetric_a_1, null);\n    clientMetrics_a.disconnected(socketMetric_a_2, null);\n\n    nanoTime = 13;\n    defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"tcp://\" + address1.toString()));\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"tcp://\" + address2.toString()));\n\n    clientMetrics_b.disconnected(socketMetric_b_1, null);\n    clientMetrics_b.disconnected(socketMetric_b_2, null);\n\n    nanoTime = 23;\n    defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"tcp://\" + address1.toString()));\n    Assertions.assertNotNull(\n        defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(\"tcp://\" + address2.toString()));\n\n    nanoTime = 24;\n    defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);\n    Assertions\n        .assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1.toString()));\n    Assertions\n        .assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2.toString()));\n  }\n\n  @Test\n  public void connect() {\n    {\n      Assertions.assertSame(endpointMetric_a_1, socketMetric_a_1.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_a_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(0, socketMetric_a_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(2, socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 2;\n      clientMetrics_a.disconnected(socketMetric_a_1, null);\n\n      Assertions.assertEquals(2, ((DefaultClientEndpointMetric) endpointMetric_a_1).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_a_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_a_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());\n    }\n\n    {\n      Assertions.assertSame(endpointMetric_a_2, socketMetric_a_2.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_a_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(0, socketMetric_a_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(2, socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 4;\n      clientMetrics_a.disconnected(socketMetric_a_2, null);\n\n      Assertions.assertEquals(4, ((DefaultClientEndpointMetric) endpointMetric_a_2).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_a_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_a_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_a_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_a_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());\n    }\n\n    {\n      Assertions.assertSame(endpointMetric_b_1, socketMetric_b_1.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_b_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_b_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 6;\n      clientMetrics_b.disconnected(socketMetric_b_1, null);\n\n      Assertions.assertEquals(6, ((DefaultClientEndpointMetric) endpointMetric_b_1).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_b_1.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_1.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_1.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(2, socketMetric_b_1.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(0, socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());\n    }\n\n    {\n      Assertions.assertSame(endpointMetric_b_2, socketMetric_b_2.getEndpointMetric());\n      Assertions.assertTrue(socketMetric_b_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(1, socketMetric_b_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(1, socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());\n\n      nanoTime = 7;\n      clientMetrics_b.disconnected(socketMetric_b_2, null);\n\n      Assertions.assertEquals(7, ((DefaultClientEndpointMetric) endpointMetric_b_2).getLastNanoTime());\n      Assertions.assertFalse(socketMetric_b_2.isConnected());\n      Assertions.assertEquals(1, socketMetric_b_2.getConnectedTime());\n      Assertions.assertEquals(2, socketMetric_b_2.getEndpointMetric().getConnectCount());\n      Assertions.assertEquals(2, socketMetric_b_2.getEndpointMetric().getDisconnectCount());\n      Assertions.assertEquals(0, socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());\n    }\n  }\n\n  @Test\n  public void bytesReadAndWritten() {\n    clientMetrics_a.bytesRead(socketMetric_a_1, address1, 1);\n    clientMetrics_a.bytesWritten(socketMetric_a_1, address1, 1);\n\n    clientMetrics_a.bytesRead(socketMetric_a_2, address2, 1);\n    clientMetrics_a.bytesWritten(socketMetric_a_2, address2, 1);\n\n    clientMetrics_b.bytesRead(socketMetric_b_1, address1, 1);\n    clientMetrics_b.bytesWritten(socketMetric_b_1, address1, 1);\n\n    clientMetrics_b.bytesRead(socketMetric_b_2, address2, 1);\n    clientMetrics_b.bytesWritten(socketMetric_b_2, address2, 1);\n\n    Assertions.assertEquals(2, endpointMetric_a_1.getBytesRead());\n    Assertions.assertEquals(2, endpointMetric_a_2.getBytesRead());\n    Assertions.assertEquals(2, endpointMetric_a_1.getBytesWritten());\n    Assertions.assertEquals(2, endpointMetric_a_2.getBytesWritten());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpServerMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport java.util.IdentityHashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.net.NetServerOptions;\nimport io.vertx.core.net.SocketAddress;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestDefaultTcpServerMetrics {\n\n  VertxOptions vertxOptions = new VertxOptions();\n\n  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();\n\n  DefaultVertxMetrics defaultVertxMetrics;\n\n  @Mocked\n  SocketAddress listen1_addr;\n\n  @Mocked\n  SocketAddress listen2_addr;\n\n  @Mocked\n  NetServerOptions options;\n\n  DefaultTcpServerMetrics metrics_listen1_server1;\n\n  DefaultTcpServerMetrics metrics_listen1_server2;\n\n  DefaultEndpointMetric endpointMetric1;\n\n  DefaultTcpServerMetrics metrics_listen2_server1;\n\n  DefaultTcpServerMetrics metrics_listen2_server2;\n\n  DefaultEndpointMetric endpointMetric2;\n\n  @Mocked\n  SocketAddress anyRemoteAddr;\n\n  String remoteName = \"remote\";\n\n  DefaultTcpSocketMetric socketMetric_listen1_1;\n\n  DefaultTcpSocketMetric socketMetric_listen1_2;\n\n  DefaultTcpSocketMetric socketMetric_listen2_1;\n\n  DefaultTcpSocketMetric socketMetric_listen2_2;\n\n  DefaultTcpSocketMetric socketMetric_listen2_3;\n\n  @Before\n  public void setup() {\n    vertxOptions.setMetricsOptions(metricsOptionsEx);\n    defaultVertxMetrics = new DefaultVertxMetrics(vertxOptions);\n\n    metrics_listen1_server1 = (DefaultTcpServerMetrics) defaultVertxMetrics\n        .createNetServerMetrics(options, listen1_addr);\n    metrics_listen1_server2 = (DefaultTcpServerMetrics) defaultVertxMetrics\n        .createNetServerMetrics(options, listen1_addr);\n    endpointMetric1 = metrics_listen1_server1.getEndpointMetric();\n\n    metrics_listen2_server1 = (DefaultTcpServerMetrics) defaultVertxMetrics\n        .createNetServerMetrics(options, listen2_addr);\n    metrics_listen2_server2 = (DefaultTcpServerMetrics) defaultVertxMetrics\n        .createNetServerMetrics(options, listen2_addr);\n    endpointMetric2 = metrics_listen2_server1.getEndpointMetric();\n\n    socketMetric_listen1_1 = metrics_listen1_server1.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen1_2 = metrics_listen1_server2.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen2_1 = metrics_listen2_server1.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen2_2 = metrics_listen2_server2.connected(anyRemoteAddr, remoteName);\n    socketMetric_listen2_3 = metrics_listen2_server2.connected(anyRemoteAddr, remoteName);\n  }\n\n  @Test\n  public void createMetrics() {\n    Map<Object, Object> instances = new IdentityHashMap<>();\n    instances.put(metrics_listen1_server1, null);\n    instances.put(metrics_listen1_server2, null);\n    instances.put(metrics_listen2_server1, null);\n    instances.put(metrics_listen2_server2, null);\n    Assertions.assertEquals(4, instances.size());\n\n    Assertions.assertSame(metrics_listen1_server1.getEndpointMetric(), metrics_listen1_server2.getEndpointMetric());\n    Assertions.assertNotSame(metrics_listen1_server1.getEndpointMetric(), metrics_listen2_server1.getEndpointMetric());\n    Assertions.assertSame(metrics_listen2_server1.getEndpointMetric(), metrics_listen2_server2.getEndpointMetric());\n  }\n\n  @Test\n  public void connectionCount() {\n    Map<Object, Object> instances = new IdentityHashMap<>();\n    instances.put(socketMetric_listen1_1, null);\n    instances.put(socketMetric_listen1_2, null);\n    instances.put(socketMetric_listen2_1, null);\n    instances.put(socketMetric_listen2_2, null);\n    instances.put(socketMetric_listen2_3, null);\n    Assertions.assertEquals(5, instances.size());\n\n    Assertions.assertTrue(socketMetric_listen1_1.isConnected());\n    Assertions.assertTrue(socketMetric_listen1_2.isConnected());\n    Assertions.assertTrue(socketMetric_listen2_1.isConnected());\n    Assertions.assertTrue(socketMetric_listen2_2.isConnected());\n    Assertions.assertTrue(socketMetric_listen2_3.isConnected());\n\n    Assertions.assertEquals(2, endpointMetric1.getCurrentConnectionCount());\n    Assertions.assertEquals(3, endpointMetric2.getCurrentConnectionCount());\n\n    // disconnect\n    metrics_listen1_server1.disconnected(socketMetric_listen1_1, anyRemoteAddr);\n    metrics_listen1_server2.disconnected(socketMetric_listen1_2, anyRemoteAddr);\n    metrics_listen2_server1.disconnected(socketMetric_listen2_1, anyRemoteAddr);\n    metrics_listen2_server2.disconnected(socketMetric_listen2_2, anyRemoteAddr);\n    metrics_listen2_server2.disconnected(socketMetric_listen2_3, anyRemoteAddr);\n\n    Assertions.assertFalse(socketMetric_listen1_1.isConnected());\n    Assertions.assertFalse(socketMetric_listen1_2.isConnected());\n    Assertions.assertFalse(socketMetric_listen2_1.isConnected());\n    Assertions.assertFalse(socketMetric_listen2_2.isConnected());\n    Assertions.assertFalse(socketMetric_listen2_3.isConnected());\n\n    Assertions.assertEquals(0, endpointMetric1.getCurrentConnectionCount());\n    Assertions.assertEquals(0, endpointMetric2.getCurrentConnectionCount());\n  }\n\n  @Test\n  public void bytesRead() {\n    metrics_listen1_server1.bytesRead(socketMetric_listen1_1, anyRemoteAddr, 1);\n    metrics_listen1_server2.bytesRead(socketMetric_listen1_2, anyRemoteAddr, 2);\n    metrics_listen2_server1.bytesRead(socketMetric_listen2_1, anyRemoteAddr, 3);\n    metrics_listen2_server2.bytesRead(socketMetric_listen2_2, anyRemoteAddr, 4);\n    metrics_listen2_server2.bytesRead(socketMetric_listen2_3, anyRemoteAddr, 5);\n\n    Assertions.assertEquals(3, endpointMetric1.getBytesRead());\n    Assertions.assertEquals(12, endpointMetric2.getBytesRead());\n  }\n\n  @Test\n  public void bytesWritten() {\n    metrics_listen1_server1.bytesWritten(socketMetric_listen1_1, anyRemoteAddr, 1);\n    metrics_listen1_server2.bytesWritten(socketMetric_listen1_2, anyRemoteAddr, 2);\n    metrics_listen2_server1.bytesWritten(socketMetric_listen2_1, anyRemoteAddr, 3);\n    metrics_listen2_server2.bytesWritten(socketMetric_listen2_2, anyRemoteAddr, 4);\n    metrics_listen2_server2.bytesWritten(socketMetric_listen2_3, anyRemoteAddr, 5);\n\n    Assertions.assertEquals(3, endpointMetric1.getBytesWritten());\n    Assertions.assertEquals(12, endpointMetric2.getBytesWritten());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport org.junit.Test;\n\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.metrics.MetricsOptions;\nimport io.vertx.core.spi.metrics.VertxMetrics;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestDefaultVertxMetricsFactory {\n\n  VertxOptions options = new VertxOptions();\n\n  DefaultVertxMetricsFactory factory = new DefaultVertxMetricsFactory();\n\n  @Test\n  public void metrics() {\n    MetricsOptions metricsOptions = factory.newOptions();\n    options.setMetricsOptions(metricsOptions);\n    VertxMetrics vertxMetrics = factory.metrics(options);\n\n    Assertions.assertTrue(metricsOptions.isEnabled());\n\n    Assertions.assertSame(factory.getVertxMetrics(), vertxMetrics);\n    Assertions.assertTrue(vertxMetrics.isMetricsEnabled());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestMetricsOptionsEx.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.metrics;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMetricsOptionsEx {\n  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();\n\n  @Test\n  public void interval() {\n    Assertions.assertEquals(TimeUnit.MINUTES.toMillis(1),\n        metricsOptionsEx.getCheckClientEndpointMetricIntervalInMilliseconds());\n\n    metricsOptionsEx.setCheckClientEndpointMetricIntervalInMinute(2);\n    Assertions.assertEquals(TimeUnit.MINUTES.toMillis(2),\n        metricsOptionsEx.getCheckClientEndpointMetricIntervalInMilliseconds());\n  }\n\n  @Test\n  public void expired() {\n    Assertions.assertEquals(TimeUnit.MINUTES.toNanos(15), metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano());\n\n    metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);\n    Assertions.assertEquals(10, metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano());\n\n    metricsOptionsEx.setCheckClientEndpointMetricExpiredInMinute(60);\n    Assertions.assertEquals(TimeUnit.MINUTES.toNanos(60), metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/server/TestTcpParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.server;\n\nimport java.io.UnsupportedEncodingException;\n\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\n\nimport io.vertx.core.buffer.Buffer;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestTcpParser {\n  long msgId;\n\n  Buffer headerBuffer;\n\n  Buffer bodyBuffer;\n\n  @Test\n  public void test() throws UnsupportedEncodingException {\n    TcpBufferHandler output = (_msgId, _headerBuffer, _bodyBuffer) -> {\n      msgId = _msgId;\n      headerBuffer = _headerBuffer;\n      bodyBuffer = _bodyBuffer;\n    };\n\n    byte[] header = new byte[] {1, 2, 3};\n    byte[] body = new byte[] {1, 2, 3, 4};\n    TcpOutputStream os = new TcpOutputStream(1);\n    os.writeInt(header.length + body.length);\n    os.writeInt(header.length);\n    os.write(header);\n    os.write(body);\n\n    TcpParser parser = new TcpParser(output);\n    parser.handle(os.getBuffer());\n    os.close();\n\n    Assertions.assertEquals(1, msgId);\n    Assertions.assertArrayEquals(header, headerBuffer.getBytes());\n    Assertions.assertArrayEquals(body, bodyBuffer.getBytes());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/server/TestTcpServerConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.foundation.vertx.server;\n\nimport io.vertx.core.net.SocketAddress;\nimport io.vertx.core.net.impl.NetSocketImpl;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestTcpServerConnection {\n  @Test\n  public void test() {\n    SocketAddress socketAddress = Mockito.mock(SocketAddress.class);\n    NetSocketImpl netSocket = Mockito.mock(NetSocketImpl.class);\n    Mockito.when(netSocket.remoteAddress()).thenReturn(socketAddress);\n    TcpServerConnection connection = new TcpServerConnection();\n    connection.setProtocol(\"p\");\n    connection.setZipName(\"z\");\n\n    connection.init(netSocket);\n\n    Assertions.assertEquals(netSocket, connection.getNetSocket());\n  }\n}\n"
  },
  {
    "path": "foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/stream/TestBufferInputStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.foundation.vertx.stream;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.zip.GZIPInputStream;\nimport java.util.zip.GZIPOutputStream;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class TestBufferInputStream {\n\n  private BufferInputStream instance;\n\n  @Before\n  public void setUp() throws Exception {\n    Buffer buffer = Mockito.mock(Buffer.class);\n    instance = new BufferInputStream(buffer);\n  }\n\n  @After\n  public void tearDown() throws Exception {\n    instance = null;\n  }\n\n  @Test\n  public void testRead() {\n    Assertions.assertEquals(0, instance.read());\n  }\n\n  @Test\n  public void testReadDecorate() throws IOException {\n    String text = \"abcdefg123456789\";\n    ByteArrayOutputStream out = new ByteArrayOutputStream();\n    GZIPOutputStream gzipOutputStream = new GZIPOutputStream(out);\n    gzipOutputStream.write(text.getBytes());\n    gzipOutputStream.close();\n\n    Buffer buffer = Buffer.buffer();\n    buffer.appendBytes(out.toByteArray());\n    out.close();\n    BufferInputStream bufferInputStream = new BufferInputStream(buffer);\n    GZIPInputStream gzipInputStream = new GZIPInputStream(bufferInputStream);\n    StringBuilder sb = new StringBuilder();\n    byte[] bufferByte = new byte[256];\n    int n;\n    while ((n = gzipInputStream.read(bufferByte)) >= 0) {\n      sb.append(new String(bufferByte, 0, n));\n    }\n    gzipInputStream.close();\n\n    Assertions.assertEquals(text, sb.toString());\n  }\n\n  @Test\n  public void testReadByteArray() {\n    byte[] b = \"csr\".getBytes(StandardCharsets.UTF_8);\n    Assertions.assertEquals(-1, instance.read(b));\n  }\n\n  @Test\n  public void testReadByteArrayIntInt() {\n    byte[] b = \"csr\".getBytes(StandardCharsets.UTF_8);\n    Assertions.assertEquals(-1, instance.read(b, 1, 0));\n  }\n\n  @Test\n  public void testSkip() {\n    Assertions.assertEquals(0, instance.skip(1));\n  }\n\n  @Test\n  public void testAvailable() {\n    Assertions.assertEquals(0, instance.available());\n  }\n\n  @Test\n  public void testClose() {\n    try {\n      instance.close();\n    } catch (Exception e) {\n      Assertions.fail(); // This assertion is made to fail the test case in case the close() throws exception\n    }\n  }\n\n  @Test\n  public void testBufferInputStream() {\n    Assertions.assertNotNull(instance);\n  }\n\n  @Test\n  public void testReadBoolean() {\n    Assertions.assertFalse(instance.readBoolean());\n  }\n\n  @Test\n  public void testReadShort() {\n    Assertions.assertEquals(0, instance.readShort());\n  }\n\n  @Test\n  public void testReadInt() {\n    Assertions.assertEquals(0, instance.readInt());\n  }\n\n  @Test\n  public void testReadLong() {\n    Assertions.assertEquals(0, instance.readLong());\n  }\n\n  @Test\n  public void testGetIndex() {\n    Assertions.assertEquals(0, instance.getIndex());\n  }\n\n  @Test\n  public void testReadString() {\n    Assertions.assertNotNull(instance.readString());\n  }\n}\n"
  },
  {
    "path": "foundations/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>foundations</artifactId>\n  <name>Java Chassis::Foundations</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>foundation-spi</module>\n    <module>foundation-vertx</module>\n    <module>foundation-common</module>\n    <module>foundation-config</module>\n    <module>foundation-metrics</module>\n    <module>foundation-ssl</module>\n    <module>foundation-test-scaffolding</module>\n    <module>foundation-protobuf</module>\n    <module>foundation-registry</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "governance/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>servicecomb-governance</artifactId>\n  <name>Java Chassis::Governance</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.github.resilience4j</groupId>\n      <artifactId>resilience4j-all</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.github.resilience4j</groupId>\n      <artifactId>resilience4j-micrometer</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.micrometer</groupId>\n      <artifactId>micrometer-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-beans</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-context</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.yaml</groupId>\n      <artifactId>snakeyaml</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>failureaccess</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-test</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-test</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.micrometer</groupId>\n      <artifactId>micrometer-registry-prometheus</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/GovernanceCommonConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.governance.handler.BulkheadHandler;\nimport org.apache.servicecomb.governance.handler.CircuitBreakerHandler;\nimport org.apache.servicecomb.governance.handler.FaultInjectionHandler;\nimport org.apache.servicecomb.governance.handler.GovernanceCacheHandler;\nimport org.apache.servicecomb.governance.handler.IdentifierRateLimitingHandler;\nimport org.apache.servicecomb.governance.handler.InstanceBulkheadHandler;\nimport org.apache.servicecomb.governance.handler.InstanceIsolationHandler;\nimport org.apache.servicecomb.governance.handler.LoadBalanceHandler;\nimport org.apache.servicecomb.governance.handler.MapperHandler;\nimport org.apache.servicecomb.governance.handler.RateLimitingHandler;\nimport org.apache.servicecomb.governance.handler.RetryHandler;\nimport org.apache.servicecomb.governance.handler.TimeLimiterHandler;\nimport org.apache.servicecomb.governance.handler.ext.AbstractCircuitBreakerExtension;\nimport org.apache.servicecomb.governance.handler.ext.AbstractInstanceIsolationExtension;\nimport org.apache.servicecomb.governance.handler.ext.AbstractRetryExtension;\nimport org.apache.servicecomb.governance.marker.RequestProcessor;\nimport org.apache.servicecomb.governance.marker.operator.CompareOperator;\nimport org.apache.servicecomb.governance.marker.operator.ContainsOperator;\nimport org.apache.servicecomb.governance.marker.operator.ExactOperator;\nimport org.apache.servicecomb.governance.marker.operator.MatchOperator;\nimport org.apache.servicecomb.governance.marker.operator.PrefixOperator;\nimport org.apache.servicecomb.governance.marker.operator.SuffixOperator;\nimport org.apache.servicecomb.governance.properties.BulkheadProperties;\nimport org.apache.servicecomb.governance.properties.CircuitBreakerProperties;\nimport org.apache.servicecomb.governance.properties.FaultInjectionProperties;\nimport org.apache.servicecomb.governance.properties.GovernanceCacheProperties;\nimport org.apache.servicecomb.governance.properties.IdentifierRateLimitProperties;\nimport org.apache.servicecomb.governance.properties.InstanceBulkheadProperties;\nimport org.apache.servicecomb.governance.properties.InstanceIsolationProperties;\nimport org.apache.servicecomb.governance.properties.LoadBalanceProperties;\nimport org.apache.servicecomb.governance.properties.MapperProperties;\nimport org.apache.servicecomb.governance.properties.MatchProperties;\nimport org.apache.servicecomb.governance.properties.RateLimitProperties;\nimport org.apache.servicecomb.governance.properties.RetryProperties;\nimport org.apache.servicecomb.governance.properties.TimeLimiterProperties;\nimport org.apache.servicecomb.governance.service.MatchersService;\nimport org.apache.servicecomb.governance.service.MatchersServiceImpl;\nimport org.springframework.beans.factory.ObjectProvider;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\n@Configuration\npublic class GovernanceCommonConfiguration {\n  // properties configuration\n  @Bean\n  public BulkheadProperties scbBulkheadProperties() {\n    return new BulkheadProperties();\n  }\n\n  @Bean\n  public InstanceBulkheadProperties scbInstanceBulkheadProperties() {\n    return new InstanceBulkheadProperties();\n  }\n\n  @Bean\n  public CircuitBreakerProperties scbCircuitBreakerProperties() {\n    return new CircuitBreakerProperties();\n  }\n\n  @Bean\n  public InstanceIsolationProperties scbInstanceIsolationProperties() {\n    return new InstanceIsolationProperties();\n  }\n\n  @Bean\n  public MatchProperties scbMatchProperties() {\n    return new MatchProperties();\n  }\n\n  @Bean\n  public RateLimitProperties scbRateLimitProperties() {\n    return new RateLimitProperties();\n  }\n\n  @Bean\n  public IdentifierRateLimitProperties scbIdentifierRateLimitProperties() {\n    return new IdentifierRateLimitProperties();\n  }\n\n  @Bean\n  public RetryProperties scbRetryProperties() {\n    return new RetryProperties();\n  }\n\n  @Bean\n  public TimeLimiterProperties scbTimeLimiterProperties() {\n    return new TimeLimiterProperties();\n  }\n\n  @Bean\n  public GovernanceCacheProperties scbCacheProperties() {\n    return new GovernanceCacheProperties();\n  }\n\n  @Bean\n  public FaultInjectionProperties scbFaultInjectionProperties() {\n    return new FaultInjectionProperties();\n  }\n\n  @Bean\n  public LoadBalanceProperties scbLoadBalanceProperties() {\n    return new LoadBalanceProperties();\n  }\n\n  @Bean\n  public MapperProperties scbMapperProperties() {\n    return new MapperProperties();\n  }\n\n  // handlers configuration\n  @Bean\n  public BulkheadHandler scbBulkheadHandler(BulkheadProperties scbBulkheadProperties) {\n    return new BulkheadHandler(scbBulkheadProperties);\n  }\n\n  @Bean\n  public InstanceBulkheadHandler scbInstanceBulkheadHandler(InstanceBulkheadProperties scbInstanceBulkheadProperties) {\n    return new InstanceBulkheadHandler(scbInstanceBulkheadProperties);\n  }\n\n  @Bean\n  public LoadBalanceHandler scbLoadBalanceHandler(LoadBalanceProperties loadBalanceProperties) {\n    return new LoadBalanceHandler(loadBalanceProperties);\n  }\n\n  @Bean\n  public CircuitBreakerHandler scbCircuitBreakerHandler(CircuitBreakerProperties scbCircuitBreakerProperties,\n      AbstractCircuitBreakerExtension circuitBreakerExtension) {\n    return new CircuitBreakerHandler(scbCircuitBreakerProperties, circuitBreakerExtension);\n  }\n\n  @Bean\n  public InstanceIsolationHandler scbInstanceIsolationHandler(InstanceIsolationProperties scbInstanceIsolationProperties,\n      AbstractInstanceIsolationExtension isolationExtension,\n      ObjectProvider<MeterRegistry> meterRegistry) {\n    return new InstanceIsolationHandler(scbInstanceIsolationProperties, isolationExtension, meterRegistry);\n  }\n\n  @Bean\n  public RateLimitingHandler scbRateLimitingHandler(RateLimitProperties rateLimitProperties) {\n    return new RateLimitingHandler(rateLimitProperties);\n  }\n\n  @Bean\n  public IdentifierRateLimitingHandler scbIdentifierRateLimitingHandler(\n      IdentifierRateLimitProperties identifierRateLimitProperties) {\n    return new IdentifierRateLimitingHandler(identifierRateLimitProperties);\n  }\n\n  @Bean\n  public RetryHandler scbRetryHandler(RetryProperties retryProperties, AbstractRetryExtension retryExtension) {\n    return new RetryHandler(retryProperties, retryExtension);\n  }\n\n  @Bean\n  public TimeLimiterHandler scbTimeLimiterHandler(TimeLimiterProperties timeLimiterProperties) {\n    return new TimeLimiterHandler(timeLimiterProperties);\n  }\n\n  @Bean\n  public GovernanceCacheHandler<String, Object> scbGovernanceCacheHandler(GovernanceCacheProperties cacheProperties) {\n    return new GovernanceCacheHandler<String, Object>(cacheProperties);\n  }\n\n  @Bean\n  public FaultInjectionHandler scbFaultInjectionHandler(FaultInjectionProperties scbFaultInjectionProperties) {\n    return new FaultInjectionHandler(scbFaultInjectionProperties);\n  }\n\n  @Bean\n  public MapperHandler scbMapperHandler(MapperProperties scbMapperProperties) {\n    return new MapperHandler(scbMapperProperties);\n  }\n\n  // request processor\n  @Bean\n  public RequestProcessor scbRequestProcessor(Map<String, MatchOperator> operatorMap) {\n    return new RequestProcessor(operatorMap);\n  }\n\n  // matchers\n  @Bean\n  public MatchersService scbMatchersService(RequestProcessor requestProcessor, MatchProperties scbMatchProperties) {\n    return new MatchersServiceImpl(requestProcessor, scbMatchProperties);\n  }\n\n  @Bean\n  public MatchersManager scbMatchersManager(MatchersService matchersService) {\n    return new MatchersManager(matchersService);\n  }\n\n  // operators\n  @Bean\n  public CompareOperator scbCompareOperator() {\n    return new CompareOperator();\n  }\n\n  @Bean\n  public ContainsOperator scbContainsOperator() {\n    return new ContainsOperator();\n  }\n\n  @Bean\n  public ExactOperator scbExactOperator() {\n    return new ExactOperator();\n  }\n\n  @Bean\n  public PrefixOperator scbPrefixOperator() {\n    return new PrefixOperator();\n  }\n\n  @Bean\n  public SuffixOperator scbSuffixOperator() {\n    return new SuffixOperator();\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/MatchersManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.AbstractPolicy;\nimport org.apache.servicecomb.governance.service.MatchersService;\n\npublic class MatchersManager {\n  private MatchersService matchersService;\n\n  public MatchersManager(MatchersService matchersService) {\n    this.matchersService = matchersService;\n  }\n\n  public <T extends AbstractPolicy> T match(GovernanceRequestExtractor requestExtractor, Map<String, T> policies) {\n    List<T> sortPolicies = new ArrayList<>(policies.size());\n    sortPolicies.addAll(policies.values());\n    sortPolicies.sort(T::compareTo);\n\n    for (T policy : sortPolicies) {\n      if (matchersService.checkMatch(requestExtractor, policy.getName())) {\n        return policy;\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/MicroserviceMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\npublic interface MicroserviceMeta {\n  String getName();\n\n  String getVersion();\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/entity/Configurable.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.entity;\n\n/**\n * Indicates a object can be configure in configuration file or config center.\n */\npublic abstract class Configurable {\n  protected String name;\n\n  protected String services;\n\n  public abstract boolean isValid();\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getServices() {\n    return this.services;\n  }\n\n  public void setServices(String services) {\n    this.services = services;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/event/GovernanceConfigurationChangedEvent.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.event;\n\nimport java.util.Set;\n\npublic class GovernanceConfigurationChangedEvent {\n  private final Set<String> changedConfigurations;\n\n  public GovernanceConfigurationChangedEvent(Set<String> changedConfigurations) {\n    this.changedConfigurations = changedConfigurations;\n  }\n\n  public Set<String> getChangedConfigurations() {\n    return changedConfigurations;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/event/GovernanceEventManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.event;\n\nimport com.google.common.eventbus.EventBus;\n\npublic class GovernanceEventManager {\n  private static final EventBus eventBus = new EventBus();\n\n  public static EventBus getEventBus() {\n    return eventBus;\n  }\n\n  public static void post(Object event) {\n    eventBus.post(event);\n  }\n\n  public static void register(Object subscriber) {\n    eventBus.register(subscriber);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/exception/IllegalArgsOperatorException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.exception;\n\npublic class IllegalArgsOperatorException extends RuntimeException {\n  private static final long serialVersionUID = 793575987576638624L;\n\n  public IllegalArgsOperatorException(String message) {\n    super(message);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/AbstractGovernanceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport org.apache.servicecomb.governance.MatchersManager;\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.AbstractPolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.eventbus.Subscribe;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic abstract class AbstractGovernanceHandler<PROCESSOR, POLICY extends AbstractPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGovernanceHandler.class);\n\n  protected final DisposableMap<PROCESSOR> processors;\n\n  private final Object lock = new Object();\n\n  protected MatchersManager matchersManager;\n\n  protected MeterRegistry meterRegistry;\n\n  protected AbstractGovernanceHandler() {\n    GovernanceEventManager.register(this);\n    processors = new DisposableMap<>(this::onConfigurationChanged);\n  }\n\n  @Autowired\n  public void setMatchersManager(MatchersManager matchersManager) {\n    this.matchersManager = matchersManager;\n  }\n\n  @Autowired(required = false)\n  public void setMeterRegistry(MeterRegistry meterRegistry) {\n    this.meterRegistry = meterRegistry;\n  }\n\n  public PROCESSOR getActuator(GovernanceRequestExtractor requestExtractor) {\n    POLICY policy = matchPolicy(requestExtractor);\n    if (policy == null) {\n      return null;\n    }\n\n    String key = createKey(requestExtractor, policy);\n    if (key == null) {\n      return null;\n    }\n\n    Disposable<PROCESSOR> processor = processors.get(key);\n    if (processor == null) {\n      synchronized (lock) {\n        processor = processors.get(key);\n        if (processor == null) {\n          processor = createProcessor(key, requestExtractor, policy);\n          processors.put(key, processor);\n        }\n      }\n    }\n\n    return processor.get();\n  }\n\n  protected abstract String createKey(GovernanceRequestExtractor requestExtractor, POLICY policy);\n\n  protected abstract POLICY matchPolicy(GovernanceRequestExtractor requestExtractor);\n\n  protected abstract Disposable<PROCESSOR> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      POLICY policy);\n\n  protected void onConfigurationChanged(String key) {\n    Disposable<PROCESSOR> processor = processors.remove(key);\n    if (processor != null) {\n      LOGGER.info(\"remove governance processor {}\", key);\n      processor.dispose();\n    }\n  }\n\n  @Subscribe\n  public void onDynamicConfigurationListener(GovernanceConfigurationChangedEvent event) {\n    event.getChangedConfigurations().forEach(this::onConfigurationChanged);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/BulkheadHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.BulkheadPolicy;\nimport org.apache.servicecomb.governance.properties.BulkheadProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.bulkhead.Bulkhead;\nimport io.github.resilience4j.bulkhead.BulkheadConfig;\nimport io.github.resilience4j.bulkhead.BulkheadRegistry;\nimport io.github.resilience4j.micrometer.tagged.BulkheadMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedBulkheadMetrics;\n\npublic class BulkheadHandler extends AbstractGovernanceHandler<Bulkhead, BulkheadPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(BulkheadHandler.class);\n\n  private final BulkheadProperties bulkheadProperties;\n\n  public BulkheadHandler(BulkheadProperties bulkheadProperties) {\n    this.bulkheadProperties = bulkheadProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, BulkheadPolicy policy) {\n    return bulkheadProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public BulkheadPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, bulkheadProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<Bulkhead> createProcessor(String key, GovernanceRequestExtractor requestExtractor, BulkheadPolicy policy) {\n    return getBulkhead(key, policy);\n  }\n\n  private Disposable<Bulkhead> getBulkhead(String key, BulkheadPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n\n    BulkheadConfig config = BulkheadConfig.custom()\n        .maxConcurrentCalls(policy.getMaxConcurrentCalls())\n        .maxWaitDuration(Duration.parse(policy.getMaxWaitDuration()))\n        .build();\n\n    BulkheadRegistry registry = BulkheadRegistry.of(config);\n    if (meterRegistry != null) {\n      TaggedBulkheadMetrics\n          .ofBulkheadRegistry(BulkheadMetricNames.custom()\n              .availableConcurrentCallsMetricName(bulkheadProperties.getConfigKey() + \".available.concurrent.calls\")\n              .maxAllowedConcurrentCallsMetricName(\n                  bulkheadProperties.getConfigKey() + \".max.allowed.concurrent.calls\").build(), registry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableBulkhead(key, registry, registry.bulkhead(key));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/CircuitBreakerHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractCircuitBreakerExtension;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;\nimport org.apache.servicecomb.governance.properties.CircuitBreakerProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.circuitbreaker.CircuitBreaker;\nimport io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;\nimport io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;\nimport io.github.resilience4j.micrometer.tagged.CircuitBreakerMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics;\n\npublic class CircuitBreakerHandler extends AbstractGovernanceHandler<CircuitBreaker, CircuitBreakerPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(CircuitBreakerHandler.class);\n\n  private final CircuitBreakerProperties circuitBreakerProperties;\n\n  private final AbstractCircuitBreakerExtension circuitBreakerExtension;\n\n  public CircuitBreakerHandler(CircuitBreakerProperties circuitBreakerProperties,\n      AbstractCircuitBreakerExtension circuitBreakerExtension) {\n    this.circuitBreakerProperties = circuitBreakerProperties;\n    this.circuitBreakerExtension = circuitBreakerExtension;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, CircuitBreakerPolicy policy) {\n    return this.circuitBreakerProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public CircuitBreakerPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, circuitBreakerProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<CircuitBreaker> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      CircuitBreakerPolicy policy) {\n    return getCircuitBreaker(key, policy);\n  }\n\n  private Disposable<CircuitBreaker> getCircuitBreaker(String key, CircuitBreakerPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy);\n\n    CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()\n        .failureRateThreshold(policy.getFailureRateThreshold())\n        .slowCallRateThreshold(policy.getSlowCallRateThreshold())\n        .waitDurationInOpenState(Duration.parse(policy.getWaitDurationInOpenState()))\n        .slowCallDurationThreshold(Duration.parse(policy.getSlowCallDurationThreshold()))\n        .permittedNumberOfCallsInHalfOpenState(policy.getPermittedNumberOfCallsInHalfOpenState())\n        .minimumNumberOfCalls(policy.getMinimumNumberOfCalls())\n        .slidingWindowType(policy.getSlidingWindowTypeEnum())\n        .slidingWindowSize(Integer.parseInt(policy.getSlidingWindowSize()))\n        .recordException(e -> circuitBreakerExtension.isFailedResult(policy.getRecordFailureStatus(), e))\n        .recordResult(r -> circuitBreakerExtension.isFailedResult(policy.getRecordFailureStatus(), r))\n        .build();\n    CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig);\n    if (meterRegistry != null) {\n      TaggedCircuitBreakerMetrics\n          .ofCircuitBreakerRegistry(CircuitBreakerMetricNames.custom()\n              .callsMetricName(this.circuitBreakerProperties.getConfigKey() + \".calls\")\n              .notPermittedCallsMetricName(this.circuitBreakerProperties.getConfigKey() + \".not.permitted.calls\")\n              .stateMetricName(this.circuitBreakerProperties.getConfigKey() + \".state\")\n              .bufferedCallsMetricName(this.circuitBreakerProperties.getConfigKey() + \".buffered.calls\")\n              .slowCallsMetricName(this.circuitBreakerProperties.getConfigKey() + \".slow.calls\")\n              .failureRateMetricName(this.circuitBreakerProperties.getConfigKey() + \".failure.rate\")\n              .slowCallRateMetricName(this.circuitBreakerProperties.getConfigKey() + \".slow.call.rate\")\n              .build(), circuitBreakerRegistry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableCircuitBreaker(key, circuitBreakerRegistry,\n        circuitBreakerRegistry.circuitBreaker(key, circuitBreakerConfig));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/Disposable.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\npublic abstract class Disposable<V> {\n  private long lastAccessed;\n\n  protected Disposable() {\n    lastAccessed = System.currentTimeMillis();\n  }\n\n  public abstract void dispose();\n\n  public V get() {\n    lastAccessed = System.currentTimeMillis();\n    return getValue();\n  }\n\n  public abstract V getValue();\n\n  public abstract String getKey();\n\n  public long lastAccessed() {\n    return lastAccessed;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableBulkhead.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport io.github.resilience4j.bulkhead.Bulkhead;\nimport io.github.resilience4j.bulkhead.BulkheadRegistry;\n\npublic class DisposableBulkhead extends Disposable<Bulkhead> {\n  private final String key;\n\n  private final BulkheadRegistry bulkheadRegistry;\n\n  private final Bulkhead bulkhead;\n\n  public DisposableBulkhead(String key, BulkheadRegistry bulkheadRegistry,\n      Bulkhead bulkhead) {\n    this.key = key;\n    this.bulkheadRegistry = bulkheadRegistry;\n    this.bulkhead = bulkhead;\n  }\n\n  @Override\n  public void dispose() {\n    bulkheadRegistry.remove(key);\n  }\n\n  @Override\n  public Bulkhead getValue() {\n    return bulkhead;\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableCircuitBreaker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport io.github.resilience4j.circuitbreaker.CircuitBreaker;\nimport io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;\n\npublic class DisposableCircuitBreaker extends Disposable<CircuitBreaker> {\n  private final CircuitBreaker circuitBreaker;\n\n  private final CircuitBreakerRegistry circuitBreakerRegistry;\n\n  private final String key;\n\n  public DisposableCircuitBreaker(String key, CircuitBreakerRegistry registry, CircuitBreaker circuitBreaker) {\n    this.key = key;\n    this.circuitBreaker = circuitBreaker;\n    this.circuitBreakerRegistry = registry;\n  }\n\n  @Override\n  public void dispose() {\n    this.circuitBreakerRegistry.remove(key);\n  }\n\n  @Override\n  public CircuitBreaker getValue() {\n    return circuitBreaker;\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableHolder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\npublic class DisposableHolder<E> extends Disposable<E> {\n  private final E e;\n\n  private final String key;\n\n  public DisposableHolder(String key, E e) {\n    this.key = key;\n    this.e = e;\n  }\n\n  @Override\n  public void dispose() {\n\n  }\n\n  @Override\n  public E getValue() {\n    return e;\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableMap.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * check if some items are expired when put new item to map and remove expired items.\n */\npublic class DisposableMap<V> extends ConcurrentHashMap<String, Disposable<V>> {\n  private static final long serialVersionUID = 7249069246763182397L;\n\n  public interface RemoveListener {\n    void onRemoveEntry(String k);\n  }\n\n  private static final int EXPIRE_TIME = 10 * 60 * 1000;\n\n  private final RemoveListener listener;\n\n  public DisposableMap(RemoveListener listener) {\n    this.listener = listener;\n  }\n\n  @Override\n  public Disposable<V> put(String key, Disposable<V> value) {\n    Disposable<V> result = super.put(key, value);\n\n    checkExpired();\n\n    return result;\n  }\n\n  private void checkExpired() {\n    List<String> expired = new ArrayList<>();\n    this.values().forEach(v -> {\n      if (System.currentTimeMillis() - v.lastAccessed() >= EXPIRE_TIME) {\n        expired.add(v.getKey());\n      }\n    });\n    expired.forEach(listener::onRemoveEntry);\n  }\n\n  @Override\n  public Disposable<V> get(Object key) {\n    return super.get(key);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableRateLimiter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport io.github.resilience4j.ratelimiter.RateLimiter;\nimport io.github.resilience4j.ratelimiter.RateLimiterRegistry;\n\npublic class DisposableRateLimiter extends Disposable<RateLimiter> {\n  private final String key;\n\n  private final RateLimiter rateLimiter;\n\n  private final RateLimiterRegistry registry;\n\n  public DisposableRateLimiter(String key, RateLimiter rateLimiter,\n      RateLimiterRegistry registry) {\n    this.key = key;\n    this.rateLimiter = rateLimiter;\n    this.registry = registry;\n  }\n\n  @Override\n  public void dispose() {\n    registry.remove(key);\n  }\n\n  @Override\n  public RateLimiter getValue() {\n    return rateLimiter;\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableRetry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport io.github.resilience4j.retry.Retry;\nimport io.github.resilience4j.retry.RetryRegistry;\n\npublic class DisposableRetry extends Disposable<Retry> {\n  private final String key;\n\n  private final RetryRegistry registry;\n\n  private final Retry retry;\n\n  public DisposableRetry(String key, RetryRegistry registry, Retry retry) {\n    this.key = key;\n    this.registry = registry;\n    this.retry = retry;\n  }\n\n  @Override\n  public void dispose() {\n    registry.remove(key);\n  }\n\n  @Override\n  public Retry getValue() {\n    return retry;\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/DisposableTimeLimiter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport io.github.resilience4j.timelimiter.TimeLimiter;\nimport io.github.resilience4j.timelimiter.TimeLimiterRegistry;\n\npublic class DisposableTimeLimiter extends Disposable<TimeLimiter> {\n  private final String key;\n\n  private final TimeLimiterRegistry timeLimiterRegistry;\n\n  private final TimeLimiter timeLimiter;\n\n  public DisposableTimeLimiter(String key, TimeLimiterRegistry registry, TimeLimiter timeLimiter) {\n    this.key = key;\n    this.timeLimiterRegistry = registry;\n    this.timeLimiter = timeLimiter;\n  }\n\n  @Override\n  public void dispose() {\n    timeLimiterRegistry.remove(key);\n  }\n\n  @Override\n  public TimeLimiter getValue() {\n    return timeLimiter;\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/FaultInjectionHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\nimport org.apache.servicecomb.governance.processor.injection.Fault;\nimport org.apache.servicecomb.governance.processor.injection.FaultInjectionUtil;\nimport org.apache.servicecomb.governance.properties.FaultInjectionProperties;\n\npublic class FaultInjectionHandler extends AbstractGovernanceHandler<Fault, FaultInjectionPolicy> {\n\n  private final FaultInjectionProperties faultInjectionProperties;\n\n  public FaultInjectionHandler(FaultInjectionProperties faultInjectionProperties) {\n    this.faultInjectionProperties = faultInjectionProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, FaultInjectionPolicy policy) {\n    return FaultInjectionProperties.MATCH_FAULT_INJECTION_KEY + \".\" + policy.getName();\n  }\n\n  @Override\n  public FaultInjectionPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, faultInjectionProperties.getParsedEntity());\n  }\n\n  @Override\n  protected DisposableHolder<Fault> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      FaultInjectionPolicy policy) {\n    return new DisposableHolder<>(key, FaultInjectionUtil.getFault(key, policy));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/GovernanceCacheHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.GovernanceCachePolicy;\nimport org.apache.servicecomb.governance.properties.GovernanceCacheProperties;\nimport org.apache.servicecomb.governance.service.GovernanceCache;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.cache.Cache;\nimport com.google.common.cache.CacheBuilder;\n\npublic class GovernanceCacheHandler<K, V>\n    extends AbstractGovernanceHandler<GovernanceCache<K, V>, GovernanceCachePolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(GovernanceCacheHandler.class);\n\n  private final GovernanceCacheProperties cacheProperties;\n\n  public GovernanceCacheHandler(GovernanceCacheProperties cacheProperties) {\n    this.cacheProperties = cacheProperties;\n  }\n\n  @Override\n  public GovernanceCachePolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, cacheProperties.getParsedEntity());\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, GovernanceCachePolicy policy) {\n    return cacheProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  protected Disposable<GovernanceCache<K, V>> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      GovernanceCachePolicy policy) {\n    return getGovernanceCache(key, policy);\n  }\n\n  protected Disposable<GovernanceCache<K, V>> getGovernanceCache(String key, GovernanceCachePolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n    Cache<K,\n        V> cache = CacheBuilder.newBuilder()\n        .expireAfterWrite(Duration.parse(policy.getTtl()))\n        .maximumSize(policy.getMaximumSize())\n        .concurrencyLevel(policy.getConcurrencyLevel())\n        .build();\n    GovernanceCache<K, V> governanceCache = GovernanceCache.of(cache);\n    return new DisposableHolder<>(key, governanceCache);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/IdentifierRateLimitingHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.IdentifierRateLimitingPolicy;\nimport org.apache.servicecomb.governance.properties.IdentifierRateLimitProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.micrometer.tagged.RateLimiterMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedRateLimiterMetrics;\nimport io.github.resilience4j.ratelimiter.RateLimiter;\nimport io.github.resilience4j.ratelimiter.RateLimiterConfig;\nimport io.github.resilience4j.ratelimiter.RateLimiterRegistry;\n\npublic class IdentifierRateLimitingHandler extends\n    AbstractGovernanceHandler<RateLimiter, IdentifierRateLimitingPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(IdentifierRateLimitingHandler.class);\n\n  private final IdentifierRateLimitProperties rateLimitProperties;\n\n  public IdentifierRateLimitingHandler(IdentifierRateLimitProperties rateLimitProperties) {\n    this.rateLimitProperties = rateLimitProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, IdentifierRateLimitingPolicy policy) {\n    if (StringUtils.isEmpty(policy.getIdentifier()) ||\n        StringUtils.isEmpty(requestExtractor.header(policy.getIdentifier()))) {\n      LOGGER.info(\"identifier rate limiting is not properly configured, identifier is empty.\");\n      return null;\n    }\n    return this.rateLimitProperties.getConfigKey()\n        + \".\" + policy.getName()\n        + \".\" + requestExtractor.header(policy.getIdentifier());\n  }\n\n  @Override\n  protected void onConfigurationChanged(String key) {\n    if (key.startsWith(this.rateLimitProperties.getConfigKey())) {\n      for (String processorKey : processors.keySet()) {\n        if (processorKey.startsWith(key)) {\n          Disposable<RateLimiter> processor = processors.remove(processorKey);\n          if (processor != null) {\n            LOGGER.info(\"remove identifier rate limiting processor {}\", key);\n            processor.dispose();\n          }\n        }\n      }\n    }\n  }\n\n  @Override\n  public IdentifierRateLimitingPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, rateLimitProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<RateLimiter> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      IdentifierRateLimitingPolicy policy) {\n    return getRateLimiter(key, policy);\n  }\n\n  private Disposable<RateLimiter> getRateLimiter(String key, IdentifierRateLimitingPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n\n    RateLimiterConfig config = RateLimiterConfig.custom()\n        .limitForPeriod(policy.getRate())\n        .limitRefreshPeriod(Duration.parse(policy.getLimitRefreshPeriod()))\n        .timeoutDuration(Duration.parse(policy.getTimeoutDuration()))\n        .build();\n    RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config);\n    if (meterRegistry != null) {\n      TaggedRateLimiterMetrics\n          .ofRateLimiterRegistry(RateLimiterMetricNames.custom()\n                  .availablePermissionsMetricName(\n                      this.rateLimitProperties.getConfigKey() + \".available.permissions\")\n                  .waitingThreadsMetricName(this.rateLimitProperties.getConfigKey() + \".waiting.threads\")\n                  .build(),\n              rateLimiterRegistry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableRateLimiter(key, rateLimiterRegistry.rateLimiter(key), rateLimiterRegistry);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceBulkheadHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.BulkheadPolicy;\nimport org.apache.servicecomb.governance.properties.InstanceBulkheadProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.bulkhead.Bulkhead;\nimport io.github.resilience4j.bulkhead.BulkheadConfig;\nimport io.github.resilience4j.bulkhead.BulkheadRegistry;\nimport io.github.resilience4j.micrometer.tagged.BulkheadMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedBulkheadMetrics;\n\npublic class InstanceBulkheadHandler extends AbstractGovernanceHandler<Bulkhead, BulkheadPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(InstanceBulkheadHandler.class);\n\n  private final InstanceBulkheadProperties bulkheadProperties;\n\n  public InstanceBulkheadHandler(InstanceBulkheadProperties bulkheadProperties) {\n    this.bulkheadProperties = bulkheadProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, BulkheadPolicy policy) {\n    return this.bulkheadProperties.getConfigKey()\n        + \".\" + policy.getName()\n        + \".\" + requestExtractor.serviceName()\n        + \".\" + requestExtractor.instanceId();\n  }\n\n  @Override\n  protected void onConfigurationChanged(String key) {\n    if (key.startsWith(this.bulkheadProperties.getConfigKey())) {\n      for (String processorKey : processors.keySet()) {\n        if (processorKey.startsWith(key)) {\n          Disposable<Bulkhead> processor = processors.remove(processorKey);\n          if (processor != null) {\n            LOGGER.info(\"remove instance bulkhead processor {}\", key);\n            processor.dispose();\n          }\n        }\n      }\n    }\n  }\n\n  @Override\n  public BulkheadPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    if (StringUtils.isEmpty(requestExtractor.serviceName()) || StringUtils.isEmpty(\n        requestExtractor.instanceId())) {\n      LOGGER.info(\"Instance bulkhead is not properly configured, service id or instance id is empty.\");\n      return null;\n    }\n    return matchersManager.match(requestExtractor, bulkheadProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<Bulkhead> createProcessor(String key, GovernanceRequestExtractor requestExtractor, BulkheadPolicy policy) {\n    return getBulkhead(key, policy);\n  }\n\n  private Disposable<Bulkhead> getBulkhead(String key, BulkheadPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n\n    BulkheadConfig config = BulkheadConfig.custom()\n        .maxConcurrentCalls(policy.getMaxConcurrentCalls())\n        .maxWaitDuration(Duration.parse(policy.getMaxWaitDuration()))\n        .build();\n\n    BulkheadRegistry registry = BulkheadRegistry.of(config);\n    if (meterRegistry != null) {\n      TaggedBulkheadMetrics\n          .ofBulkheadRegistry(BulkheadMetricNames.custom()\n                  .availableConcurrentCallsMetricName(\n                      this.bulkheadProperties.getConfigKey() + \".available.concurrent.calls\")\n                  .maxAllowedConcurrentCallsMetricName(\n                      this.bulkheadProperties.getConfigKey() + \".max.allowed.concurrent.calls\").build(),\n              registry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableBulkhead(key, registry, registry.bulkhead(key, config));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceIsolationHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.handler.ext.AbstractInstanceIsolationExtension;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;\nimport org.apache.servicecomb.governance.properties.InstanceIsolationProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.ObjectProvider;\n\nimport io.github.resilience4j.circuitbreaker.CircuitBreaker;\nimport io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;\nimport io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;\nimport io.github.resilience4j.micrometer.tagged.CircuitBreakerMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics;\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic final class InstanceIsolationHandler extends AbstractGovernanceHandler<CircuitBreaker, CircuitBreakerPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(InstanceIsolationHandler.class);\n\n  private final InstanceIsolationProperties instanceIsolationProperties;\n\n  private final AbstractInstanceIsolationExtension isolationExtension;\n\n  private final MeterRegistry meterRegistry;\n\n  public InstanceIsolationHandler(InstanceIsolationProperties instanceIsolationProperties,\n      AbstractInstanceIsolationExtension isolationExtension,\n      ObjectProvider<MeterRegistry> meterRegistry) {\n    this.instanceIsolationProperties = instanceIsolationProperties;\n    this.isolationExtension = isolationExtension;\n    this.meterRegistry = meterRegistry.getIfAvailable();\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, CircuitBreakerPolicy policy) {\n    return this.instanceIsolationProperties.getConfigKey()\n        + \".\" + policy.getName()\n        + \".\" + requestExtractor.serviceName()\n        + \".\" + requestExtractor.instanceId();\n  }\n\n  @Override\n  protected void onConfigurationChanged(String key) {\n    if (key.startsWith(this.instanceIsolationProperties.getConfigKey())) {\n      for (String processorKey : processors.keySet()) {\n        if (processorKey.startsWith(key)) {\n          Disposable<CircuitBreaker> circuitBreaker = processors.remove(processorKey);\n          if (circuitBreaker != null) {\n            LOGGER.info(\"remove instance isolation processor {}\", key);\n            circuitBreaker.dispose();\n          }\n        }\n      }\n    }\n  }\n\n  @Override\n  public CircuitBreakerPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    if (StringUtils.isEmpty(requestExtractor.serviceName()) || StringUtils.isEmpty(\n        requestExtractor.instanceId())) {\n      LOGGER.debug(\"Isolation is not properly configured, service id or instance id is empty.\");\n      return null;\n    }\n    return matchersManager.match(requestExtractor, instanceIsolationProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<CircuitBreaker> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      CircuitBreakerPolicy policy) {\n    return getCircuitBreaker(key, policy);\n  }\n\n  private Disposable<CircuitBreaker> getCircuitBreaker(String key, CircuitBreakerPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n\n    CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()\n        .failureRateThreshold(policy.getFailureRateThreshold())\n        .slowCallRateThreshold(policy.getSlowCallRateThreshold())\n        .waitDurationInOpenState(Duration.parse(policy.getWaitDurationInOpenState()))\n        .slowCallDurationThreshold(Duration.parse(policy.getSlowCallDurationThreshold()))\n        .permittedNumberOfCallsInHalfOpenState(policy.getPermittedNumberOfCallsInHalfOpenState())\n        .minimumNumberOfCalls(policy.getMinimumNumberOfCalls())\n        .slidingWindowType(policy.getSlidingWindowTypeEnum())\n        .slidingWindowSize(Integer.parseInt(policy.getSlidingWindowSize()))\n        .recordException(e -> isolationExtension.isFailedResult(policy.getRecordFailureStatus(), e))\n        .recordResult(r -> isolationExtension.isFailedResult(policy.getRecordFailureStatus(), r))\n        .build();\n    CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig);\n    if (meterRegistry != null) {\n      TaggedCircuitBreakerMetrics\n          .ofCircuitBreakerRegistry(CircuitBreakerMetricNames.custom()\n              .callsMetricName(this.instanceIsolationProperties.getConfigKey() + \".calls\")\n              .notPermittedCallsMetricName(\n                  this.instanceIsolationProperties.getConfigKey() + \".not.permitted.calls\")\n              .stateMetricName(this.instanceIsolationProperties.getConfigKey() + \".state\")\n              .bufferedCallsMetricName(this.instanceIsolationProperties.getConfigKey() + \".buffered.calls\")\n              .slowCallsMetricName(this.instanceIsolationProperties.getConfigKey() + \".slow.calls\")\n              .failureRateMetricName(this.instanceIsolationProperties.getConfigKey() + \".failure.rate\")\n              .slowCallRateMetricName(this.instanceIsolationProperties.getConfigKey() + \".slow.call.rate\")\n              .build(), circuitBreakerRegistry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableCircuitBreaker(key, circuitBreakerRegistry,\n        circuitBreakerRegistry.circuitBreaker(key, circuitBreakerConfig));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/LoadBalanceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.LoadBalancerPolicy;\nimport org.apache.servicecomb.governance.processor.loadbanlance.LoadBalance;\nimport org.apache.servicecomb.governance.properties.LoadBalanceProperties;\n\npublic class LoadBalanceHandler extends AbstractGovernanceHandler<LoadBalance, LoadBalancerPolicy> {\n\n  private final LoadBalanceProperties loadBalanceProperties;\n\n  public LoadBalanceHandler(LoadBalanceProperties loadBalanceProperties) {\n    this.loadBalanceProperties = loadBalanceProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, LoadBalancerPolicy policy) {\n    return this.loadBalanceProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public LoadBalancerPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, loadBalanceProperties.getParsedEntity());\n  }\n\n  @Override\n  protected DisposableHolder<LoadBalance> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      LoadBalancerPolicy policy) {\n    return new DisposableHolder<>(key, LoadBalance.getLoadBalance(key, policy));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/MapperHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.MapperPolicy;\nimport org.apache.servicecomb.governance.processor.mapping.Mapper;\nimport org.apache.servicecomb.governance.properties.MapperProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class MapperHandler extends AbstractGovernanceHandler<Mapper, MapperPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RateLimitingHandler.class);\n\n  private final MapperProperties mapperProperties;\n\n  public MapperHandler(MapperProperties mapperProperties) {\n    this.mapperProperties = mapperProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, MapperPolicy policy) {\n    return mapperProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public MapperPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, mapperProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<Mapper> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      MapperPolicy policy) {\n    return getMapper(key, policy);\n  }\n\n  private Disposable<Mapper> getMapper(String key, MapperPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n\n    return new DisposableHolder<>(key, Mapper.create(policy.getTarget()));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/RateLimitingHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.RateLimitingPolicy;\nimport org.apache.servicecomb.governance.properties.RateLimitProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.micrometer.tagged.RateLimiterMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedRateLimiterMetrics;\nimport io.github.resilience4j.ratelimiter.RateLimiter;\nimport io.github.resilience4j.ratelimiter.RateLimiterConfig;\nimport io.github.resilience4j.ratelimiter.RateLimiterRegistry;\n\npublic class RateLimitingHandler extends AbstractGovernanceHandler<RateLimiter, RateLimitingPolicy> {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RateLimitingHandler.class);\n\n  private final RateLimitProperties rateLimitProperties;\n\n  public RateLimitingHandler(RateLimitProperties rateLimitProperties) {\n    this.rateLimitProperties = rateLimitProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, RateLimitingPolicy policy) {\n    return this.rateLimitProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public RateLimitingPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, rateLimitProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<RateLimiter> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      RateLimitingPolicy policy) {\n    return getRateLimiter(key, policy);\n  }\n\n  private Disposable<RateLimiter> getRateLimiter(String key, RateLimitingPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy.toString());\n\n    RateLimiterConfig config = RateLimiterConfig.custom()\n        .limitForPeriod(policy.getRate())\n        .limitRefreshPeriod(Duration.parse(policy.getLimitRefreshPeriod()))\n        .timeoutDuration(Duration.parse(policy.getTimeoutDuration()))\n        .build();\n    RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config);\n    if (meterRegistry != null) {\n      TaggedRateLimiterMetrics\n          .ofRateLimiterRegistry(RateLimiterMetricNames.custom()\n                  .availablePermissionsMetricName(\n                      this.rateLimitProperties.getConfigKey() + \".available.permissions\")\n                  .waitingThreadsMetricName(this.rateLimitProperties.getConfigKey() + \".waiting.threads\")\n                  .build(),\n              rateLimiterRegistry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableRateLimiter(key, rateLimiterRegistry.rateLimiter(key), rateLimiterRegistry);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/RetryHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractRetryExtension;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.RetryPolicy;\nimport org.apache.servicecomb.governance.properties.RetryProperties;\nimport org.apache.servicecomb.governance.utils.GovernanceUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.core.IntervalFunction;\nimport io.github.resilience4j.micrometer.tagged.RetryMetricNames;\nimport io.github.resilience4j.micrometer.tagged.TaggedRetryMetrics;\nimport io.github.resilience4j.retry.Retry;\nimport io.github.resilience4j.retry.RetryConfig;\nimport io.github.resilience4j.retry.RetryRegistry;\n\npublic class RetryHandler extends AbstractGovernanceHandler<Retry, RetryPolicy> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(RetryHandler.class);\n\n  private final RetryProperties retryProperties;\n\n  private final AbstractRetryExtension retryExtension;\n\n  public RetryHandler(RetryProperties retryProperties, AbstractRetryExtension retryExtension) {\n    this.retryProperties = retryProperties;\n    this.retryExtension = retryExtension;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, RetryPolicy policy) {\n    return this.retryProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public RetryPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, retryProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<Retry> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      RetryPolicy policy) {\n    return getRetry(key, policy);\n  }\n\n  private Disposable<Retry> getRetry(String key, RetryPolicy retryPolicy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, retryPolicy.toString());\n\n    RetryConfig config = RetryConfig.custom()\n        .maxAttempts(retryPolicy.getMaxAttempts() + 1)\n        .retryOnResult(response -> retryExtension.isFailedResult(retryPolicy.getRetryOnResponseStatus(), response))\n        .retryOnException(exception -> retryExtension.isFailedResult(retryPolicy.getRetryOnResponseStatus(), exception))\n        .intervalFunction(getIntervalFunction(retryPolicy))\n        .failAfterMaxAttempts(retryPolicy.isFailAfterMaxAttempts())\n        .build();\n\n    RetryRegistry registry = RetryRegistry.of(config);\n    if (meterRegistry != null) {\n      TaggedRetryMetrics\n          .ofRetryRegistry(RetryMetricNames.custom()\n                  .callsMetricName(this.retryProperties.getConfigKey() + \".calls\")\n                  .build(),\n              registry)\n          .bindTo(meterRegistry);\n    }\n    return new DisposableRetry(key, registry, registry.retry(key));\n  }\n\n  private IntervalFunction getIntervalFunction(RetryPolicy retryPolicy) {\n    if (GovernanceUtils.STRATEGY_RANDOM_BACKOFF.equals(retryPolicy.getRetryStrategy())) {\n      return IntervalFunction.ofExponentialRandomBackoff(Duration.parse(retryPolicy.getInitialInterval()),\n          retryPolicy.getMultiplier(), retryPolicy.getRandomizationFactor());\n    }\n    return IntervalFunction.of(Duration.parse(retryPolicy.getWaitDuration()));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/TimeLimiterHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.TimeLimiterPolicy;\nimport org.apache.servicecomb.governance.properties.TimeLimiterProperties;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.github.resilience4j.micrometer.tagged.TaggedTimeLimiterMetrics;\nimport io.github.resilience4j.micrometer.tagged.TimeLimiterMetricNames;\nimport io.github.resilience4j.timelimiter.TimeLimiter;\nimport io.github.resilience4j.timelimiter.TimeLimiterConfig;\nimport io.github.resilience4j.timelimiter.TimeLimiterRegistry;\n\npublic class TimeLimiterHandler extends AbstractGovernanceHandler<TimeLimiter, TimeLimiterPolicy> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(TimeLimiterHandler.class);\n\n  private final TimeLimiterProperties timeLimiterProperties;\n\n  public TimeLimiterHandler(TimeLimiterProperties timeLimiterProperties) {\n    this.timeLimiterProperties = timeLimiterProperties;\n  }\n\n  @Override\n  protected String createKey(GovernanceRequestExtractor requestExtractor, TimeLimiterPolicy policy) {\n    return timeLimiterProperties.getConfigKey() + \".\" + policy.getName();\n  }\n\n  @Override\n  public TimeLimiterPolicy matchPolicy(GovernanceRequestExtractor requestExtractor) {\n    return matchersManager.match(requestExtractor, timeLimiterProperties.getParsedEntity());\n  }\n\n  @Override\n  public Disposable<TimeLimiter> createProcessor(String key, GovernanceRequestExtractor requestExtractor,\n      TimeLimiterPolicy policy) {\n    return getTimeLimiter(key, policy);\n  }\n\n  private Disposable<TimeLimiter> getTimeLimiter(String key, TimeLimiterPolicy policy) {\n    LOGGER.info(\"applying new policy {} for {}\", key, policy);\n    TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()\n        .timeoutDuration(Duration.parse(policy.getTimeoutDuration()))\n        .cancelRunningFuture(policy.isCancelRunningFuture())\n        .build();\n    TimeLimiterRegistry timeLimiterRegistry = TimeLimiterRegistry.of(timeLimiterConfig);\n    if (meterRegistry != null) {\n      TaggedTimeLimiterMetrics.ofTimeLimiterRegistry(TimeLimiterMetricNames.custom()\n          .callsMetricName(timeLimiterProperties.getConfigKey() + \".calls\")\n          .build(), timeLimiterRegistry).bindTo(meterRegistry);\n    }\n    return new DisposableTimeLimiter(key, timeLimiterRegistry, timeLimiterRegistry.timeLimiter(key));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/AbstractCircuitBreakerExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler.ext;\n\npublic abstract class AbstractCircuitBreakerExtension extends AbstractFailurePredictor {\n\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/AbstractFailurePredictor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler.ext;\n\nimport java.util.List;\nimport java.util.stream.IntStream;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic abstract class AbstractFailurePredictor implements FailurePredictor {\n  @Override\n  public boolean isFailedResult(List<String> statusList, Object result) {\n    String statusCode = extractStatusCode(result);\n    if (StringUtils.isEmpty(statusCode)) {\n      return false;\n    }\n    return statusCodeContains(statusList, statusCode);\n  }\n\n  protected abstract String extractStatusCode(Object result);\n\n  protected static boolean statusCodeContains(List<String> statusList, String responseStatus) {\n    return statusList.stream().anyMatch(status -> statusCodeMatch(status, responseStatus));\n  }\n\n  private static boolean statusCodeMatch(String status, String responseStatus) {\n    if (status == null) {\n      return false;\n    }\n    if (responseStatus.length() != status.length()) {\n      return false;\n    }\n    char[] statusChar = status.toCharArray();\n    char[] responseChar = responseStatus.toCharArray();\n    return IntStream.range(0, statusChar.length).noneMatch(i ->\n        statusChar[i] != responseChar[i] && statusChar[i] != 'x');\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/AbstractInstanceIsolationExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler.ext;\n\npublic abstract class AbstractInstanceIsolationExtension extends AbstractFailurePredictor {\n\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/AbstractRetryExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler.ext;\n\npublic abstract class AbstractRetryExtension extends AbstractFailurePredictor {\n\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/ClientRecoverPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler.ext;\n\npublic interface ClientRecoverPolicy<T> {\n\n  T apply(Throwable th);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/FailurePredictor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.handler.ext;\n\nimport java.io.IOException;\nimport java.net.ConnectException;\nimport java.net.NoRouteToHostException;\nimport java.net.SocketTimeoutException;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport javax.net.ssl.SSLHandshakeException;\n\nimport com.google.common.collect.ImmutableMap;\n\nimport io.netty.handler.ssl.SslHandshakeTimeoutException;\nimport io.vertx.core.VertxException;\n\npublic interface FailurePredictor {\n  Map<Class<? extends Throwable>, List<String>> STRICT_RETRIABLE =\n      ImmutableMap.<Class<? extends Throwable>, List<String>>builder()\n          .put(ConnectException.class, Collections.emptyList())\n          .put(SocketTimeoutException.class, Collections.emptyList())\n          /*\n           * deal with some special exceptions caused by the server side close the connection\n           */\n          .put(IOException.class, Collections.singletonList(\"Connection reset by peer\"))\n          .put(VertxException.class, Collections.singletonList(\"Connection was closed\"))\n          .put(NoRouteToHostException.class, Collections.emptyList())\n          .put(SSLHandshakeException.class, Collections.emptyList())\n          .put(SslHandshakeTimeoutException.class, Collections.emptyList())\n          .build();\n\n  boolean isFailedResult(List<String> statusList, Object result);\n\n  default boolean isFailedResult(List<String> statusList, Throwable e) {\n    return canRetryForException(STRICT_RETRIABLE, e);\n  }\n\n  static boolean canRetryForException(Map<Class<? extends Throwable>, List<String>> retryList,\n      Throwable throwableToSearchIn) {\n    // retry on exception type on message match\n    int infiniteLoopPreventionCounter = 10;\n    while (throwableToSearchIn != null && infiniteLoopPreventionCounter > 0) {\n      infiniteLoopPreventionCounter--;\n      for (Entry<Class<? extends Throwable>, List<String>> c : retryList.entrySet()) {\n        Class<? extends Throwable> key = c.getKey();\n        if (key.isAssignableFrom(throwableToSearchIn.getClass())) {\n          if (c.getValue() == null || c.getValue().isEmpty()) {\n            return true;\n          } else {\n            String msg = throwableToSearchIn.getMessage();\n            for (String val : c.getValue()) {\n              if (val.equals(msg)) {\n                return true;\n              }\n            }\n          }\n        }\n      }\n      throwableToSearchIn = throwableToSearchIn.getCause();\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/handler/ext/ServerRecoverPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler.ext;\n\npublic interface ServerRecoverPolicy<T> {\n\n  T apply(Throwable th);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/CustomMatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.marker;\n\npublic class CustomMatcher {\n\n    private String customMatcherHandler;\n\n    private String customMatcherParameters;\n\n    public String getCustomMatcherHandler() {\n        return customMatcherHandler;\n    }\n\n    public void setCustomMatcherHandler(String customMatcherHandler) {\n        this.customMatcherHandler = customMatcherHandler;\n    }\n\n    public String getCustomMatcherParameters() {\n        return customMatcherParameters;\n    }\n\n    public void setCustomMatcherParameters(String customMatcherParameters) {\n        this.customMatcherParameters = customMatcherParameters;\n    }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/GovernanceRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker;\n\nimport java.util.Collections;\nimport java.util.Map;\n\nimport org.springframework.util.LinkedCaseInsensitiveMap;\n\npublic class GovernanceRequest implements GovernanceRequestExtractor {\n  /**\n   * headers with this request, maybe null.\n   * For provider: headers indicates the request headers to me.\n   * For consumer: headers indicates the request headers to the target.\n   */\n  private Map<String, String> headers = Collections.emptyMap();\n\n  /**\n   * Queries with this request, maybe null.\n   * For provider: Queries indicates the request params to me.\n   * For consumer: Queries indicates the request params to the target.\n   */\n  private Map<String, String> queries = Collections.emptyMap();\n\n  /**\n   * api path with this request, maybe null. For REST, e.g. /foo/bar; For RPC, e.g. MySchema.sayHello\n   * For provider: uri indicates the request uri to me.\n   * For consumer: uri indicates the request uri to the target.\n   */\n  private String apiPath;\n\n  /**\n   * method with this request, maybe null.\n   * For provider: method indicates the request method to me.\n   * For consumer: method indicates the request method to the target.\n   */\n  private String method;\n\n  /**\n   * instance id with this request, maybe null.\n   * For provider: instanceId indicates who calls me.\n   * For consumer: instanceId indicates the target instance.\n   */\n  private String instanceId;\n\n  /**\n   * microservice id (microservice name or application name + microservice name) with this request, maybe null.\n   * For provider: serviceName indicates who calls me.\n   * For consumer: serviceName indicates the target service.\n   */\n  private String serviceName;\n\n  /**\n   * sourceRequest the source request for creating this governanceRequest\n   * For provider: uri indicates the request to me.\n   * For consumer: uri indicates the request to the target.\n   * the type of sourceRequest could be ClientRequest, ServerWebExchange, HttpRequest, HttpServletRequest and so on,\n   * User will use this request to extract the information he need\n   */\n  private Object sourceRequest;\n\n  @Override\n  public String header(String key) {\n    return headers.get(key);\n  }\n\n  @Override\n  public String query(String key) {\n    return queries.get(key);\n  }\n\n  public Map<String, String> getHeaders() {\n    return headers;\n  }\n\n  public Map<String, String> getQueries() {\n    return queries;\n  }\n\n  public void setHeaders(Map<String, String> headers) {\n    Map<String, String> temp = new LinkedCaseInsensitiveMap<>();\n    temp.putAll(headers);\n    this.headers = temp;\n  }\n\n  public void setQueries(Map<String, String> queries) {\n    Map<String, String> temp = new LinkedCaseInsensitiveMap<>();\n    temp.putAll(queries);\n    this.queries = temp;\n  }\n\n  @Override\n  public String apiPath() {\n    return apiPath;\n  }\n\n  public void setApiPath(String apiPath) {\n    this.apiPath = apiPath;\n  }\n\n  @Override\n  public String method() {\n    return method;\n  }\n\n  public void setMethod(String method) {\n    this.method = method;\n  }\n\n  @Override\n  public String instanceId() {\n    return instanceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  @Override\n  public String serviceName() {\n    return serviceName;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  @Override\n  public Object sourceRequest() {\n    return sourceRequest;\n  }\n\n  public void setSourceRequest(Object sourceRequest) {\n    this.sourceRequest = sourceRequest;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/GovernanceRequestExtractor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker;\n\npublic interface GovernanceRequestExtractor {\n  String apiPath();\n\n  String method();\n\n  String header(String key);\n\n  String query(String key);\n\n  String instanceId();\n\n  String serviceName();\n\n  Object sourceRequest();\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/Matcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.governance.marker.operator.RawOperator;\n\npublic class Matcher {\n  private String name;\n\n  private Map<String, RawOperator> headers;\n\n  private Map<String, RawOperator> queries;\n\n  private RawOperator apiPath;\n\n  private List<String> method;\n\n  private String serviceName;\n\n  private CustomMatcher customMatcher;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public Map<String, RawOperator> getHeaders() {\n    return headers;\n  }\n\n  public void setHeaders(Map<String, RawOperator> headers) {\n    this.headers = headers;\n  }\n\n  public Map<String, RawOperator> getQueries() {\n    return queries;\n  }\n\n  public void setQueries(Map<String, RawOperator> queries) {\n    this.queries = queries;\n  }\n\n  public RawOperator getApiPath() {\n    return apiPath;\n  }\n\n  public void setApiPath(RawOperator apiPath) {\n    this.apiPath = apiPath;\n  }\n\n  public List<String> getMethod() {\n    return method;\n  }\n\n  public void setMethod(List<String> method) {\n    this.method = method;\n  }\n\n  public String getServiceName() {\n    return serviceName;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public CustomMatcher getCustomMatcher() {\n    return customMatcher;\n  }\n\n  public void setCustomMatcher(CustomMatcher customMatcher) {\n    this.customMatcher = customMatcher;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/RequestProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.marker.operator.MatchOperator;\nimport org.apache.servicecomb.governance.marker.operator.RawOperator;\nimport org.apache.servicecomb.governance.utils.CustomMatch;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.support.BeanDefinitionBuilder;\nimport org.springframework.beans.factory.support.BeanDefinitionRegistry;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\n\n/**\n * Request Processor checks if a request matches a configuration.\n */\npublic class RequestProcessor implements ApplicationContextAware {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(RequestProcessor.class);\n\n  public static final String errorMessageForNotImplements = \" didn't implement interface org.apache.servicecomb.governance.utils.CustomMatch\";\n\n  public static final String errorMessageForAbstractClass = \" should be a instantiable class rather than abstract class or other else\";\n\n  public static final String infoMessageForCreatingClass = \"is not in spring container, create one and register it to spring container\";\n\n  private final Map<String, MatchOperator> operatorMap;\n\n  private ApplicationContext applicationContext;\n\n  public RequestProcessor(Map<String, MatchOperator> operatorMap) {\n    this.operatorMap = new HashMap<>(operatorMap.size());\n    operatorMap.forEach((k, v) -> this.operatorMap.put(v.name(), v));\n  }\n\n  public boolean match(GovernanceRequestExtractor request, Matcher matcher) {\n    if (!methodMatch(request, matcher)) {\n      return false;\n    }\n    if (!apiPathMatch(request, matcher)) {\n      return false;\n    }\n    if (!headersMatch(request, matcher)) {\n      return false;\n    }\n    if (!queriesMatch(request, matcher)) {\n      return false;\n    }\n    if (!serviceNameMatch(request, matcher)) {\n      return false;\n    }\n    return customMatch(request, matcher);\n  }\n\n  private boolean serviceNameMatch(GovernanceRequestExtractor request, Matcher matcher) {\n    if (matcher.getServiceName() == null) {\n      return true;\n    }\n    return matcher.getServiceName().equals(request.serviceName());\n  }\n\n  private boolean headersMatch(GovernanceRequestExtractor request, Matcher matcher) {\n    if (matcher.getHeaders() == null) {\n      return true;\n    }\n    for (Entry<String, RawOperator> entry : matcher.getHeaders().entrySet()) {\n      if (request.header(entry.getKey()) == null ||\n          !operatorMatch(request.header(entry.getKey()), entry.getValue())) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private boolean queriesMatch(GovernanceRequestExtractor request, Matcher matcher) {\n    if (matcher.getQueries() == null) {\n      return true;\n    }\n    for (Entry<String, RawOperator> entry : matcher.getQueries().entrySet()) {\n      if (request.query(entry.getKey()) == null ||\n          !operatorMatch(request.query(entry.getKey()), entry.getValue())) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private boolean apiPathMatch(GovernanceRequestExtractor request, Matcher matcher) {\n    if (matcher.getApiPath() == null) {\n      return true;\n    }\n    return operatorMatch(request.apiPath(), matcher.getApiPath());\n  }\n\n  private boolean methodMatch(GovernanceRequestExtractor request, Matcher matcher) {\n    if (matcher.getMethod() == null) {\n      return true;\n    }\n    return matcher.getMethod().contains(request.method());\n  }\n\n  private boolean operatorMatch(String str, RawOperator rawOperator) {\n    if (rawOperator.isEmpty()) {\n      return false;\n    }\n\n    for (Entry<String, String> entry : rawOperator.entrySet()) {\n      MatchOperator operator = operatorMap.get(entry.getKey());\n      if (operator == null) {\n        LOGGER.error(\"unsupported operator:\" + entry.getKey() + \", please use one of :\" + operatorMap.keySet());\n        return false;\n      }\n      if (!operator.match(str, entry.getValue())) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private boolean customMatch(GovernanceRequestExtractor request, Matcher matcher) {\n    if (matcher.getCustomMatcher() == null) {\n      return true;\n    }\n    String customMatcherHandlerName = matcher.getCustomMatcher().getCustomMatcherHandler();\n    String customMatcherParameters = matcher.getCustomMatcher().getCustomMatcherParameters();\n\n    if (StringUtils.isEmpty(customMatcherHandlerName) || StringUtils.isEmpty(customMatcherParameters)) {\n      return true;\n    }\n\n    CustomMatch customMatcherHandler = generateHandler(customMatcherHandlerName);\n    return customMatcherHandler.matchRequest(request, customMatcherParameters);\n  }\n\n  private CustomMatch getBeanByHandlerName(String customMatcherHandler) {\n    Object extractObject = null;\n    if (applicationContext.containsBean(customMatcherHandler)) {\n      extractObject = applicationContext.getBean(customMatcherHandler);\n      if (!(extractObject instanceof CustomMatch)) {\n        LOGGER.error(\"{} {}\", customMatcherHandler, errorMessageForNotImplements);\n        throw new RuntimeException(customMatcherHandler + errorMessageForNotImplements);\n      }\n      return (CustomMatch) extractObject;\n    }\n    return null;\n  }\n\n\n  public CustomMatch generateHandler(String customMatcherHandler) {\n    CustomMatch extractObject = getBeanByHandlerName(customMatcherHandler);\n    if (extractObject != null) {\n      return extractObject;\n    }\n\n    LOGGER.info(\"{} {}\", customMatcherHandler, infoMessageForCreatingClass);\n    Class<?> extractionHandlerClass = null;\n    try {\n      extractionHandlerClass = Class.forName(customMatcherHandler);\n    } catch (ClassNotFoundException e) {\n      LOGGER.error(e.getMessage(), e);\n      throw new RuntimeException(e);\n    }\n\n    if (!CustomMatch.class.isAssignableFrom(extractionHandlerClass)) {\n      LOGGER.error(\"{} {}\", customMatcherHandler, errorMessageForNotImplements);\n      throw new RuntimeException(customMatcherHandler + errorMessageForNotImplements);\n    }\n    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(extractionHandlerClass);\n    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext;\n    registry.registerBeanDefinition(customMatcherHandler, builder.getBeanDefinition());\n    try {\n      extractObject = (CustomMatch) applicationContext.getBean(customMatcherHandler);\n      return extractObject;\n    } catch (BeansException e) {\n      LOGGER.error(e.getMessage(), e);\n      throw new RuntimeException(customMatcherHandler + errorMessageForAbstractClass, e);\n    }\n  }\n\n  @Override\n  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n    this.applicationContext = applicationContext;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/TrafficMarker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.entity.Configurable;\n\npublic class TrafficMarker extends Configurable {\n  private List<Matcher> matches;\n\n  @Override\n  public boolean isValid() {\n    if (matches == null || matches.isEmpty()) {\n      return false;\n    }\n    return true;\n  }\n\n  public List<Matcher> getMatches() {\n    return matches;\n  }\n\n  public void setMatches(List<Matcher> matches) {\n    this.matches = matches;\n  }\n\n  public boolean checkMatch(GovernanceRequestExtractor extractor, RequestProcessor requestProcessor) {\n    return this.matches.stream().anyMatch(match -> requestProcessor.match(extractor, match));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/CompareOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker.operator;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport org.apache.servicecomb.governance.exception.IllegalArgsOperatorException;\n\npublic class CompareOperator implements MatchOperator {\n\n  private final Set<Character> charSet = new HashSet<>();\n\n  public CompareOperator() {\n    charSet.add('>');\n    charSet.add('<');\n    charSet.add('=');\n    charSet.add('!');\n  }\n\n  @Override\n  public String name() {\n    return \"compare\";\n  }\n\n  /**\n   * 支持 {@code > < = >= <= !} 后面加数字\n   *\n   * @param targetStr\n   * @param patternStr\n   * @return\n   */\n  @Override\n  public boolean match(String targetStr, String patternStr) {\n    char[] chars = patternStr.toCharArray();\n    if (isLegalChar(chars[0]) && isLegalChar(chars[1])) {\n      return process(targetStr, patternStr.substring(0, 2), patternStr.substring(2));\n    } else if (isLegalChar(chars[0])) {\n      return process(targetStr, patternStr.substring(0, 1), patternStr.substring(1));\n    } else {\n      throw new IllegalArgsOperatorException(\"operator \" + patternStr + \" is illegal.\");\n    }\n  }\n\n  private boolean process(String targetStr, String charStr, String numStr) {\n    double result;\n    double target;\n    try {\n      target = Double.parseDouble(targetStr);\n      if (numStr.startsWith(\"-\")) {\n        result = -Double.parseDouble(numStr.substring(1));\n      } else {\n        result = Double.parseDouble(numStr);\n      }\n    } catch (NumberFormatException e) {\n      throw new IllegalArgsOperatorException(\"operator \" + charStr + numStr + \" is illegal.\");\n    }\n    switch (charStr) {\n      case \">\":\n        return target > result;\n      case \"<\":\n        return target < result;\n      case \"=\":\n        return doubleEquals(target, result);\n      case \">=\":\n        return target >= result;\n      case \"<=\":\n        return target <= result;\n      case \"!\":\n      case \"!=\":\n        return !doubleEquals(target, result);\n      default:\n        throw new IllegalArgsOperatorException(\"operator \" + charStr + numStr + \" is illegal.\");\n    }\n  }\n\n  private boolean isLegalChar(char c) {\n    return charSet.contains(c);\n  }\n\n  private boolean doubleEquals(double target, double result) {\n    return Math.abs(target - result) < 1e-6;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/ContainsOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker.operator;\n\npublic class ContainsOperator implements MatchOperator {\n\n  @Override\n  public String name() {\n    return \"contains\";\n  }\n\n  @Override\n  public boolean match(String targetStr, String patternStr) {\n    return targetStr.contains(patternStr);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/ExactOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker.operator;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class ExactOperator implements MatchOperator {\n\n  @Override\n  public String name() {\n    return \"exact\";\n  }\n\n  @Override\n  public boolean match(String targetStr, String patternStr) {\n    return StringUtils.equals(targetStr, patternStr);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/MatchOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker.operator;\n\npublic interface MatchOperator {\n  String name();\n\n  boolean match(String targetStr, String patternStr);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/PrefixOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.marker.operator;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class PrefixOperator implements MatchOperator {\n  @Override\n  public String name() {\n    return \"prefix\";\n  }\n\n  @Override\n  public boolean match(String requestValue, String patternValue) {\n    return StringUtils.startsWith(requestValue, patternValue);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/RawOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.marker.operator;\n\nimport java.util.HashMap;\n\npublic class RawOperator extends HashMap<String, String> {\n  private static final long serialVersionUID = 659728839992490564L;\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/marker/operator/SuffixOperator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.marker.operator;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class SuffixOperator implements MatchOperator {\n  @Override\n  public String name() {\n    return \"suffix\";\n  }\n\n  @Override\n  public boolean match(String requestValue, String patternValue) {\n    return StringUtils.endsWith(requestValue, patternValue);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/AbstractPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.entity.Configurable;\nimport org.apache.servicecomb.governance.utils.GovernanceUtils;\n\npublic abstract class AbstractPolicy extends Configurable implements Comparable<AbstractPolicy> {\n  protected int order = 0;\n\n  @Override\n  public boolean isValid() {\n    return !StringUtils.isEmpty(name);\n  }\n\n  @Override\n  public int compareTo(AbstractPolicy o) {\n    return this.order - o.order;\n  }\n\n  public int getOrder() {\n    return order;\n  }\n\n  public void setOrder(int order) {\n    this.order = order;\n  }\n\n  private Duration parseToDuration(String time, Duration defaultValue) {\n    if (StringUtils.isEmpty(time)) {\n      return defaultValue;\n    }\n    if (time.matches(GovernanceUtils.DIGIT_REGEX)) {\n      if (Long.parseLong(time) < 0) {\n        throw new RuntimeException(\"The value of time should not be less than 0.\");\n      }\n      return Duration.ofMillis(Long.parseLong(time));\n    }\n    return Duration.parse(GovernanceUtils.DIGIT_PREFIX + time);\n  }\n\n  public String stringOfDuration(String time, Duration defaultValue) {\n    return parseToDuration(time, defaultValue).toString();\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/BulkheadPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\n\npublic class BulkheadPolicy extends AbstractPolicy {\n\n  public static final int DEFAULT_MAX_CONCURRENT_CALLS = 1000;\n\n  public static final Duration DEFAULT_MAX_WAIT_DURATION = Duration.ofMillis(0);\n\n  private int maxConcurrentCalls = DEFAULT_MAX_CONCURRENT_CALLS;\n\n  private String maxWaitDuration = DEFAULT_MAX_WAIT_DURATION.toString();\n\n  public int getMaxConcurrentCalls() {\n    return maxConcurrentCalls;\n  }\n\n  public void setMaxConcurrentCalls(int maxConcurrentCalls) {\n    this.maxConcurrentCalls = maxConcurrentCalls;\n  }\n\n  public String getMaxWaitDuration() {\n    return maxWaitDuration;\n  }\n\n  public void setMaxWaitDuration(String maxWaitDuration) {\n    this.maxWaitDuration = stringOfDuration(maxWaitDuration, DEFAULT_MAX_WAIT_DURATION);\n  }\n\n  @Override\n  public boolean isValid() {\n    if (maxConcurrentCalls < 0) {\n      return false;\n    }\n    if (Duration.parse(maxWaitDuration).toMillis() < 0) {\n      return false;\n    }\n    return super.isValid();\n  }\n\n  @Override\n  public String toString() {\n    return \"BulkheadPolicy{\" +\n        \"maxConcurrentCalls=\" + maxConcurrentCalls +\n        \", maxWaitDuration=\" + maxWaitDuration +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/CircuitBreakerPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.utils.GovernanceUtils;\nimport org.springframework.util.CollectionUtils;\n\nimport io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.SlidingWindowType;\n\npublic class CircuitBreakerPolicy extends AbstractPolicy {\n\n  public static final float DEFAULT_FAILURE_RATE_THRESHOLD = 50;\n\n  public static final float DEFAULT_SLOW_CALL_RATE_THRESHOLD = 100;\n\n  public static final Duration DEFAULT_WAIT_DURATION_IN_OPEN_STATUS = Duration.ofMillis(60000);\n\n  //ms\n  public static final Duration DEFAULT_SLOW_CALL_DURATION_THRESHOLD = Duration.ofMillis(60000);\n\n  // the number of permitted calls when the CircuitBreaker is half open.\n  public static final int DEFAULT_PERMITTED = 10;\n\n  public static final int DEFAULT_MINIMUM_NUMBER_CALLS = 100;\n\n  public static final String DEFAULT_SLIDING_WINDOW_SIZE = \"100\";\n\n  public static final String DEFAULT_FAILURE_RESPONSE_STATUS_502 = \"502\";\n\n  public static final String DEFAULT_FAILURE_RESPONSE_STATUS_503 = \"503\";\n\n  public static final List<String> DEFAULT_STATUS_LIST = Arrays.asList(DEFAULT_FAILURE_RESPONSE_STATUS_502,\n      DEFAULT_FAILURE_RESPONSE_STATUS_503);\n\n  private float failureRateThreshold = DEFAULT_FAILURE_RATE_THRESHOLD;\n\n  private float slowCallRateThreshold = DEFAULT_SLOW_CALL_RATE_THRESHOLD;\n\n  private String waitDurationInOpenState = DEFAULT_WAIT_DURATION_IN_OPEN_STATUS.toString();\n\n  private String slowCallDurationThreshold = DEFAULT_SLOW_CALL_DURATION_THRESHOLD.toString();\n\n  private int permittedNumberOfCallsInHalfOpenState = DEFAULT_PERMITTED;\n\n  private int minimumNumberOfCalls = DEFAULT_MINIMUM_NUMBER_CALLS;\n\n  private String slidingWindowType;\n\n  private String slidingWindowSize = DEFAULT_SLIDING_WINDOW_SIZE;\n\n  //status code that need record as a failure\n  private List<String> recordFailureStatus = DEFAULT_STATUS_LIST;\n\n  //force close this circuit breaker. This parameter is not used by circuit breaker directly\n  private boolean forceClosed = false;\n\n  //force open this circuit breaker. This parameter is not used by circuit breaker directly\n  private boolean forceOpen = false;\n\n  public CircuitBreakerPolicy() {\n  }\n\n  @Override\n  public boolean isValid() {\n    if (failureRateThreshold > 100.0F || failureRateThreshold <= 0.0F) {\n      return false;\n    }\n    if (slowCallRateThreshold > 100.0F || slowCallRateThreshold <= 0.0F) {\n      return false;\n    }\n    if (Duration.parse(waitDurationInOpenState).toMillis() <= 0) {\n      return false;\n    }\n    if (Duration.parse(slowCallDurationThreshold).toMillis() <= 0) {\n      return false;\n    }\n    if (permittedNumberOfCallsInHalfOpenState <= 0) {\n      return false;\n    }\n    if (minimumNumberOfCalls <= 0) {\n      return false;\n    }\n\n    return super.isValid();\n  }\n\n  public float getFailureRateThreshold() {\n    return failureRateThreshold;\n  }\n\n  public void setFailureRateThreshold(float failureRateThreshold) {\n    this.failureRateThreshold = failureRateThreshold;\n  }\n\n  public float getSlowCallRateThreshold() {\n    return slowCallRateThreshold;\n  }\n\n  public void setSlowCallRateThreshold(float slowCallRateThreshold) {\n    this.slowCallRateThreshold = slowCallRateThreshold;\n  }\n\n  public String getWaitDurationInOpenState() {\n    return waitDurationInOpenState;\n  }\n\n  public void setWaitDurationInOpenState(String waitDurationInOpenState) {\n    this.waitDurationInOpenState = stringOfDuration(waitDurationInOpenState, DEFAULT_WAIT_DURATION_IN_OPEN_STATUS);\n  }\n\n  public String getSlowCallDurationThreshold() {\n    return slowCallDurationThreshold;\n  }\n\n  public void setSlowCallDurationThreshold(String slowCallDurationThreshold) {\n    this.slowCallDurationThreshold = stringOfDuration(slowCallDurationThreshold, DEFAULT_SLOW_CALL_DURATION_THRESHOLD);\n  }\n\n  public int getPermittedNumberOfCallsInHalfOpenState() {\n    return permittedNumberOfCallsInHalfOpenState;\n  }\n\n  public void setPermittedNumberOfCallsInHalfOpenState(int permittedNumberOfCallsInHalfOpenState) {\n    this.permittedNumberOfCallsInHalfOpenState = permittedNumberOfCallsInHalfOpenState;\n  }\n\n  public int getMinimumNumberOfCalls() {\n    return minimumNumberOfCalls;\n  }\n\n  public void setMinimumNumberOfCalls(int minimumNumberOfCalls) {\n    this.minimumNumberOfCalls = minimumNumberOfCalls;\n  }\n\n  public SlidingWindowType getSlidingWindowTypeEnum() {\n    if (StringUtils.isEmpty(slidingWindowType)) {\n      return SlidingWindowType.TIME_BASED;\n    }\n\n    try {\n      return SlidingWindowType.valueOf(slidingWindowType);\n    } catch (Exception e) {\n      return SlidingWindowType.TIME_BASED;\n    }\n  }\n\n  public String getSlidingWindowType() {\n    return this.slidingWindowType;\n  }\n\n  public void setSlidingWindowType(String slidingWindowType) {\n    this.slidingWindowType = slidingWindowType;\n  }\n\n  // time's unit is second\n  public String getSlidingWindowSize() {\n    return slidingWindowSize;\n  }\n\n  public void setSlidingWindowSize(String slidingWindowSize) {\n    this.slidingWindowSize = getValue(slidingWindowSize);\n  }\n\n  private String getValue(String slidingWindowSize) {\n    if (StringUtils.isEmpty(slidingWindowSize)) {\n      return DEFAULT_SLIDING_WINDOW_SIZE;\n    }\n    if (slidingWindowSize.matches(GovernanceUtils.DIGIT_REGEX)) {\n      if (Long.parseLong(slidingWindowSize) < 0) {\n        throw new RuntimeException(\"The value should be more than 0.\");\n      }\n      return slidingWindowSize;\n    }\n    Duration duration = Duration.parse(GovernanceUtils.DIGIT_PREFIX + slidingWindowSize);\n    return String.valueOf(duration.getSeconds());\n  }\n\n  public List<String> getRecordFailureStatus() {\n    if (CollectionUtils.isEmpty(this.recordFailureStatus)) {\n      return DEFAULT_STATUS_LIST;\n    }\n    return this.recordFailureStatus;\n  }\n\n  public void setRecordFailureStatus(List<String> recordFailureStatus) {\n    if (recordFailureStatus == null) {\n      return;\n    }\n    this.recordFailureStatus = recordFailureStatus.stream().filter(e -> !StringUtils.isEmpty(e))\n        .collect(Collectors.toList());\n  }\n\n  public boolean isForceClosed() {\n    return forceClosed;\n  }\n\n  public void setForceClosed(boolean forceClosed) {\n    this.forceClosed = forceClosed;\n  }\n\n  public boolean isForceOpen() {\n    return forceOpen;\n  }\n\n  public void setForceOpen(boolean forceOpen) {\n    this.forceOpen = forceOpen;\n  }\n\n  @Override\n  public String toString() {\n    return \"CircuitBreakerPolicy{\" +\n        \"failureRateThreshold=\" + failureRateThreshold +\n        \", slowCallRateThreshold=\" + slowCallRateThreshold +\n        \", waitDurationInOpenState=\" + waitDurationInOpenState +\n        \", slowCallDurationThreshold=\" + slowCallDurationThreshold +\n        \", permittedNumberOfCallsInHalfOpenState=\" + permittedNumberOfCallsInHalfOpenState +\n        \", minimumNumberOfCalls=\" + minimumNumberOfCalls +\n        \", slidingWindowType='\" + slidingWindowType + '\\'' +\n        \", slidingWindowSize=\" + slidingWindowSize +\n        \", recordFailureStatus=\" + recordFailureStatus +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/FaultInjectionPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.processor.injection.FaultInjectionConst;\n\npublic class FaultInjectionPolicy extends AbstractPolicy {\n  public static final Duration DEFAULT_TIMEOUT_DURATION = Duration.ofMillis(0);\n\n  private String type = FaultInjectionConst.TYPE_DELAY;\n\n  private String delayTime = DEFAULT_TIMEOUT_DURATION.toString();\n\n  private int percentage = -1;\n\n  private int errorCode = 500;\n\n  private boolean forceClosed = false;\n\n  private String fallbackType = FaultInjectionConst.FALLBACK_THROWEXCEPTION;\n\n  public String getType() {\n    return type;\n  }\n\n  public void setType(String type) {\n    this.type = type;\n  }\n\n  public String getDelayTime() {\n    return delayTime;\n  }\n\n  public void setDelayTime(String delayTime) {\n    this.delayTime = stringOfDuration(delayTime, Duration.ofMillis(-1));\n  }\n\n  public int getPercentage() {\n    return percentage;\n  }\n\n  public void setPercentage(int percentage) {\n    this.percentage = percentage;\n  }\n\n  public int getErrorCode() {\n    return errorCode;\n  }\n\n  public void setErrorCode(int errorCode) {\n    this.errorCode = errorCode;\n  }\n\n  public long getDelayTimeToMillis() {\n    return Duration.parse(delayTime).toMillis();\n  }\n\n  public boolean isForceClosed() {\n    return forceClosed;\n  }\n\n  public void setForceClosed(boolean forceClosed) {\n    this.forceClosed = forceClosed;\n  }\n\n  public String getFallbackType() {\n    return fallbackType;\n  }\n\n  public void setFallbackType(String fallbackType) {\n    this.fallbackType = fallbackType;\n  }\n\n  @Override\n  public boolean isValid() {\n    if (getDelayTimeToMillis() < 0 && FaultInjectionConst.TYPE_DELAY.equals(type)) {\n      return false;\n    }\n    if ((getErrorCode() < FaultInjectionConst.ERROR_CODE_MIN\n        || getErrorCode() > FaultInjectionConst.ERROR_CODE_MAX)\n        && FaultInjectionConst.TYPE_ABORT.equals(type)) {\n      return false;\n    }\n    return super.isValid();\n  }\n\n  @Override\n  public String toString() {\n    return \"FaultInjectionPolicy{\" +\n        \"type=\" + type +\n        \", delayTime=\" + delayTime +\n        \", percentage=\" + percentage +\n        \", errorCode=\" + errorCode +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/GovernanceCachePolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\n\npublic class GovernanceCachePolicy extends AbstractPolicy {\n  public static final Duration DEFAULT_TTL = Duration.ofMillis(21600000);\n\n  public static final long DEFAULT_MAXIMUM_SIZE = 60000;\n\n  public static final int DEFAULT_CONCURRENCY_LEVEL = 8;\n\n  private String ttl = DEFAULT_TTL.toString();\n\n  private long maximumSize = DEFAULT_MAXIMUM_SIZE;\n\n  private int concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL;\n\n  public String getTtl() {\n    return ttl;\n  }\n\n  public void setTtl(String ttl) {\n    this.ttl = stringOfDuration(ttl, DEFAULT_TTL);\n  }\n\n  public Long getMaximumSize() {\n    return maximumSize;\n  }\n\n  public void setMaximumSize(Long maximumSize) {\n    this.maximumSize = maximumSize;\n  }\n\n  public int getConcurrencyLevel() {\n    return concurrencyLevel;\n  }\n\n  public void setConcurrencyLevel(int concurrencyLevel) {\n    this.concurrencyLevel = concurrencyLevel;\n  }\n\n  @Override\n  public String toString() {\n    return \"CachePolicy{\" + \"ttl=\" + ttl + \",concurrencyLevel=\" + concurrencyLevel + \", maximumSize=\" + maximumSize\n        + '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/IdentifierRateLimitingPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.policy;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class IdentifierRateLimitingPolicy extends RateLimitingPolicy {\n  /**\n   * header name used to identify this rate limiter\n   */\n  protected String identifier;\n\n  public String getIdentifier() {\n    return identifier;\n  }\n\n  public void setIdentifier(String identifier) {\n    this.identifier = identifier;\n  }\n\n  @Override\n  public boolean isValid() {\n    if (StringUtils.isEmpty(identifier)) {\n      return false;\n    }\n    return super.isValid();\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/LoadBalancerPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.policy;\n\npublic class LoadBalancerPolicy extends AbstractPolicy {\n  private String rule;\n\n  public String getRule() {\n    return rule;\n  }\n\n  public void setRule(String rule) {\n    this.rule = rule;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/MapperPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.policy;\n\nimport java.util.Map;\n\npublic class MapperPolicy extends AbstractPolicy {\n  private Map<String, String> target;\n\n  public Map<String, String> getTarget() {\n    return target;\n  }\n\n  public void setTarget(Map<String, String> target) {\n    this.target = target;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/RateLimitingPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\n\npublic class RateLimitingPolicy extends AbstractPolicy {\n\n  public static final Duration DEFAULT_TIMEOUT_DURATION = Duration.ofMillis(0);\n\n  public static final Duration DEFAULT_LIMIT_REFRESH_PERIOD = Duration.ofMillis(1000);\n\n  public static final int DEFAULT_LIMIT_FOR_PERIOD = 1000;\n\n  protected String timeoutDuration = DEFAULT_TIMEOUT_DURATION.toString();\n\n  protected String limitRefreshPeriod = DEFAULT_LIMIT_REFRESH_PERIOD.toString();\n\n  // 配置项名称使用 rate， 对应于 resilience4j 的 limitForPeriod\n  protected int rate = DEFAULT_LIMIT_FOR_PERIOD;\n\n  public String getTimeoutDuration() {\n    return timeoutDuration;\n  }\n\n  public void setTimeoutDuration(String timeoutDuration) {\n    this.timeoutDuration = stringOfDuration(timeoutDuration, DEFAULT_TIMEOUT_DURATION);\n  }\n\n  public String getLimitRefreshPeriod() {\n    return limitRefreshPeriod;\n  }\n\n  public void setLimitRefreshPeriod(String limitRefreshPeriod) {\n    this.limitRefreshPeriod = stringOfDuration(limitRefreshPeriod, DEFAULT_LIMIT_REFRESH_PERIOD);\n  }\n\n  public int getRate() {\n    return rate;\n  }\n\n  public void setRate(int rate) {\n    this.rate = rate;\n  }\n\n  public RateLimitingPolicy() {\n  }\n\n  @Override\n  public boolean isValid() {\n    if (Duration.parse(timeoutDuration).toMillis() < 0) {\n      return false;\n    }\n    if (Duration.parse(limitRefreshPeriod).toMillis() <= 0) {\n      return false;\n    }\n    if (rate <= 0) {\n      return false;\n    }\n    return super.isValid();\n  }\n\n  @Override\n  public String toString() {\n    return \"RateLimitingPolicy{\" +\n        \"timeoutDuration=\" + timeoutDuration +\n        \", limitRefreshPeriod=\" + limitRefreshPeriod +\n        \", rate=\" + rate + \" req/s\" +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/RetryPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.springframework.util.CollectionUtils;\n\npublic class RetryPolicy extends AbstractPolicy {\n\n  public static final int DEFAULT_MAX_ATTEMPTS = 3;\n\n  public static final Duration DEFAULT_WAIT_DURATION = Duration.ofMillis(1);\n\n  public static final String DEFAULT_RETRY_ON_RESPONSE_STATUS_502 = \"502\";\n\n  public static final String DEFAULT_RETRY_ON_RESPONSE_STATUS_503 = \"503\";\n\n  public static final List<String> DEFAULT_STATUS_LIST = Arrays.asList(DEFAULT_RETRY_ON_RESPONSE_STATUS_502,\n      DEFAULT_RETRY_ON_RESPONSE_STATUS_503);\n\n  private static final Duration INITIAL_INTERVAL = Duration.ofMillis(1000);\n\n  private static final float MULTIPLIER = 2;\n\n  private static final double RANDOMIZATION_FACTOR = 0.5;\n\n  private static final String DEFAULT_RETRY_STRATEGY = \"FixedInterval\";\n\n  //max retry attempts\n  private int maxAttempts = DEFAULT_MAX_ATTEMPTS;\n\n  //wait duration for each retry\n  private String waitDuration = DEFAULT_WAIT_DURATION.toString();\n\n  //status code that need retry\n  private List<String> retryOnResponseStatus = DEFAULT_STATUS_LIST;\n\n  //retry strategy\n  private String retryStrategy = DEFAULT_RETRY_STRATEGY;\n\n  // initial interval for backoff retry\n  private String initialInterval = INITIAL_INTERVAL.toString();\n\n  // multiplier for backoff retry\n  private float multiplier = MULTIPLIER;\n\n  // randomization factor for backoff retry\n  private double randomizationFactor = RANDOMIZATION_FACTOR;\n\n  // if throw an MaxRetriesExceededException if retry condition is based on result\n  private boolean failAfterMaxAttempts = false;\n\n  // if retry on the same instance. This property is not directly used in\n  // RetryHandler, but used for loadbalancers\n  private int retryOnSame = 0;\n\n  public List<String> getRetryOnResponseStatus() {\n    if (CollectionUtils.isEmpty(retryOnResponseStatus)) {\n      return DEFAULT_STATUS_LIST;\n    }\n    return retryOnResponseStatus;\n  }\n\n  public void setRetryOnResponseStatus(List<String> retryOnResponseStatus) {\n    if (retryOnResponseStatus == null) {\n      return;\n    }\n    this.retryOnResponseStatus = retryOnResponseStatus.stream().filter(e -> !StringUtils.isEmpty(e))\n        .collect(Collectors.toList());\n  }\n\n  public int getMaxAttempts() {\n    return maxAttempts;\n  }\n\n  public void setMaxAttempts(int maxAttempts) {\n    this.maxAttempts = maxAttempts;\n  }\n\n  public String getWaitDuration() {\n    return Duration.parse(waitDuration).toMillis() < 1 ? DEFAULT_WAIT_DURATION.toString() : waitDuration;\n  }\n\n  public void setWaitDuration(String waitDuration) {\n    this.waitDuration = stringOfDuration(waitDuration, DEFAULT_WAIT_DURATION);\n  }\n\n  public String getRetryStrategy() {\n    if (StringUtils.isEmpty(retryStrategy)) {\n      retryStrategy = DEFAULT_RETRY_STRATEGY;\n    }\n    return retryStrategy;\n  }\n\n  public void setRetryStrategy(String retryStrategy) {\n    this.retryStrategy = retryStrategy;\n  }\n\n  public String getInitialInterval() {\n    return initialInterval;\n  }\n\n  public void setInitialInterval(String initialInterval) {\n    this.initialInterval = stringOfDuration(initialInterval, INITIAL_INTERVAL);\n  }\n\n  public float getMultiplier() {\n    return multiplier;\n  }\n\n  public void setMultiplier(float multiplier) {\n    this.multiplier = multiplier;\n  }\n\n  public double getRandomizationFactor() {\n    return randomizationFactor;\n  }\n\n  public void setRandomizationFactor(double randomizationFactor) {\n    this.randomizationFactor = randomizationFactor;\n  }\n\n  public boolean isFailAfterMaxAttempts() {\n    return failAfterMaxAttempts;\n  }\n\n  public void setFailAfterMaxAttempts(boolean failAfterMaxAttempts) {\n    this.failAfterMaxAttempts = failAfterMaxAttempts;\n  }\n\n  public int getRetryOnSame() {\n    return retryOnSame;\n  }\n\n  public void setRetryOnSame(int retryOnSame) {\n    this.retryOnSame = retryOnSame;\n  }\n\n  @Override\n  public boolean isValid() {\n    if (maxAttempts < 1) {\n      return false;\n    }\n    if (Duration.parse(waitDuration).toMillis() < 0) {\n      return false;\n    }\n    if (Duration.parse(initialInterval).toMillis() < 10) {\n      return false;\n    }\n    return super.isValid();\n  }\n\n  @Override\n  public String toString() {\n    return \"RetryPolicy{\" +\n        \"maxAttempts=\" + maxAttempts +\n        \", waitDuration=\" + waitDuration +\n        \", retryOnResponseStatus='\" + retryOnResponseStatus + '\\'' +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/policy/TimeLimiterPolicy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.policy;\n\nimport java.time.Duration;\n\npublic class TimeLimiterPolicy extends AbstractPolicy {\n  public static final Duration DEFAULT_TIMEOUT_DURATION = Duration.ofMillis(1000);\n\n  public static final boolean DEFAULT_CANCEL_RUNNING_FUTURE = true;\n\n  private String timeoutDuration = DEFAULT_TIMEOUT_DURATION.toString();\n\n  private boolean cancelRunningFuture = DEFAULT_CANCEL_RUNNING_FUTURE;\n\n  public String getTimeoutDuration() {\n    return timeoutDuration;\n  }\n\n  public void setTimeoutDuration(String timeoutDuration) {\n    this.timeoutDuration = stringOfDuration(timeoutDuration, DEFAULT_TIMEOUT_DURATION);\n  }\n\n  public boolean isCancelRunningFuture() {\n    return cancelRunningFuture;\n  }\n\n  public void setCancelRunningFuture(boolean cancelRunningFuture) {\n    this.cancelRunningFuture = cancelRunningFuture;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/AbortFault.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class AbortFault extends AbstractFault {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbortFault.class);\n\n  public static final String ABORTED_ERROR_MSG = \"aborted by fault inject\";\n\n  public AbortFault(String key, FaultInjectionPolicy policy) {\n    super(key, policy);\n  }\n\n  @Override\n  public boolean injectFault(FaultParam faultParam) {\n    return shouldAbort(faultParam, policy);\n  }\n\n  private boolean shouldAbort(FaultParam param, FaultInjectionPolicy policy) {\n    // get the config values related to abort.\n    int abortPercent = policy.getPercentage();\n    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: Abort percentage is not configured\");\n      return false;\n    }\n\n    // check fault abort condition.\n    return FaultInjectionUtil.isFaultNeedToInject(param.getReqCount(), abortPercent);\n  }\n\n  @Override\n  public int getOrder() {\n    return 200;\n  }\n\n  @Override\n  public String getName() {\n    return FaultInjectionConst.TYPE_ABORT;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/AbstractFault.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\n\npublic abstract class AbstractFault implements Fault {\n  protected String key;\n\n  protected FaultInjectionPolicy policy;\n\n  public AbstractFault(String key, FaultInjectionPolicy policy) {\n    this.key = key;\n    this.policy = policy;\n  }\n\n  @Override\n  public boolean injectFault() {\n    if (policy.isForceClosed()) {\n      return false;\n    }\n    FaultParam faultParam = FaultInjectionUtil.initFaultParam(key);\n    return injectFault(faultParam);\n  }\n\n  @Override\n  public String getKey() {\n    return key;\n  }\n\n  @Override\n  public FaultInjectionPolicy getPolicy() {\n    return policy;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/DelayFault.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class DelayFault extends AbstractFault {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DelayFault.class);\n\n  public DelayFault(String key, FaultInjectionPolicy policy) {\n    super(key, policy);\n  }\n\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n\n  @Override\n  public boolean injectFault(FaultParam faultParam) {\n    if (!shouldDelay(faultParam, policy)) {\n      return false;\n    }\n\n    LOGGER.debug(\"Fault injection: delay is added for the request by fault inject handler\");\n    long delay = policy.getDelayTimeToMillis();\n    if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: delay is not configured\");\n      return false;\n    }\n\n    executeDelay(faultParam, delay);\n    return false;\n  }\n\n  private void executeDelay(FaultParam faultParam, long delay) {\n    Sleepable sleepable = faultParam.getSleepable();\n    if (sleepable != null) {\n      sleepable.sleep(delay);\n    }\n  }\n\n  private boolean shouldDelay(FaultParam param, FaultInjectionPolicy policy) {\n    int delayPercent = policy.getPercentage();\n    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: delay percentage is not configured\");\n      return false;\n    }\n    // check fault delay condition.\n    return FaultInjectionUtil.isFaultNeedToInject(param.getReqCount(), delayPercent);\n  }\n\n  @Override\n  public String getName() {\n    return FaultInjectionConst.TYPE_DELAY;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/Fault.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\n\nimport io.vavr.CheckedFunction0;\n\npublic interface Fault {\n  static <T> CheckedFunction0<T> decorateCheckedSupplier(Fault fault, CheckedFunction0<T> supplier) {\n    return () -> {\n      if (fault.injectFault()) {\n        if (FaultInjectionConst.FALLBACK_THROWEXCEPTION.equals(fault.getPolicy().getFallbackType())) {\n          throw new FaultInjectionException(\n              FaultResponse.createFail(fault.getPolicy().getErrorCode(), AbortFault.ABORTED_ERROR_MSG));\n        } else {\n          return null;\n        }\n      }\n      return supplier.apply();\n    };\n  }\n\n  int getOrder();\n\n  String getName();\n\n  /*\n   * If true is returned,the downgrade governance policy is executed.\n   * Otherwise,the original request is directly executed.\n   * */\n  boolean injectFault();\n\n  /*\n   * If true is returned,the downgrade governance policy is executed.\n   * Otherwise,the original request is directly executed.\n   * */\n  boolean injectFault(FaultParam faultParam);\n\n  String getKey();\n\n  FaultInjectionPolicy getPolicy();\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/FaultInjectionConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\n/**\n * Handles the all constant values for fault injection.\n */\npublic class FaultInjectionConst {\n\n  public static final int FAULT_INJECTION_DEFAULT_VALUE = -1;\n\n  public static final String TYPE_DELAY = \"delay\";\n\n  public static final String TYPE_ABORT = \"abort\";\n\n  public static final String FALLBACK_THROWEXCEPTION = \"ThrowException\";\n\n  public static final String FALLBACK_RETURNNULL = \"ReturnNull\";\n\n  public static final int ERROR_CODE_MIN = 200;\n\n  public static final int ERROR_CODE_MAX = 600;\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/FaultInjectionDecorators.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport io.vavr.CheckedFunction0;\n\npublic interface FaultInjectionDecorators {\n  static <T> FaultInjectionDecorateCheckedSupplier<T> ofCheckedSupplier(CheckedFunction0<T> supplier) {\n    return new FaultInjectionDecorateCheckedSupplier<>(supplier);\n  }\n\n  class FaultInjectionDecorateCheckedSupplier<T> {\n\n    private CheckedFunction0<T> supplier;\n\n    protected FaultInjectionDecorateCheckedSupplier(CheckedFunction0<T> supplier) {\n      this.supplier = supplier;\n    }\n\n    public FaultInjectionDecorateCheckedSupplier<T> withFaultInjection(Fault fault) {\n      supplier = Fault.decorateCheckedSupplier(fault, supplier);\n      return this;\n    }\n\n    public T get() throws Throwable {\n      return supplier.apply();\n    }\n  }\n\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/FaultInjectionException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\npublic class FaultInjectionException extends RuntimeException {\n  private static final long serialVersionUID = 1675558351029273343L;\n\n  private final FaultResponse faultResponse;\n\n  public FaultInjectionException(FaultResponse faultResponse) {\n    super(faultResponse.getErrorMsg());\n    this.faultResponse = faultResponse;\n  }\n\n  public FaultResponse getFaultResponse() {\n    return faultResponse;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/FaultInjectionUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\n\n/**\n * Handles the count for all request based key[transport + microservice qualified name].\n */\npublic final class FaultInjectionUtil {\n\n  private FaultInjectionUtil() {\n  }\n\n  /**\n   * key is transport+operQualifiedName\n   */\n  private static final Map<String, AtomicLong> REQUEST_COUNT = new ConcurrentHashMapEx<>();\n\n  /**\n   * Returns total requests per provider for operational level.\n   *\n   * @param key\n   *            transport+operational name\n   * @return long total requests\n   */\n  public static AtomicLong getOperMetTotalReq(String key) {\n    return REQUEST_COUNT.computeIfAbsent(key, p -> new AtomicLong(1));\n  }\n\n  /**\n   * It will check the delay/abort condition based on request count and percentage\n   * received.\n   *\n   * @param reqCount total request count of the uri\n   * @param percentage the percentage of hitting fault injection\n   * @return true: delay/abort is needed. false: delay/abort is not needed.\n   */\n  public static boolean isFaultNeedToInject(long reqCount, int percentage) {\n    /*\n     * Example: delay/abort percentage configured is 10% and Get the count(suppose\n     * if it is 10th request) from map and calculate resultNew(10th request) and\n     * requestOld(9th request). Like this for every request it will calculate\n     * current request count and previous count. if both not matched need to add\n     * delay/abort otherwise no need to add.\n     */\n\n    // calculate the value with current request count.\n    long resultNew = (reqCount * percentage) / 100;\n\n    // calculate the value with previous count value.\n    long resultOld = ((reqCount - 1) * percentage) / 100;\n\n    // if both are not matching then delay/abort should be added.\n    return (resultNew != resultOld);\n  }\n\n  public static Fault getFault(String key, FaultInjectionPolicy policy) {\n    Fault fault = null;\n    if (FaultInjectionConst.TYPE_DELAY.equals(policy.getType())) {\n      fault = new DelayFault(key, policy);\n    } else if (FaultInjectionConst.TYPE_ABORT.equals(policy.getType())) {\n      fault = new AbortFault(key, policy);\n    }\n    return fault;\n  }\n\n  public static FaultParam initFaultParam(String key) {\n    AtomicLong reqCount = FaultInjectionUtil.getOperMetTotalReq(key);\n    // increment the request count here after checking the delay/abort condition.\n    long reqCountCurrent = reqCount.getAndIncrement();\n\n    FaultParam param = new FaultParam(reqCountCurrent);\n    Context currentContext = Vertx.currentContext();\n    if (currentContext != null && currentContext.owner() != null && currentContext.isEventLoopContext()) {\n      param.setSleepable(\n          (delay) -> currentContext.owner().setTimer(delay, timeId -> {}));\n    }\n    return param;\n  }\n\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/FaultParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Fault injection parameters which decides the fault injection condition.\n */\npublic class FaultParam {\n  private static final Logger LOGGER = LoggerFactory.getLogger(FaultParam.class);\n\n  private final long reqCount;\n\n  private Sleepable sleepable = (delay) -> {\n    try {\n      Thread.sleep(delay);\n    } catch (InterruptedException e) {\n      LOGGER.info(\"Interrupted exception is received\");\n    }\n  };\n\n  public long getReqCount() {\n    return reqCount;\n  }\n\n  public FaultParam(long reqCount) {\n    this.reqCount = reqCount;\n  }\n\n  public Sleepable getSleepable() {\n    return sleepable;\n  }\n\n  public void setSleepable(Sleepable sleepable) {\n    this.sleepable = sleepable;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/FaultResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\npublic class FaultResponse {\n\n  private int errorCode;\n\n  private String errorMsg;\n\n  public static FaultResponse createFail(int errorCode, String errorMsg) {\n    FaultResponse faultResponse = new FaultResponse();\n    faultResponse.setErrorCode(errorCode);\n    faultResponse.setErrorMsg(errorMsg);\n    return faultResponse;\n  }\n\n  public int getErrorCode() {\n    return errorCode;\n  }\n\n  public void setErrorCode(int errorCode) {\n    this.errorCode = errorCode;\n  }\n\n  public String getErrorMsg() {\n    return errorMsg;\n  }\n\n  public void setErrorMsg(String errorMsg) {\n    this.errorMsg = errorMsg;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/injection/Sleepable.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.injection;\n\npublic interface Sleepable {\n  /**\n   * sleep some time\n   * @param delay time unit is millisecond\n   */\n  void sleep(long delay);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/loadbanlance/LoadBalance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.loadbanlance;\n\nimport org.apache.servicecomb.governance.policy.LoadBalancerPolicy;\n\npublic interface LoadBalance {\n\n  static LoadBalance getLoadBalance(String key, LoadBalancerPolicy policy) {\n    LoadBalance loadBalance = new LoadBalanceImpl(policy.getRule());\n    return loadBalance;\n  }\n\n  String getRule();\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/loadbanlance/LoadBalanceImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.loadbanlance;\n\npublic class LoadBalanceImpl implements LoadBalance {\n  private final String rule;\n\n  public LoadBalanceImpl(String rule) {\n    this.rule = rule;\n  }\n\n  public String getRule() {\n    return rule;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/processor/mapping/Mapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.processor.mapping;\n\nimport java.util.Map;\n\npublic interface Mapper {\n  static Mapper create(Map<String, String> target) {\n    return () -> target;\n  }\n\n  Map<String, String> target();\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/BulkheadProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.BulkheadPolicy;\n\npublic class BulkheadProperties extends PolicyProperties<BulkheadPolicy> {\n  public static final String MATCH_BULKHEAD_KEY = \"servicecomb.bulkhead\";\n\n  public BulkheadProperties() {\n    super(MATCH_BULKHEAD_KEY);\n  }\n\n  public BulkheadProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<BulkheadPolicy> getEntityClass() {\n    return BulkheadPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/CircuitBreakerProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;\n\npublic class CircuitBreakerProperties extends PolicyProperties<CircuitBreakerPolicy> {\n  public static final String MATCH_CIRCUITBREAKER_KEY = \"servicecomb.circuitBreaker\";\n\n  public CircuitBreakerProperties() {\n    super(MATCH_CIRCUITBREAKER_KEY);\n  }\n\n  public CircuitBreakerProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<CircuitBreakerPolicy> getEntityClass() {\n    return CircuitBreakerPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/FaultInjectionProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\n\npublic class FaultInjectionProperties extends PolicyProperties<FaultInjectionPolicy> {\n  public static final String MATCH_FAULT_INJECTION_KEY = \"servicecomb.faultInjection\";\n\n  public FaultInjectionProperties() {\n    super(MATCH_FAULT_INJECTION_KEY);\n  }\n\n  public FaultInjectionProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<FaultInjectionPolicy> getEntityClass() {\n    return FaultInjectionPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/GovernanceCacheProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.GovernanceCachePolicy;\n\npublic class GovernanceCacheProperties extends PolicyProperties<GovernanceCachePolicy> {\n  public static final String MATCH_CACHE_KEY = \"servicecomb.cache\";\n\n  public GovernanceCacheProperties() {\n    super(MATCH_CACHE_KEY);\n  }\n\n  public GovernanceCacheProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<GovernanceCachePolicy> getEntityClass() {\n    return GovernanceCachePolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/GovernanceProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.MicroserviceMeta;\nimport org.apache.servicecomb.governance.entity.Configurable;\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.CompositePropertySource;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.PropertySource;\nimport org.springframework.util.CollectionUtils;\nimport org.yaml.snakeyaml.DumperOptions;\nimport org.yaml.snakeyaml.LoaderOptions;\nimport org.yaml.snakeyaml.TypeDescription;\nimport org.yaml.snakeyaml.Yaml;\nimport org.yaml.snakeyaml.constructor.Constructor;\nimport org.yaml.snakeyaml.representer.Representer;\n\nimport com.google.common.eventbus.Subscribe;\n\npublic abstract class GovernanceProperties<T extends Configurable> implements InitializingBean {\n  private static final Logger LOGGER = LoggerFactory.getLogger(GovernanceProperties.class);\n\n  private final Representer representer = new Representer(new DumperOptions());\n\n  private final String configKey;\n\n  protected Environment environment;\n\n  private MicroserviceMeta microserviceMeta;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setMicroserviceMeta(MicroserviceMeta microserviceMeta) {\n    this.microserviceMeta = microserviceMeta;\n  }\n\n  protected Map<String, T> parsedEntity;\n\n  protected Class<T> entityClass;\n\n  protected GovernanceProperties(String key) {\n    configKey = key;\n    representer.getPropertyUtils().setSkipMissingProperties(true);\n    GovernanceEventManager.register(this);\n    entityClass = getEntityClass();\n  }\n\n  public String getConfigKey() {\n    return this.configKey;\n  }\n\n  @Override\n  public void afterPropertiesSet() {\n    parsedEntity = parseEntity(readPropertiesFromPrefix());\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(GovernanceConfigurationChangedEvent event) {\n    for (String key : event.getChangedConfigurations()) {\n      if (key.startsWith(configKey + \".\")) {\n        String mapKey = key.substring((configKey + \".\").length());\n        parsedEntity.remove(mapKey);\n        T entityItem = parseEntityItem(mapKey, environment.getProperty(key));\n        if (entityItem != null) {\n          parsedEntity.put(mapKey, entityItem);\n        }\n      }\n    }\n  }\n\n  private Map<String, String> readPropertiesFromPrefix() {\n    Set<String> allKeys = getAllKeys(environment);\n    Map<String, String> result = new HashMap<>();\n    allKeys.forEach(key -> {\n      if (key.startsWith(configKey + \".\")) {\n        result.put(key.substring(configKey.length() + 1), environment.getProperty(key));\n      }\n    });\n    return result;\n  }\n\n  private Set<String> getAllKeys(Environment environment) {\n    Set<String> allKeys = new HashSet<>();\n\n    if (!(environment instanceof ConfigurableEnvironment)) {\n      return allKeys;\n    }\n\n    ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;\n\n    for (PropertySource<?> propertySource : configurableEnvironment.getPropertySources()) {\n      getProperties(propertySource, allKeys);\n    }\n    return allKeys;\n  }\n\n  private void getProperties(PropertySource<?> propertySource,\n      Set<String> allKeys) {\n    if (propertySource instanceof CompositePropertySource) {\n      // recursively get EnumerablePropertySource\n      CompositePropertySource compositePropertySource = (CompositePropertySource) propertySource;\n      compositePropertySource.getPropertySources().forEach(ps -> getProperties(ps, allKeys));\n      return;\n    }\n    if (propertySource instanceof EnumerablePropertySource) {\n      EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) propertySource;\n      Collections.addAll(allKeys, enumerablePropertySource.getPropertyNames());\n      return;\n    }\n\n    LOGGER.debug(\"None EnumerablePropertySource ignored in {}, propertySourceName = [{}]\", this.getClass().getName(),\n        propertySource.getName());\n  }\n\n  public Map<String, T> getParsedEntity() {\n    return this.parsedEntity;\n  }\n\n  protected Map<String, T> parseEntity(Map<String, String> yamlEntity) {\n    if (CollectionUtils.isEmpty(yamlEntity)) {\n      return new HashMap<>();\n    }\n\n    Map<String, T> resultMap = new HashMap<>();\n    for (Entry<String, String> entry : yamlEntity.entrySet()) {\n      T marker = parseEntityItem(entry.getKey(), entry.getValue());\n      if (marker != null) {\n        resultMap.put(entry.getKey(), marker);\n      }\n    }\n    return resultMap;\n  }\n\n  protected abstract Class<T> getEntityClass();\n\n  protected T parseEntityItem(String key, String value) {\n    if (StringUtils.isEmpty(value)) {\n      return null;\n    }\n\n    try {\n      Yaml entityParser = new Yaml(new Constructor(new TypeDescription(entityClass, entityClass), new LoaderOptions()),\n          representer);\n      T result = entityParser.loadAs(value, entityClass);\n      result.setName(key);\n\n      if (!result.isValid()) {\n        LOGGER.warn(\"Entity configuration is not valid and ignored. Key [{}], value [{}]\", key, value);\n        return null;\n      }\n      if (!servicesMatch(result.getServices())) {\n        LOGGER.info(\"Configuration belongs to other service is ignored. Key [{}]\", key);\n        return null;\n      }\n      return result;\n    } catch (RuntimeException e) {\n      LOGGER.error(\"governance config yaml is illegal : {}\", e.getMessage());\n    }\n    return null;\n  }\n\n  private boolean servicesMatch(String services) {\n    if (StringUtils.isEmpty(services)) {\n      return true;\n    }\n\n    return Arrays.stream(services.split(\",\")).anyMatch(service -> {\n      String[] serviceAndVersion = service.split(\":\");\n      if (serviceAndVersion.length == 1) {\n        return microserviceMeta.getName().equals(serviceAndVersion[0]);\n      } else if (serviceAndVersion.length == 2) {\n        return microserviceMeta.getName().equals(serviceAndVersion[0]) && microserviceMeta.getVersion()\n            .equals(serviceAndVersion[1]);\n      } else {\n        return false;\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/IdentifierRateLimitProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.IdentifierRateLimitingPolicy;\n\npublic class IdentifierRateLimitProperties extends PolicyProperties<IdentifierRateLimitingPolicy> {\n  public static final String MATCH_RATE_LIMIT_KEY = \"servicecomb.identifierRateLimiting\";\n\n  public IdentifierRateLimitProperties() {\n    super(MATCH_RATE_LIMIT_KEY);\n  }\n\n  public IdentifierRateLimitProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<IdentifierRateLimitingPolicy> getEntityClass() {\n    return IdentifierRateLimitingPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/InstanceBulkheadProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.BulkheadPolicy;\n\npublic class InstanceBulkheadProperties extends PolicyProperties<BulkheadPolicy> {\n  public static final String MATCH_INSTANCE_BULKHEAD_KEY = \"servicecomb.instanceBulkhead\";\n\n  public InstanceBulkheadProperties() {\n    super(MATCH_INSTANCE_BULKHEAD_KEY);\n  }\n\n  public InstanceBulkheadProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<BulkheadPolicy> getEntityClass() {\n    return BulkheadPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/InstanceIsolationProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;\n\npublic class InstanceIsolationProperties extends PolicyProperties<CircuitBreakerPolicy> {\n  public static final String MATCH_INSTANCE_ISOLATION_KEY = \"servicecomb.instanceIsolation\";\n\n  public InstanceIsolationProperties() {\n    super(MATCH_INSTANCE_ISOLATION_KEY);\n  }\n\n  public InstanceIsolationProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<CircuitBreakerPolicy> getEntityClass() {\n    return CircuitBreakerPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/LoadBalanceProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.LoadBalancerPolicy;\n\npublic class LoadBalanceProperties extends PolicyProperties<LoadBalancerPolicy> {\n  public static final String MATCH_LOADBANLANCER_KEY = \"servicecomb.loadbalance\";\n\n  public LoadBalanceProperties() {\n    super(MATCH_LOADBANLANCER_KEY);\n  }\n\n  public LoadBalanceProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  protected Class<LoadBalancerPolicy> getEntityClass() {\n    return LoadBalancerPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/MapperProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.MapperPolicy;\n\npublic class MapperProperties extends PolicyProperties<MapperPolicy> {\n  public static final String MATCH_MAPPER_KEY = \"servicecomb.mapper\";\n\n  public MapperProperties() {\n    super(MATCH_MAPPER_KEY);\n  }\n\n  public MapperProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  protected Class<MapperPolicy> getEntityClass() {\n    return MapperPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/MatchProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.marker.TrafficMarker;\n\npublic class MatchProperties extends GovernanceProperties<TrafficMarker> {\n  public static final String MATCH_POLICY_KEY = \"servicecomb.matchGroup\";\n\n  public MatchProperties() {\n    super(MATCH_POLICY_KEY);\n  }\n\n  @Override\n  public Class<TrafficMarker> getEntityClass() {\n    return TrafficMarker.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/PolicyProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.AbstractPolicy;\n\npublic abstract class PolicyProperties<T extends AbstractPolicy> extends GovernanceProperties<T> {\n  protected PolicyProperties(String key) {\n    super(key);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/RateLimitProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\n\nimport org.apache.servicecomb.governance.policy.RateLimitingPolicy;\n\npublic class RateLimitProperties extends PolicyProperties<RateLimitingPolicy> {\n  public static final String MATCH_RATE_LIMIT_KEY = \"servicecomb.rateLimiting\";\n\n  public RateLimitProperties() {\n    super(MATCH_RATE_LIMIT_KEY);\n  }\n\n  public RateLimitProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<RateLimitingPolicy> getEntityClass() {\n    return RateLimitingPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/RetryProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\nimport org.apache.servicecomb.governance.policy.RetryPolicy;\n\npublic class RetryProperties extends PolicyProperties<RetryPolicy> {\n  public static final String MATCH_RETRY_KEY = \"servicecomb.retry\";\n\n  public RetryProperties() {\n    super(MATCH_RETRY_KEY);\n  }\n\n  public RetryProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<RetryPolicy> getEntityClass() {\n    return RetryPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/properties/TimeLimiterProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.properties;\n\n\nimport org.apache.servicecomb.governance.policy.TimeLimiterPolicy;\n\npublic class TimeLimiterProperties extends PolicyProperties<TimeLimiterPolicy> {\n  public static final String MATCH_TIMELIMITER_KEY = \"servicecomb.timeLimiter\";\n\n  public TimeLimiterProperties() {\n    super(MATCH_TIMELIMITER_KEY);\n  }\n\n  public TimeLimiterProperties(String key) {\n    super(key);\n  }\n\n  @Override\n  public Class<TimeLimiterPolicy> getEntityClass() {\n    return TimeLimiterPolicy.class;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/service/GovernanceCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.service;\n\nimport com.google.common.cache.Cache;\n\nimport java.util.Objects;\n\npublic interface GovernanceCache<K, V> {\n  static <K, V> GovernanceCache<K, V> of(Cache<K, V> cache) {\n    Objects.requireNonNull(cache, \"Cache must not be null\");\n    return new GovernanceCacheImpl<>(cache);\n  }\n\n  V getValueFromCache(K cacheKey);\n\n  void putValueIntoCache(K cacheKey, V value);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/service/GovernanceCacheImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.service;\n\nimport com.google.common.cache.Cache;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class GovernanceCacheImpl<K, V> implements GovernanceCache<K, V> {\n\n  private static final Logger LOG = LoggerFactory.getLogger(GovernanceCacheImpl.class);\n\n  private final Cache<K, V> cache;\n\n  public GovernanceCacheImpl(Cache<K, V> cache) {\n    this.cache = cache;\n  }\n\n  public V getValueFromCache(K cacheKey) {\n    try {\n      return cache.getIfPresent(cacheKey);\n    } catch (Exception exception) {\n      LOG.warn(\"Failed to get a value from Cache\", exception);\n      return null;\n    }\n  }\n\n  @Override\n  public void putValueIntoCache(K cacheKey, V value) {\n    try {\n      cache.put(cacheKey, value);\n    } catch (Exception exception) {\n      LOG.warn(\"Failed to put a value into Cache {}\", exception);\n    }\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/service/MatchersService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance.service;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\n\npublic interface MatchersService {\n  boolean checkMatch(GovernanceRequestExtractor governanceRequest, String key);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/service/MatchersServiceImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.service;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.marker.RequestProcessor;\nimport org.apache.servicecomb.governance.marker.TrafficMarker;\nimport org.apache.servicecomb.governance.properties.MatchProperties;\n\npublic class MatchersServiceImpl implements MatchersService {\n  private final RequestProcessor requestProcessor;\n\n  private final MatchProperties matchProperties;\n\n  public MatchersServiceImpl(RequestProcessor requestProcessor, MatchProperties matchProperties) {\n    this.requestProcessor = requestProcessor;\n    this.matchProperties = matchProperties;\n  }\n\n  @Override\n  public boolean checkMatch(GovernanceRequestExtractor governanceRequest, String key) {\n    Map<String, TrafficMarker> parsedEntity = matchProperties.getParsedEntity();\n\n    TrafficMarker trafficMarker = parsedEntity.get(key);\n\n    if (trafficMarker == null) {\n      return false;\n    }\n\n    return trafficMarker.checkMatch(governanceRequest, requestProcessor);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/utils/CustomMatch.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.utils;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\n\npublic interface CustomMatch {\n  boolean matchRequest(GovernanceRequestExtractor requestExtractor, String parameters);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/governance/utils/GovernanceUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.utils;\n\npublic final class GovernanceUtils {\n  public static final String DIGIT_REGEX = \"-{0,1}[0-9]{1,10}\";\n\n  public static final String DIGIT_PREFIX = \"PT\";\n\n  public static final String STRATEGY_RANDOM_BACKOFF = \"RandomBackoff\";\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/RouterCommonConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router;\n\nimport org.apache.servicecomb.governance.marker.RequestProcessor;\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.match.RouterRuleMatcher;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\npublic class RouterCommonConfiguration {\n  @Bean\n  public RouterRuleCache scbRouterRuleCache(Environment environment) {\n    return new RouterRuleCache(environment);\n  }\n\n  @Bean\n  public RouterRuleMatcher scbRouterRuleMatcher(RouterRuleCache routerRuleCache, RequestProcessor requestProcessor) {\n    return new RouterRuleMatcher(routerRuleCache, requestProcessor);\n  }\n\n  @Bean\n  public RouterFilter scbRouterFilter(RouterRuleMatcher routerRuleMatcher, RouterRuleCache routerRuleCache) {\n    return new RouterFilter(routerRuleMatcher, routerRuleCache);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/RouterFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router;\n\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\nimport org.apache.servicecomb.router.match.RouterRuleMatcher;\nimport org.apache.servicecomb.router.model.PolicyRuleItem;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\npublic class RouterFilter {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(RouterFilter.class);\n\n  private final RouterRuleMatcher routerRuleMatcher;\n\n  private final RouterRuleCache routerRuleCache;\n\n  public RouterFilter(RouterRuleMatcher routerRuleMatcher, RouterRuleCache routerRuleCache) {\n    this.routerRuleMatcher = routerRuleMatcher;\n    this.routerRuleCache = routerRuleCache;\n  }\n\n  public <T> List<T> getFilteredListOfServers(List<T> list,\n      String targetServiceName, GovernanceRequestExtractor extractor, RouterDistributor<T> distributor) {\n    if (CollectionUtils.isEmpty(list)) {\n      return list;\n    }\n    if (StringUtils.isEmpty(targetServiceName)) {\n      return list;\n    }\n    // 1.init and cache\n    if (!routerRuleCache.doInit(targetServiceName)) {\n      LOGGER.debug(\"route management init failed\");\n      return list;\n    }\n    // 2.match rule\n    PolicyRuleItem invokeRule = routerRuleMatcher.match(targetServiceName, extractor);\n\n    if (invokeRule == null) {\n      LOGGER.debug(\"route management match rule failed\");\n      return list;\n    }\n\n    LOGGER.debug(\"route management match rule success: {}\", invokeRule);\n\n    // 3.distribute select endpoint\n    List<T> resultList = distributor.distribute(targetServiceName, list, invokeRule);\n\n    LOGGER.debug(\"route management distribute rule success: {}\", resultList);\n\n    return resultList;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/cache/RouterRuleCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.cache;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.apache.servicecomb.router.model.PolicyRuleItem;\nimport org.apache.servicecomb.router.model.ServiceInfoCache;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\nimport org.yaml.snakeyaml.DumperOptions;\nimport org.yaml.snakeyaml.LoaderOptions;\nimport org.yaml.snakeyaml.TypeDescription;\nimport org.yaml.snakeyaml.Yaml;\nimport org.yaml.snakeyaml.constructor.Constructor;\nimport org.yaml.snakeyaml.representer.Representer;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.eventbus.Subscribe;\n\npublic class RouterRuleCache {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RouterRuleCache.class);\n\n  public static final String ROUTE_RULE_PREFIX = \"servicecomb.routeRule.\";\n\n  private static final String ROUTE_RULE = \"servicecomb.routeRule.%s\";\n\n  public static final String GLOBAL_ROUTE_RULE_KEY = \"servicecomb.globalRouteRule\";\n\n  private final Environment environment;\n\n  private final ConcurrentHashMap<String, ServiceInfoCache> serviceInfoCacheMap = new ConcurrentHashMap<>();\n\n  private final Object lock = new Object();\n\n  private final Representer representer = new Representer(new DumperOptions());\n\n  public RouterRuleCache(Environment environment) {\n    this.environment = environment;\n    representer.getPropertyUtils().setSkipMissingProperties(true);\n    GovernanceEventManager.register(this);\n  }\n\n  /**\n   * cache and register callback\n   *\n   * return false when: 1. parsing error 2. rule is null\n   */\n  public boolean doInit(String targetServiceName) {\n    if (!isServerContainRule(targetServiceName)) {\n      return false;\n    }\n    if (!serviceInfoCacheMap.containsKey(targetServiceName)) {\n      synchronized (lock) {\n        if (serviceInfoCacheMap.containsKey(targetServiceName)) {\n          return true;\n        }\n        return addAllRule(targetServiceName);\n      }\n    }\n    return true;\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(GovernanceConfigurationChangedEvent event) {\n    for (String key : event.getChangedConfigurations()) {\n      if (key.startsWith(ROUTE_RULE_PREFIX)) {\n        serviceInfoCacheMap.remove(key.substring(ROUTE_RULE_PREFIX.length()));\n      }\n      if (key.equals(GLOBAL_ROUTE_RULE_KEY)) {\n        serviceInfoCacheMap.clear();\n      }\n    }\n  }\n\n  private boolean addAllRule(String targetServiceName) {\n    String ruleStr = environment.getProperty(String.format(ROUTE_RULE, targetServiceName), \"\");\n    if (StringUtils.isEmpty(ruleStr)) {\n      ruleStr = environment.getProperty(GLOBAL_ROUTE_RULE_KEY, \"\");\n    }\n    if (StringUtils.isEmpty(ruleStr)) {\n      return false;\n    }\n    List<PolicyRuleItem> policyRuleItemList;\n    try {\n      Yaml entityParser = new Yaml(\n          new Constructor(new TypeDescription(PolicyRuleItem[].class, PolicyRuleItem[].class), new LoaderOptions()),\n          representer);\n      policyRuleItemList = Arrays\n          .asList(entityParser.loadAs(ruleStr, PolicyRuleItem[].class));\n    } catch (Exception e) {\n      LOGGER.warn(\"Route management serialization for service {} failed: {}\", targetServiceName, e.getMessage());\n      return false;\n    }\n    if (CollectionUtils.isEmpty(policyRuleItemList)) {\n      LOGGER.warn(\"Route management serialization for service {} is empty\", targetServiceName);\n      return false;\n    }\n    ServiceInfoCache serviceInfoCache = new ServiceInfoCache(policyRuleItemList);\n    serviceInfoCacheMap.put(targetServiceName, serviceInfoCache);\n    LOGGER.info(\"Route management serialization service {} rules success, content: {}\", targetServiceName,\n        serviceInfoCache.getAllrule());\n    return true;\n  }\n\n  /**\n   * if a server don't have rule , avoid registered too many callback , it may cause memory leak\n   */\n  private boolean isServerContainRule(String targetServiceName) {\n    return !StringUtils.isEmpty(environment.getProperty(String.format(ROUTE_RULE, targetServiceName), \"\")) ||\n        !StringUtils.isEmpty(environment.getProperty(GLOBAL_ROUTE_RULE_KEY, \"\"));\n  }\n\n  public ConcurrentHashMap<String, ServiceInfoCache> getServiceInfoCacheMap() {\n    return serviceInfoCacheMap;\n  }\n\n  @VisibleForTesting\n  void refresh() {\n    serviceInfoCacheMap.clear();\n  }\n\n  public void refresh(String targetServiceName) {\n    serviceInfoCacheMap.remove(targetServiceName);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.distribute;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\n\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.model.PolicyRuleItem;\nimport org.apache.servicecomb.router.model.RouteItem;\nimport org.apache.servicecomb.router.model.TagItem;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.util.CollectionUtils;\n\npublic abstract class AbstractRouterDistributor<INSTANCE> implements\n    RouterDistributor<INSTANCE> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRouterDistributor.class);\n\n  private Function<INSTANCE, String> getVersion;\n\n  private Function<INSTANCE, String> getServerName;\n\n  private Function<INSTANCE, Map<String, String>> getProperties;\n\n  private RouterRuleCache routerRuleCache;\n\n  @Autowired\n  public void setRouterRuleCache(RouterRuleCache routerRuleCache) {\n    this.routerRuleCache = routerRuleCache;\n  }\n\n  protected AbstractRouterDistributor() {\n  }\n\n  /**\n   * distribute logic:\n   * 1、First according to the set route rules to choose target instances, if have just return.\n   * 2、if route rules not match instance, check if fallback rules are set, if set and match instances then return.\n   * 3、if route and fallback routes all have not match instance, then if route rules weight count less 100, return\n   * unset instances, otherwise return all instances.\n   * @param targetServiceName\n   * @param list\n   * @param invokeRule\n   * @return\n   */\n  @Override\n  public List<INSTANCE> distribute(String targetServiceName, List<INSTANCE> list, PolicyRuleItem invokeRule) {\n    invokeRule.check();\n\n    // unSetTags instance list\n    List<INSTANCE> unSetTagInstances = new ArrayList<>();\n\n    // record fallback router targItem instance\n    Map<TagItem, List<INSTANCE>> fallbackVersionServerMap = new HashMap<>();\n\n    // get tag instance map, fallbackVersionServerMap, unSetTagInstances\n    Map<TagItem, List<INSTANCE>> versionServerMap = getDistributList(targetServiceName, list, invokeRule,\n        unSetTagInstances, fallbackVersionServerMap);\n\n    // weight calculation to obtain the next tags instance\n    TagItem targetTag = getFilteredServerTagItem(invokeRule, targetServiceName);\n    if (targetTag != null && versionServerMap.containsKey(targetTag)) {\n      return versionServerMap.get(targetTag);\n    }\n\n    if (!fallbackVersionServerMap.isEmpty()) {\n      // weight calculation to obtain the next fallback tags instance\n      TagItem fallbackTargetTag = getFallbackFilteredServerTagItem(invokeRule, targetServiceName);\n      if (fallbackTargetTag != null && fallbackVersionServerMap.containsKey(fallbackTargetTag)) {\n        return fallbackVersionServerMap.get(fallbackTargetTag);\n      }\n    }\n\n    // has weightLess situation and unSetTagInstances has values\n    if (invokeRule.isWeightLess() && !unSetTagInstances.isEmpty()) {\n      return unSetTagInstances;\n    }\n    if (invokeRule.isEmptyProtection()) {\n      return list;\n    }\n\n    // weight set 100 but not matched any instance, then return empty when emptyProtection close\n    return Collections.emptyList();\n  }\n\n  @Override\n  public void init(Function<INSTANCE, String> getVersion,\n      Function<INSTANCE, String> getServerName,\n      Function<INSTANCE, Map<String, String>> getProperties) {\n    this.getVersion = getVersion;\n    this.getServerName = getServerName;\n    this.getProperties = getProperties;\n  }\n\n  public TagItem getFilteredServerTagItem(PolicyRuleItem rule, String targetServiceName) {\n    return routerRuleCache.getServiceInfoCacheMap().get(targetServiceName)\n        .getNextInvokeVersion(rule);\n  }\n\n  public TagItem getFallbackFilteredServerTagItem(PolicyRuleItem rule, String targetServiceName) {\n    return routerRuleCache.getServiceInfoCacheMap().get(targetServiceName)\n        .getFallbackNextInvokeVersion(rule);\n  }\n\n  /**\n   * 1.filter set route rules targetService, build fallback targetService map and unSetTagInstances list.\n   * 2.establish map is a more complicate way than direct traversal， because of multiple matches.\n   *\n   * the method getProperties() contains other field that we don't need.\n   */\n  private Map<TagItem, List<INSTANCE>> getDistributList(String serviceName, List<INSTANCE> list,\n      PolicyRuleItem invokeRule, List<INSTANCE> unSetTagInstances, Map<TagItem, List<INSTANCE>> fallbackVersionMap) {\n    Map<TagItem, List<INSTANCE>> versionServerMap = new HashMap<>();\n    for (INSTANCE instance : list) {\n      //get server\n      if (getServerName.apply(instance).equals(serviceName)) {\n        TagItem tagItem = new TagItem(getVersion.apply(instance), getProperties.apply(instance));\n        // route most matching TagItem\n        TagItem targetTag = buildTargetTag(invokeRule.getRoute(), tagItem);\n        if (targetTag != null) {\n          if (!versionServerMap.containsKey(targetTag)) {\n            versionServerMap.put(targetTag, new ArrayList<>());\n          }\n          versionServerMap.get(targetTag).add(instance);\n        } else {\n          // not matched, placed in the unset tag instances collection\n          unSetTagInstances.add(instance);\n        }\n        // ensure the tags can build when set for both route and fallback at the same time\n        if (!CollectionUtils.isEmpty(invokeRule.getFallback())) {\n          // fallback most matching TagItem\n          TagItem targetTagFallback = buildTargetTag(invokeRule.getFallback(), tagItem);\n          if (!fallbackVersionMap.containsKey(targetTagFallback)) {\n            fallbackVersionMap.put(targetTagFallback, new ArrayList<>());\n          }\n          fallbackVersionMap.get(targetTagFallback).add(instance);\n        }\n      }\n    }\n    return versionServerMap;\n  }\n\n  private TagItem buildTargetTag(List<RouteItem> route, TagItem tagItem) {\n    int maxMatch = 0;\n    TagItem targetTag = null;\n    // obtain the rule with the most parameter matches\n    for (RouteItem entry : route) {\n      if (entry.getTagitem() == null){\n        continue;\n      }\n      int nowMatch = entry.getTagitem().matchNum(tagItem);\n      if (nowMatch > maxMatch) {\n        maxMatch = nowMatch;\n        targetTag = entry.getTagitem();\n      }\n    }\n    return targetTag;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/distribute/RouterDistributor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.distribute;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.function.Function;\n\nimport org.apache.servicecomb.router.model.PolicyRuleItem;\n\n/**\n * @author GuoYl123\n * @since 2019/10/17\n **/\npublic interface RouterDistributor<INSTANCE> {\n\n  void init(Function<INSTANCE, String> getVersion,\n      Function<INSTANCE, String> getServerName,\n      Function<INSTANCE, Map<String, String>> getProperties);\n\n  List<INSTANCE> distribute(String targetServiceName, List<INSTANCE> list, PolicyRuleItem invokeRule);\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/exception/RouterIllegalParamException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.exception;\n\n/**\n * @author GuoYl123\n * @since 2019/11/4\n **/\npublic class RouterIllegalParamException extends RuntimeException {\n\n  private static final long serialVersionUID = 4359709211352400087L;\n\n  public RouterIllegalParamException(String message) {\n    super(message);\n  }\n\n  public RouterIllegalParamException(String message, Throwable cause) {\n    super(message, cause);\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/match/RouterRuleMatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.match;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.marker.RequestProcessor;\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.model.PolicyRuleItem;\n\npublic class RouterRuleMatcher {\n  private final RouterRuleCache routerRuleCache;\n\n  private final RequestProcessor requestProcessor;\n\n  public RouterRuleMatcher(RouterRuleCache routerRuleCache, RequestProcessor requestProcessor) {\n    this.routerRuleCache = routerRuleCache;\n    this.requestProcessor = requestProcessor;\n  }\n\n  public PolicyRuleItem match(String serviceName, GovernanceRequestExtractor request) {\n    for (PolicyRuleItem rule : routerRuleCache.getServiceInfoCacheMap().get(serviceName)\n        .getAllrule()) {\n      if (rule.getMatch() == null || requestProcessor.match(request, rule.getMatch())) {\n        return rule;\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/model/HeaderRule.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.model;\n\nimport org.apache.servicecomb.router.exception.RouterIllegalParamException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * @author GuoYl123\n * @since 2019/10/17\n **/\npublic class HeaderRule {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(HeaderRule.class);\n\n  private String regex;\n\n  private boolean caseInsensitive = true;\n\n  private String exact;\n\n  public HeaderRule() {\n  }\n\n  public boolean match(String str) {\n    if (str == null) {\n      return false;\n    }\n    if (exact == null && regex == null) {\n      throw new RouterIllegalParamException(\n          \"route management regex and exact can not br null at same time.\");\n    }\n    if (caseInsensitive) {\n      str = str.toLowerCase();\n      exact = exact == null ? null : exact.toLowerCase();\n      regex = regex == null ? null : regex.toLowerCase();\n    }\n    if (exact != null && !str.equals(exact)) {\n      return false;\n    }\n    try {\n      if (regex != null && !str.matches(regex)) {\n        return false;\n      }\n    } catch (Exception e) {\n      LOGGER.error(\"route management wrong regular expression format: {}\", regex);\n      return false;\n    }\n    return true;\n  }\n\n  public String getRegex() {\n    return regex;\n  }\n\n  public void setRegex(String regex) {\n    this.regex = regex;\n  }\n\n  public boolean isCaseInsensitive() {\n    return caseInsensitive;\n  }\n\n  public void setCaseInsensitive(boolean caseInsensitive) {\n    this.caseInsensitive = caseInsensitive;\n  }\n\n  public String getExact() {\n    return exact;\n  }\n\n  public void setExact(String exact) {\n    this.exact = exact;\n  }\n\n  @Override\n  public String toString() {\n    return \"HeaderRule{\" +\n        \"regex='\" + regex + '\\'' +\n        \", caseInsensitive=\" + caseInsensitive +\n        \", exact='\" + exact + '\\'' +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.model;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.marker.Matcher;\nimport org.apache.servicecomb.router.exception.RouterIllegalParamException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\n/**\n * @author GuoYl123\n * @since 2019/10/17\n **/\npublic class PolicyRuleItem implements Comparable<PolicyRuleItem> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(PolicyRuleItem.class);\n\n  private Integer precedence;\n\n  private Matcher match;\n\n  private List<RouteItem> route;\n\n  private Integer total;\n\n  private boolean weightLess = false;\n\n  private List<RouteItem> fallback;\n\n  private Integer fallbackTotal;\n\n  private boolean emptyProtection = true;\n\n  public PolicyRuleItem() {\n  }\n\n  /**\n   * if weight is less than 100, fill with minimum version\n   *\n   */\n  public void check() {\n    if (CollectionUtils.isEmpty(route)) {\n      throw new RouterIllegalParamException(\"canary rule list can not be null\");\n    }\n    int sum = 0;\n    for (RouteItem item : route) {\n      if (item.getWeight() == null) {\n        throw new RouterIllegalParamException(\"canary rule weight can not be null\");\n      }\n      sum += item.getWeight();\n    }\n    if (sum > 100) {\n      LOGGER.warn(\"canary rule weight sum is more than 100\");\n    } else if (sum < 100) {\n      weightLess = true;\n      route.add(new RouteItem(100 - sum, null));\n    }\n  }\n\n  @Override\n  public int compareTo(PolicyRuleItem param) {\n    return Integer.compare(param.precedence, this.precedence);\n  }\n\n  public Integer getPrecedence() {\n    return precedence;\n  }\n\n  public void setPrecedence(Integer precedence) {\n    this.precedence = precedence;\n  }\n\n  public Matcher getMatch() {\n    return match;\n  }\n\n  public void setMatch(Matcher match) {\n    this.match = match;\n  }\n\n  public List<RouteItem> getRoute() {\n    return route;\n  }\n\n  public void setRoute(List<RouteItem> route) {\n    this.route = route;\n  }\n\n  public Integer getTotal() {\n    return total;\n  }\n\n  public void setTotal(Integer total) {\n    this.total = total;\n  }\n\n  public boolean isWeightLess() {\n    return weightLess;\n  }\n\n  public void setWeightLess(boolean weightLess) {\n    this.weightLess = weightLess;\n  }\n\n  public List<RouteItem> getFallback() {\n    return fallback;\n  }\n\n  public void setFallback(List<RouteItem> fallback) {\n    this.fallback = fallback;\n  }\n\n  public Integer getFallbackTotal() {\n    return fallbackTotal;\n  }\n\n  public void setFallbackTotal(Integer fallbackTotal) {\n    this.fallbackTotal = fallbackTotal;\n  }\n\n  public boolean isEmptyProtection() {\n    return emptyProtection;\n  }\n\n  public void setEmptyProtection(boolean emptyProtection) {\n    this.emptyProtection = emptyProtection;\n  }\n\n  @Override\n  public String toString() {\n    return \"PolicyRuleItem{\" +\n        \"precedence=\" + precedence +\n        \", match=\" + match +\n        \", route=\" + route +\n        \", total=\" + total +\n        \", weightLess=\" + weightLess +\n        \", fallback=\" + fallback +\n        \", fallbackTotal=\" + fallbackTotal +\n        \", emptyProtection=\" + emptyProtection +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.model;\n\nimport java.util.Map;\n\n/**\n * @author GuoYl123\n * @since 2019/10/17\n **/\npublic class RouteItem implements Comparable<RouteItem> {\n\n  private Integer weight;\n  /**\n   * for load balance\n   */\n  private Integer currentWeight = 0;\n\n  private Map<String, String> tags;\n\n  private TagItem tagitem;\n\n\n  public void initTagItem() {\n    if (tags != null) {\n      tagitem = new TagItem(tags);\n    }\n  }\n\n  public void addCurrentWeight() {\n    currentWeight += weight;\n  }\n\n  public void reduceCurrentWeight(int total) {\n    currentWeight -= total;\n  }\n\n  public RouteItem() {\n  }\n\n  public RouteItem(Integer weight, TagItem tags) {\n    this.weight = weight;\n    this.tagitem = tags;\n  }\n\n  public Integer getWeight() {\n    return weight;\n  }\n\n  public void setWeight(Integer weight) {\n    this.weight = weight;\n  }\n\n  public Integer getCurrentWeight() {\n    return currentWeight;\n  }\n\n  public void setCurrentWeight(Integer currentWeight) {\n    this.currentWeight = currentWeight;\n  }\n\n  public Map<String, String> getTags() {\n    return tags;\n  }\n\n  public void setTags(Map<String, String> tags) {\n    this.tags = tags;\n  }\n\n  public TagItem getTagitem() {\n    return tagitem;\n  }\n\n  public void setTagitem(TagItem tagitem) {\n    this.tagitem = tagitem;\n  }\n\n  @Override\n  public int compareTo(RouteItem param) {\n    return Integer.compare(param.weight, this.weight);\n  }\n\n  @Override\n  public String toString() {\n    return \"RouteItem{\" +\n        \"weight=\" + weight +\n        \", currentWeight=\" + currentWeight +\n        \", tags=\" + tags +\n        \", tagitem=\" + tagitem +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/model/ServiceInfoCache.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.model;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.springframework.util.CollectionUtils;\n\n/**\n * @author GuoYl123\n * @since 2019/10/17\n **/\npublic class ServiceInfoCache {\n  private final List<PolicyRuleItem> allrule;\n\n  /**\n   * for default version\n   */\n  private TagItem latestVersionTag;\n\n  public ServiceInfoCache(List<PolicyRuleItem> policyRuleItemList) {\n    this.allrule = policyRuleItemList.stream().sorted().collect(Collectors.toList());\n\n    this.getAllrule().forEach(rule -> {\n      rule.getRoute().forEach(RouteItem::initTagItem);\n      if (!CollectionUtils.isEmpty(rule.getFallback())) {\n        rule.getFallback().forEach(RouteItem::initTagItem);\n      }\n    });\n  }\n\n  public TagItem getNextInvokeVersion(PolicyRuleItem policyRuleItem) {\n    List<RouteItem> rule = policyRuleItem.getRoute();\n    if (policyRuleItem.getTotal() == null) {\n      policyRuleItem.setTotal(rule.stream().mapToInt(RouteItem::getWeight).sum());\n    }\n    return calculateWeight(rule, policyRuleItem.getTotal());\n  }\n\n  public TagItem getFallbackNextInvokeVersion(PolicyRuleItem policyRuleItem) {\n    List<RouteItem> rule = policyRuleItem.getFallback();\n    if (policyRuleItem.getFallbackTotal() == null) {\n      policyRuleItem.setFallbackTotal(rule.stream().mapToInt(RouteItem::getWeight).sum());\n    }\n    return calculateWeight(rule, policyRuleItem.getFallbackTotal());\n  }\n\n  private TagItem calculateWeight(List<RouteItem> rule, int total) {\n    rule.forEach(RouteItem::addCurrentWeight);\n    int maxIndex = 0, maxWeight = -1;\n    for (int i = 0; i < rule.size(); i++) {\n      if (maxWeight < rule.get(i).getCurrentWeight()) {\n        maxIndex = i;\n        maxWeight = rule.get(i).getCurrentWeight();\n      }\n    }\n    rule.get(maxIndex).reduceCurrentWeight(total);\n    return rule.get(maxIndex).getTagitem();\n  }\n\n  public List<PolicyRuleItem> getAllrule() {\n    return allrule;\n  }\n\n  public TagItem getLatestVersionTag() {\n    return latestVersionTag;\n  }\n\n  public void setLatestVersionTag(TagItem latestVersionTag) {\n    this.latestVersionTag = latestVersionTag;\n  }\n\n  @Override\n  public String toString() {\n    return \"ServiceInfoCache{\" +\n        \"allrule=\" + allrule +\n        \", latestVersionTag=\" + latestVersionTag +\n        '}';\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/model/TagItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Objects;\n\n/**\n * @author  GuoYl123\n * @since  2019/10/17\n **/\npublic class TagItem {\n\n  private static final String VERSION = \"version\";\n\n  private String version;\n\n  private Map<String, String> param;\n\n  public TagItem() {\n  }\n\n  public TagItem(String version, Map<String, String> param) {\n    this.version = version;\n    this.param = param;\n  }\n\n  public TagItem(String version) {\n    this.version = version;\n    Map<String, String> param = new HashMap<>();\n    param.put(VERSION, version);\n    this.param = param;\n  }\n\n  public TagItem(Map<String, String> param) {\n    if (param.containsKey(VERSION)) {\n      this.version = param.get(VERSION);\n    }\n    this.param = param;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public Map<String, String> getParam() {\n    return param;\n  }\n\n  public void setParam(Map<String, String> param) {\n    this.param = param;\n  }\n\n  @Override\n  public int hashCode() {\n    return Objects.hash(getVersion(), getParam());\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n    if (!(o instanceof TagItem)) {\n      return false;\n    }\n    TagItem tagItem = (TagItem) o;\n    return Objects.equals(getVersion(), tagItem.getVersion()) &&\n        Objects.equals(getParam(), tagItem.getParam());\n  }\n\n  /**\n   * return match num\n   *\n   * @param item\n   * @return\n   */\n  public int matchNum(TagItem item) {\n    int cnt = 0;\n    if (version != null && !version.equals(item.version)) {\n      return 0;\n    }\n    for (Map.Entry<String, String> entry : param.entrySet()) {\n      if (item.getParam().containsKey(entry.getKey()) &&\n          !item.getParam().get(entry.getKey()).equals(entry.getValue())) {\n        return 0;\n      }\n      cnt++;\n    }\n    return cnt;\n  }\n}\n"
  },
  {
    "path": "governance/src/main/java/org/apache/servicecomb/router/util/VersionCompareUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.util;\n\nimport org.apache.servicecomb.foundation.common.Version;\n\npublic class VersionCompareUtil {\n  public static int compareVersion(String version1, String version2) {\n    return new Version(version1).compareTo(new Version(version2));\n  }\n}\n"
  },
  {
    "path": "governance/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.governance.GovernanceCommonConfiguration\norg.apache.servicecomb.router.RouterCommonConfiguration\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/AbstractFailurePredictorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractFailurePredictor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class AbstractFailurePredictorTest {\n  class MyAbstractFailurePredictor extends AbstractFailurePredictor {\n    MyAbstractFailurePredictor() {\n    }\n\n    @Override\n    protected String extractStatusCode(Object result) {\n      return (String) result;\n    }\n\n    @Override\n    public boolean isFailedResult(List<String> statusList, Throwable e) {\n      return super.isFailedResult(statusList, e);\n    }\n  }\n\n  @Test\n  public void testCodeMatch() {\n    AbstractFailurePredictor predictor = new MyAbstractFailurePredictor();\n    List<String> statusList = Arrays.asList(\"500\");\n    Assertions.assertTrue(predictor.isFailedResult(statusList, \"500\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"502\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"400\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"444\"));\n\n    statusList = Arrays.asList(\"5x0\");\n    Assertions.assertTrue(predictor.isFailedResult(statusList, \"500\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"502\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"400\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"444\"));\n\n    statusList = Arrays.asList(null, \"xx\", \"5x0\");\n    Assertions.assertTrue(predictor.isFailedResult(statusList, \"500\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"502\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"400\"));\n    Assertions.assertFalse(predictor.isFailedResult(statusList, \"444\"));\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/BulkheadHandlerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.handler.BulkheadHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.policy.BulkheadPolicy;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class BulkheadHandlerTest {\n  private BulkheadHandler bulkheadHandler;\n\n  @Autowired\n  public void setInstanceIsolationHandler(BulkheadHandler scbBulkheadHandler) {\n    this.bulkheadHandler = scbBulkheadHandler;\n  }\n\n  @Test\n  public void testMatchPriorityPolicy() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead\");\n    BulkheadPolicy policy = bulkheadHandler.matchPolicy(request);\n    Assertions.assertEquals(\"demo-bulkhead-priority\", policy.getName());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/CustomMatchTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.marker.CustomMatcher;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.marker.Matcher;\nimport org.apache.servicecomb.governance.marker.RequestProcessor;\nimport org.apache.servicecomb.governance.mockclasses.service.MockConfigurationForCustomMatcher;\nimport org.junit.Assert;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\nimport org.junit.jupiter.api.Assertions;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class, MockConfigurationForCustomMatcher.class})\npublic class CustomMatchTest {\n\n    private RequestProcessor requestProcessor;\n\n    @Autowired\n    public void setRequestProcessor(RequestProcessor requestProcessor) {\n        this.requestProcessor = requestProcessor;\n    }\n\n    private Matcher generateMatcher(String customMatcherHandler, String customMatcherParameters) {\n        CustomMatcher customMatcher = new CustomMatcher();\n        customMatcher.setCustomMatcherHandler(customMatcherHandler);\n        customMatcher.setCustomMatcherParameters(customMatcherParameters);\n        Matcher matcher = new Matcher();\n        matcher.setCustomMatcher(customMatcher);\n        return matcher;\n    }\n\n    @Test\n    public void test_should_pass_when_value_class_empty() {\n        GovernanceRequest request = new GovernanceRequest();\n        Matcher mockMatcher = generateMatcher(\"\", \"\");\n        Assert.assertTrue(this.requestProcessor.match(request, mockMatcher));\n        mockMatcher = generateMatcher(\"\", \"bill\");\n        Assert.assertTrue(this.requestProcessor.match(request, mockMatcher));\n        mockMatcher = generateMatcher(\"classWithAnnotation\", \"\");\n        Assert.assertTrue(this.requestProcessor.match(request, mockMatcher));\n    }\n\n    @Test\n    public void test_should_pass_when_value_class_match() {\n        GovernanceRequest request = new GovernanceRequest();\n        Matcher mockMatcher = generateMatcher(\"classWithAnnotation\", \"bill\");\n        Assert.assertTrue(this.requestProcessor.match(request, mockMatcher));\n    }\n\n    @Test\n    public void test_should_throw_exception_when_class_not_found() {\n        GovernanceRequest request = new GovernanceRequest();\n        try {\n            Matcher mockMatcher = generateMatcher(\"classWithAnnotationNotFound\", \"bill\");\n            this.requestProcessor.match(request, mockMatcher);\n            Assertions.fail(\"an exception is expected!\");\n        } catch (Exception e) {\n            Assert.assertTrue(e.getCause() instanceof ClassNotFoundException);\n        }\n    }\n\n    @Test\n    public void test_should_pass_when_multiple_value() {\n        GovernanceRequest request = new GovernanceRequest();\n        Matcher mockMatcher = generateMatcher(\"classWithAnnotation\", \"bill,bill2\");\n        Assert.assertTrue(this.requestProcessor.match(request, mockMatcher));\n    }\n\n    @Test\n    public void test_should_throw_exception_when_not_implements_interface() {\n        GovernanceRequest request = new GovernanceRequest();\n        try {\n            Matcher mockMatcher = generateMatcher(\"classNotImplements\", \"bill,bill2\");\n            this.requestProcessor.match(request, mockMatcher);\n            Assertions.fail(\"an exception is expected!\");\n        } catch (Exception e) {\n            Assert.assertTrue(e.getMessage().contains(RequestProcessor.errorMessageForNotImplements));\n        }\n    }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/FaultInjectionTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.governance.handler.FaultInjectionHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.processor.injection.Fault;\nimport org.apache.servicecomb.governance.processor.injection.FaultInjectionDecorators;\nimport org.apache.servicecomb.governance.processor.injection.FaultInjectionDecorators.FaultInjectionDecorateCheckedSupplier;\nimport org.apache.servicecomb.governance.processor.injection.FaultInjectionException;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class FaultInjectionTest {\n  private FaultInjectionHandler faultInjectionHandler;\n\n  private FaultInjectionHandler faultInjectionHandler2;\n\n  @Autowired\n  public void setFaultInjectionHandler(FaultInjectionHandler scbFaultInjectionHandler,\n      @Qualifier(\"faultInjectionHandler2\") FaultInjectionHandler faultInjectionHandler2) {\n    this.faultInjectionHandler = scbFaultInjectionHandler;\n    this.faultInjectionHandler2 = faultInjectionHandler2;\n  }\n\n  public FaultInjectionTest() {\n  }\n\n  @Test\n  public void test_delay_fault_injection_service_name_work() throws Throwable {\n    FaultInjectionDecorateCheckedSupplier<Object> ds =\n        FaultInjectionDecorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/faultInjectDelay\");\n    request.setServiceName(\"srcService\");\n\n    Fault fault = faultInjectionHandler.getActuator(request);\n    ds.withFaultInjection(fault);\n\n    Assertions.assertEquals(\"test\", ds.get());\n\n    // flow control\n    CountDownLatch cd = new CountDownLatch(10);\n    AtomicBoolean expected = new AtomicBoolean(false);\n    AtomicBoolean notExpected = new AtomicBoolean(false);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        try {\n          long startTime = System.currentTimeMillis();\n          Object result = ds.get();\n          if (!\"test\".equals(result)) {\n            notExpected.set(true);\n          }\n          // delayTime is 2S\n          if (System.currentTimeMillis() - startTime > 1000) {\n            expected.set(true);\n          }\n        } catch (Throwable e) {\n          notExpected.set(true);\n        }\n        cd.countDown();\n      }).start();\n    }\n    //timeout should be bigger than delayTime\n    cd.await(10, TimeUnit.SECONDS);\n    Assertions.assertFalse(notExpected.get());\n    Assertions.assertTrue(expected.get());\n  }\n\n  @Test\n  public void test_abort_fault_injection_service_name_work() throws Throwable {\n    FaultInjectionDecorateCheckedSupplier<Object> ds =\n        FaultInjectionDecorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/faultInjectAbort\");\n    request.setServiceName(\"srcService\");\n\n    Fault fault = faultInjectionHandler.getActuator(request);\n    ds.withFaultInjection(fault);\n\n    Assertions.assertEquals(\"test\", ds.get());\n\n    // flow control\n    CountDownLatch cd = new CountDownLatch(10);\n    AtomicBoolean expected = new AtomicBoolean(false);\n    AtomicBoolean notExpected = new AtomicBoolean(false);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        try {\n          Object result = ds.get();\n          if (!\"test\".equals(result)) {\n            notExpected.set(true);\n          }\n        } catch (FaultInjectionException e) {\n          expected.set(true);\n        } catch (Throwable e) {\n          notExpected.set(true);\n        }\n        cd.countDown();\n      }).start();\n    }\n    cd.await(1, TimeUnit.SECONDS);\n    Assertions.assertFalse(notExpected.get());\n    Assertions.assertTrue(expected.get());\n  }\n\n  @Test\n  public void test_fallback_returnNull_work() throws Throwable {\n    FaultInjectionDecorateCheckedSupplier<Object> ds =\n        FaultInjectionDecorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/returnNull\");\n    request.setServiceName(\"returnNull\");\n\n    Fault fault = faultInjectionHandler.getActuator(request);\n    ds.withFaultInjection(fault);\n    Assertions.assertEquals(null, ds.get());\n  }\n\n  @Test\n  public void test_fallback_ThrowException_work() throws Throwable {\n    FaultInjectionDecorateCheckedSupplier<Object> ds =\n        FaultInjectionDecorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/throwException\");\n    request.setServiceName(\"ThrowException\");\n\n    Fault fault = faultInjectionHandler.getActuator(request);\n    ds.withFaultInjection(fault);\n    boolean expected = false;\n    try {\n      ds.get();\n    } catch (FaultInjectionException e) {\n      if (e.getFaultResponse().getErrorCode() == 500) {\n        expected = true;\n      }\n    }\n    Assertions.assertEquals(true, expected);\n  }\n\n  @Test\n  public void test_fallback_forceClosed_work() throws Throwable {\n    FaultInjectionDecorateCheckedSupplier<Object> ds =\n        FaultInjectionDecorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/forceClosed\");\n    request.setServiceName(\"forceClosed\");\n\n    Fault fault = faultInjectionHandler.getActuator(request);\n    ds.withFaultInjection(fault);\n    Assertions.assertEquals(\"test\", ds.get());\n  }\n\n  @Test\n  public void test_fallback_ThrowException_work_handler2() throws Throwable {\n    FaultInjectionDecorateCheckedSupplier<Object> ds =\n        FaultInjectionDecorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/throwException\");\n    request.setServiceName(\"ThrowException\");\n\n    Fault fault = faultInjectionHandler2.getActuator(request);\n    ds.withFaultInjection(fault);\n    boolean expected = false;\n    try {\n      ds.get();\n    } catch (FaultInjectionException e) {\n      if (e.getFaultResponse().getErrorCode() == 500) {\n        expected = true;\n      }\n    }\n    Assertions.assertEquals(true, expected);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/FlowControlTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.governance.handler.RateLimitingHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCheckedSupplier;\nimport io.github.resilience4j.ratelimiter.RateLimiter;\nimport io.github.resilience4j.ratelimiter.RequestNotPermitted;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class FlowControlTest {\n  private RateLimitingHandler rateLimitingHandler;\n\n  @Autowired\n  public void setRateLimitingHandler(RateLimitingHandler rateLimitingHandler) {\n    this.rateLimitingHandler = rateLimitingHandler;\n  }\n\n  public FlowControlTest() {\n  }\n\n  @Test\n  public void test_rate_limiting_work() throws Throwable {\n    DecorateCheckedSupplier<Object> ds = Decorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/hello\");\n\n    RateLimiter rateLimiter = rateLimitingHandler.getActuator(request);\n    ds.withRateLimiter(rateLimiter);\n\n    Assertions.assertEquals(\"test\", ds.get());\n\n    // flow control\n    CountDownLatch cd = new CountDownLatch(10);\n    AtomicBoolean expected = new AtomicBoolean(false);\n    AtomicBoolean notExpected = new AtomicBoolean(false);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        try {\n          Object result = ds.get();\n          if (!\"test\".equals(result)) {\n            notExpected.set(true);\n          }\n        } catch (Throwable e) {\n          if (e instanceof RequestNotPermitted) {\n            expected.set(true);\n          } else {\n            notExpected.set(true);\n          }\n        }\n        cd.countDown();\n      }).start();\n    }\n    cd.await(1, TimeUnit.SECONDS);\n    Assertions.assertTrue(expected.get());\n    Assertions.assertFalse(notExpected.get());\n  }\n\n  @Test\n  public void test_rate_limiting_service_name_work() throws Throwable {\n    DecorateCheckedSupplier<Object> ds = Decorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/helloServiceName\");\n    request.setServiceName(\"srcService\");\n\n    RateLimiter rateLimiter = rateLimitingHandler.getActuator(request);\n    ds.withRateLimiter(rateLimiter);\n\n    Assertions.assertEquals(\"test\", ds.get());\n\n    // flow control\n    CountDownLatch cd = new CountDownLatch(10);\n    AtomicBoolean expected = new AtomicBoolean(false);\n    AtomicBoolean notExpected = new AtomicBoolean(false);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        try {\n          Object result = ds.get();\n          if (!\"test\".equals(result)) {\n            notExpected.set(true);\n          }\n        } catch (Throwable e) {\n          if (e instanceof RequestNotPermitted) {\n            expected.set(true);\n          } else {\n            notExpected.set(true);\n          }\n        }\n        cd.countDown();\n      }).start();\n    }\n    cd.await(1, TimeUnit.SECONDS);\n    Assertions.assertTrue(expected.get());\n    Assertions.assertFalse(notExpected.get());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/GovernanceCacheHandlerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance;\n\n\nimport org.apache.servicecomb.governance.handler.GovernanceCacheHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.policy.GovernanceCachePolicy;\nimport org.apache.servicecomb.governance.service.GovernanceCache;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class GovernanceCacheHandlerTest {\n  private GovernanceCacheHandler<String, Object> governanceCacheHandler;\n\n  @Autowired\n  public void setInstanceIsolationHandler(@Autowired GovernanceCacheHandler<String, Object> governanceCacheHandler) {\n    this.governanceCacheHandler = governanceCacheHandler;\n  }\n\n  @Test\n  public void testMatchPriorityPolicy() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/governanceCache\");\n    GovernanceCachePolicy policy = governanceCacheHandler.matchPolicy(request);\n    Assertions.assertEquals(\"demo-governanceCache\", policy.getName());\n    GovernanceCache<String, Object> governanceCache = governanceCacheHandler.getActuator(request);\n    governanceCache.putValueIntoCache(\"governance\", \"Cache\");\n    Object cache = governanceCache.getValueFromCache(\"governance\");\n    Assertions.assertEquals(\"Cache\", cache);\n    governanceCache.putValueIntoCache(\"response\", null);\n    Object response = governanceCache.getValueFromCache(\"response\");\n    Assertions.assertNull(response);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/GovernancePropertiesTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.time.Duration;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.apache.servicecomb.governance.marker.Matcher;\nimport org.apache.servicecomb.governance.marker.TrafficMarker;\nimport org.apache.servicecomb.governance.policy.AbstractPolicy;\nimport org.apache.servicecomb.governance.policy.BulkheadPolicy;\nimport org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;\nimport org.apache.servicecomb.governance.policy.FaultInjectionPolicy;\nimport org.apache.servicecomb.governance.policy.GovernanceCachePolicy;\nimport org.apache.servicecomb.governance.policy.RateLimitingPolicy;\nimport org.apache.servicecomb.governance.policy.RetryPolicy;\nimport org.apache.servicecomb.governance.policy.TimeLimiterPolicy;\nimport org.apache.servicecomb.governance.processor.injection.FaultInjectionConst;\nimport org.apache.servicecomb.governance.properties.BulkheadProperties;\nimport org.apache.servicecomb.governance.properties.CircuitBreakerProperties;\nimport org.apache.servicecomb.governance.properties.FaultInjectionProperties;\nimport org.apache.servicecomb.governance.properties.GovernanceCacheProperties;\nimport org.apache.servicecomb.governance.properties.GovernanceProperties;\nimport org.apache.servicecomb.governance.properties.InstanceIsolationProperties;\nimport org.apache.servicecomb.governance.properties.MatchProperties;\nimport org.apache.servicecomb.governance.properties.RateLimitProperties;\nimport org.apache.servicecomb.governance.properties.RetryProperties;\nimport org.apache.servicecomb.governance.properties.TimeLimiterProperties;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class GovernancePropertiesTest {\n  private List<GovernanceProperties<? extends AbstractPolicy>> propertiesList;\n\n  private MatchProperties matchProperties;\n\n  private BulkheadProperties bulkheadProperties;\n\n  private CircuitBreakerProperties circuitBreakerProperties;\n\n  private TimeLimiterProperties timeLimiterProperties;\n\n  private GovernanceCacheProperties governanceCacheProperties;\n\n  private InstanceIsolationProperties instanceIsolationProperties;\n\n  private RateLimitProperties rateLimitProperties;\n\n  private RetryProperties retryProperties;\n\n  private FaultInjectionProperties faultInjectionProperties;\n\n  private Environment environment;\n\n  @Autowired\n  public void setPropertiesList(List<GovernanceProperties<? extends AbstractPolicy>> propertiesList) {\n    this.propertiesList = propertiesList;\n  }\n\n  @Autowired\n  public void setMatchProperties(MatchProperties scbMatchProperties) {\n    this.matchProperties = scbMatchProperties;\n  }\n\n  @Autowired\n  public void setBulkheadProperties(BulkheadProperties scbBulkheadProperties) {\n    this.bulkheadProperties = scbBulkheadProperties;\n  }\n\n  @Autowired\n  public void setCircuitBreakerProperties(CircuitBreakerProperties scbCircuitBreakerProperties) {\n    this.circuitBreakerProperties = scbCircuitBreakerProperties;\n  }\n\n  @Autowired\n  public void setTimeLimiterProperties(TimeLimiterProperties scbTimeLimiterProperties) {\n    this.timeLimiterProperties = scbTimeLimiterProperties;\n  }\n\n  @Autowired\n  public void setGovernanceCacheProperties(GovernanceCacheProperties scbGovernanceCacheProperties) {\n    this.governanceCacheProperties = scbGovernanceCacheProperties;\n  }\n\n  @Autowired\n  public void setRateLimitProperties(RateLimitProperties scbRateLimitProperties) {\n    this.rateLimitProperties = scbRateLimitProperties;\n  }\n\n  @Autowired\n  public void setInstanceIsolationProperties(InstanceIsolationProperties scbInstanceIsolationProperties) {\n    this.instanceIsolationProperties = scbInstanceIsolationProperties;\n  }\n\n  @Autowired\n  public void setRetryProperties(RetryProperties scbRetryProperties) {\n    this.retryProperties = scbRetryProperties;\n  }\n\n  @Autowired\n  public void setFaultInjectionProperties(\n      FaultInjectionProperties scbFaultInjectionProperties) {\n    this.faultInjectionProperties = scbFaultInjectionProperties;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setDynamicValues(Map<String, Object> dynamicValues) {\n    this.dynamicValues = dynamicValues;\n  }\n\n  public GovernancePropertiesTest() {\n  }\n\n  private Map<String, Object> dynamicValues = new HashMap<>();\n\n  private static final float DELTA = 0.0000001f;\n\n  @BeforeEach\n  public void setUp() {\n    ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;\n\n    if (configurableEnvironment.getPropertySources().contains(\"testDynamicChange\")) {\n      configurableEnvironment.getPropertySources().remove(\"testDynamicChange\");\n    }\n\n    configurableEnvironment.getPropertySources()\n        .addFirst(new EnumerablePropertySource<Map<String, Object>>(\"testDynamicChange\", dynamicValues) {\n          @Override\n          public Object getProperty(String s) {\n            return this.getSource().get(s);\n          }\n\n          @Override\n          public String[] getPropertyNames() {\n            return this.getSource().keySet().toArray(new String[0]);\n          }\n        });\n  }\n\n  @AfterEach\n  public void tearDown() {\n    Set<String> keys = dynamicValues.keySet();\n    keys.forEach(k -> dynamicValues.put(k, null));\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n  }\n\n  @Test\n  public void test_all_bean_is_loaded() {\n    Assertions.assertEquals(16, propertiesList.size());\n  }\n\n  @Test\n  public void test_match_properties_successfully_loaded() {\n    Map<String, TrafficMarker> markers = matchProperties.getParsedEntity();\n    TrafficMarker demoRateLimiting = markers.get(\"demo-rateLimiting\");\n    List<Matcher> matchers = demoRateLimiting.getMatches();\n    Assertions.assertEquals(1, matchers.size());\n    Matcher matcher = matchers.get(0);\n    Assertions.assertEquals(\"/hello\", matcher.getApiPath().get(\"exact\"));\n\n    TrafficMarker demoBulkhead = markers.get(\"demo-bulkhead\");\n    matchers = demoBulkhead.getMatches();\n    Assertions.assertEquals(2, matchers.size());\n    matcher = matchers.get(0);\n    Assertions.assertEquals(\"/bulkhead\", matcher.getApiPath().get(\"exact\"));\n    Assertions.assertEquals(\"matchPath\", matcher.getName());\n  }\n\n  @Test\n  public void test_match_properties_delete() {\n    Map<String, TrafficMarker> markers = matchProperties.getParsedEntity();\n    Assertions.assertEquals(null, markers.get(\"test\"));\n    dynamicValues.put(\"servicecomb.matchGroup.test\", \"matches:\\n\"\n        + \"  - apiPath:\\n\"\n        + \"      exact: \\\"/hello2\\\"\\n\"\n        + \"    name: match0\");\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n    markers = matchProperties.getParsedEntity();\n    Assertions.assertEquals(1, markers.get(\"test\").getMatches().size());\n    tearDown();\n    markers = matchProperties.getParsedEntity();\n    Assertions.assertEquals(null, markers.get(\"test\"));\n  }\n\n  @Test\n  public void test_match_properties_changed() {\n    dynamicValues.put(\"servicecomb.matchGroup.demo-rateLimiting\", \"matches:\\n\"\n        + \"  - apiPath:\\n\"\n        + \"      exact: \\\"/hello2\\\"\\n\"\n        + \"    name: match0\");\n    dynamicValues.put(\"servicecomb.matchGroup.demo-rateLimiting2\", \"matches:\\n\"\n        + \"  - apiPath:\\n\"\n        + \"      exact: \\\"/hello2\\\"\\n\"\n        + \"    name: match0\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, TrafficMarker> markers = matchProperties.getParsedEntity();\n    TrafficMarker demoRateLimiting = markers.get(\"demo-rateLimiting\");\n    List<Matcher> matchers = demoRateLimiting.getMatches();\n    Assertions.assertEquals(1, matchers.size());\n    Matcher matcher = matchers.get(0);\n    Assertions.assertEquals(\"/hello2\", matcher.getApiPath().get(\"exact\"));\n\n    demoRateLimiting = markers.get(\"demo-rateLimiting2\");\n    matchers = demoRateLimiting.getMatches();\n    Assertions.assertEquals(1, matchers.size());\n    matcher = matchers.get(0);\n    Assertions.assertEquals(\"/hello2\", matcher.getApiPath().get(\"exact\"));\n  }\n\n  @Test\n  public void test_bulkhead_properties_changed() {\n    dynamicValues.put(\"servicecomb.bulkhead.demo-bulkhead\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 2\\n\"\n        + \"maxWaitDuration: 2000\");\n    dynamicValues.put(\"servicecomb.bulkhead.bulkhead1\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 3\\n\"\n        + \"maxWaitDuration: 3000\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();\n    Assertions.assertEquals(3, policies.size());\n    BulkheadPolicy policy = policies.get(\"demo-bulkhead\");\n    Assertions.assertEquals(2, policy.getMaxConcurrentCalls());\n    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n\n    policies = bulkheadProperties.getParsedEntity();\n    Assertions.assertEquals(3, policies.size());\n    policy = policies.get(\"bulkhead1\");\n    Assertions.assertEquals(3, policy.getMaxConcurrentCalls());\n    Assertions.assertEquals(3000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n    Assertions.assertEquals(\"bulkhead1\", policy.getName());\n  }\n\n  @Test\n  public void test_bulkhead_properties_bound() {\n    dynamicValues.put(\"servicecomb.bulkhead.test-bulkhead1\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 0\\n\"\n        + \"maxWaitDuration: 2000\");\n    dynamicValues.put(\"servicecomb.bulkhead.test-bulkhead2\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 1000\\n\"\n        + \"maxWaitDuration: 0\");\n    dynamicValues.put(\"servicecomb.bulkhead.test-bulkhead3\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 0\\n\"\n        + \"maxWaitDuration: 2S\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();\n    Assertions.assertEquals(5, policies.size());\n    BulkheadPolicy policy = policies.get(\"test-bulkhead1\");\n    Assertions.assertEquals(0, policy.getMaxConcurrentCalls());\n    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n\n    policy = policies.get(\"test-bulkhead2\");\n    Assertions.assertEquals(1000, policy.getMaxConcurrentCalls());\n    Assertions.assertEquals(0, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n    Assertions.assertEquals(\"test-bulkhead2\", policy.getName());\n\n    policy = policies.get(\"test-bulkhead3\");\n    Assertions.assertEquals(0, policy.getMaxConcurrentCalls());\n    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n    Assertions.assertEquals(\"test-bulkhead3\", policy.getName());\n  }\n\n  @Test\n  public void test_bulkhead_properties_successfully_loaded() {\n    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();\n    Assertions.assertEquals(2, policies.size());\n    BulkheadPolicy policy = policies.get(\"demo-bulkhead\");\n    Assertions.assertEquals(1, policy.getMaxConcurrentCalls());\n    Assertions.assertEquals(3000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n  }\n\n  @Test\n  public void test_timelimiter_properties_successfully_loaded() {\n    Map<String, TimeLimiterPolicy> policies = timeLimiterProperties.getParsedEntity();\n    Assertions.assertEquals(2, policies.size());\n    TimeLimiterPolicy timeLimiterPolicy = policies.get(\"demo-timeLimiter-other\");\n    Assertions.assertEquals(2000, Duration.parse(timeLimiterPolicy.getTimeoutDuration()).toMillis());\n    Assertions.assertEquals(false, timeLimiterPolicy.isCancelRunningFuture());\n  }\n\n  @Test\n  public void test_timelimiter_properties_bound() {\n    dynamicValues.put(\"servicecomb.timeLimiter.name1\", \"rules:\\n\"\n        + \"timeoutDuration: 5000\\n\"\n        + \"cancelRunningFuture: false\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, TimeLimiterPolicy> policies = timeLimiterProperties.getParsedEntity();\n    Assertions.assertEquals(3, policies.size());\n    TimeLimiterPolicy policy = policies.get(\"name1\");\n    Assertions.assertEquals(false, policy.isCancelRunningFuture());\n    Assertions.assertEquals(5000, Duration.parse(policy.getTimeoutDuration()).toMillis());\n  }\n\n  @Test\n  public void test_governanceCache_properties_successfully_loaded() {\n    Map<String, GovernanceCachePolicy> policies = governanceCacheProperties.getParsedEntity();\n    Assertions.assertEquals(2, policies.size());\n    GovernanceCachePolicy governanceCachePolicy = policies.get(\"demo-governanceCache-other\");\n    Assertions.assertEquals(15, governanceCachePolicy.getConcurrencyLevel());\n    Assertions.assertEquals(50000, governanceCachePolicy.getMaximumSize());\n    Assertions.assertEquals(666666, Duration.parse(governanceCachePolicy.getTtl()).toMillis());\n  }\n\n  @Test\n  public void test_governanceCache_properties_bound() {\n    dynamicValues.put(\"servicecomb.cache.name1\", \"rules:\\n\"\n        + \"ttl: 3000000\\n\"\n        + \"maximumSize: 2000\\n\"\n        + \"concurrencyLevel: 6\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, GovernanceCachePolicy> policies = governanceCacheProperties.getParsedEntity();\n    Assertions.assertEquals(3, policies.size());\n    GovernanceCachePolicy policy = policies.get(\"name1\");\n    Assertions.assertEquals(3000000, Duration.parse(policy.getTtl()).toMillis());\n    Assertions.assertEquals(2000, policy.getMaximumSize());\n    Assertions.assertEquals(6, policy.getConcurrencyLevel());\n  }\n\n  @Test\n  public void test_circuit_breaker_properties_successfully_loaded() {\n    Map<String, CircuitBreakerPolicy> policies = circuitBreakerProperties.getParsedEntity();\n    Assertions.assertEquals(1, policies.size());\n    CircuitBreakerPolicy policy = policies.get(\"demo-circuitBreaker\");\n    Assertions.assertEquals(2, policy.getMinimumNumberOfCalls());\n    Assertions.assertEquals(\"2\", policy.getSlidingWindowSize());\n  }\n\n  @Test\n  public void test_circuit_breaker_properties_Of_windows_size() {\n    dynamicValues.put(\"servicecomb.circuitBreaker.name1\", \"rules:\\n\"\n        + \"slidingWindowType: count\\n\"\n        + \"slidingWindowSize: 2\");\n    dynamicValues.put(\"servicecomb.circuitBreaker.name2\", \"rules:\\n\"\n        + \"slidingWindowType: time\\n\"\n        + \"slidingWindowSize: 2\");\n    dynamicValues.put(\"servicecomb.circuitBreaker.name3\", \"rules:\\n\"\n        + \"slidingWindowType: test\\n\"\n        + \"slidingWindowSize: 1M\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, CircuitBreakerPolicy> policies = circuitBreakerProperties.getParsedEntity();\n    Assertions.assertEquals(4, policies.size());\n    CircuitBreakerPolicy policy = policies.get(\"name1\");\n    Assertions.assertEquals(\"count\", policy.getSlidingWindowType());\n    Assertions.assertEquals(\"2\", policy.getSlidingWindowSize());\n\n    policy = policies.get(\"name2\");\n    Assertions.assertEquals(\"time\", policy.getSlidingWindowType());\n    Assertions.assertEquals(\"2\", policy.getSlidingWindowSize());\n\n    policy = policies.get(\"name3\");\n    Assertions.assertEquals(\"60\", policy.getSlidingWindowSize());\n  }\n\n  @Test\n  public void test_circuit_breaker_properties_Of_type() {\n    dynamicValues.put(\"servicecomb.circuitBreaker.type1\", \"rules:\\n\"\n        + \"failureRateThreshold: 20\\n\"\n        + \"slowCallRateThreshold: 100\");\n    dynamicValues.put(\"servicecomb.circuitBreaker.type2\", \"rules:\\n\"\n        + \"failureRateThreshold: 20.33\\n\"\n        + \"slowCallRateThreshold: 0.01\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, CircuitBreakerPolicy> policies = circuitBreakerProperties.getParsedEntity();\n    CircuitBreakerPolicy policy = policies.get(\"type1\");\n    Assertions.assertEquals(20.0f, policy.getFailureRateThreshold(), DELTA);\n    Assertions.assertEquals(100.0f, policy.getSlowCallRateThreshold(), DELTA);\n\n    policy = policies.get(\"type2\");\n    Assertions.assertEquals(20.33f, policy.getFailureRateThreshold(), DELTA);\n    Assertions.assertEquals(0.01f, policy.getSlowCallRateThreshold(), DELTA);\n  }\n\n  @Test\n  public void test_rate_limit_properties_successfully_loaded() {\n    Map<String, RateLimitingPolicy> policies = rateLimitProperties.getParsedEntity();\n    Assertions.assertEquals(2, policies.size());\n    RateLimitingPolicy policy = policies.get(\"demo-rateLimiting\");\n    Assertions.assertEquals(1, policy.getRate());\n  }\n\n  @Test\n  public void test_retry_properties_successfully_loaded() {\n    Map<String, RetryPolicy> policies = retryProperties.getParsedEntity();\n    Assertions.assertEquals(1, policies.size());\n    RetryPolicy policy = policies.get(\"demo-retry\");\n    Assertions.assertEquals(3, policy.getMaxAttempts());\n  }\n\n\n  @Test\n  public void test_properties_changed_to_duration() {\n    dynamicValues.put(\"servicecomb.bulkhead.test1\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 2\\n\"\n        + \"maxWaitDuration: 2S\");\n    dynamicValues.put(\"servicecomb.bulkhead.test2\", \"rules:\\n\"\n        + \"maxConcurrentCalls: 3\\n\"\n        + \"maxWaitDuration: 1M\");\n\n    GovernanceEventManager.post(new GovernanceConfigurationChangedEvent(new HashSet<>(dynamicValues.keySet())));\n\n    Map<String, BulkheadPolicy> policies = bulkheadProperties.getParsedEntity();\n    Assertions.assertEquals(4, policies.size());\n    BulkheadPolicy policy = policies.get(\"test1\");\n    Assertions.assertEquals(2000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n\n    policies = bulkheadProperties.getParsedEntity();\n    Assertions.assertEquals(4, policies.size());\n    policy = policies.get(\"test2\");\n    Assertions.assertEquals(60000, Duration.parse(policy.getMaxWaitDuration()).toMillis());\n  }\n\n  @Test\n  public void test_instance_isolation_properties_successfully_loaded() {\n    Map<String, CircuitBreakerPolicy> policies = instanceIsolationProperties.getParsedEntity();\n    Assertions.assertEquals(1, policies.size());\n    CircuitBreakerPolicy policy = policies.get(\"demo-allOperation\");\n    Assertions.assertEquals(2, policy.getMinimumNumberOfCalls());\n    Assertions.assertEquals(\"2\", policy.getSlidingWindowSize());\n  }\n\n  @Test\n  public void test_fault_injection_properties_successfully_loaded() {\n    Map<String, FaultInjectionPolicy> policies = faultInjectionProperties.getParsedEntity();\n    Assertions.assertEquals(5, policies.size());\n    FaultInjectionPolicy policy = policies.get(\"demo-faultInjectDelay\");\n    Assertions.assertEquals(FaultInjectionConst.TYPE_DELAY, policy.getType());\n    Assertions.assertEquals(2000, policy.getDelayTimeToMillis());\n    Assertions.assertEquals(100, policy.getPercentage());\n\n    policy = policies.get(\"demo-faultInjectAbort\");\n    Assertions.assertEquals(FaultInjectionConst.TYPE_ABORT, policy.getType());\n    Assertions.assertEquals(50, policy.getPercentage());\n    Assertions.assertEquals(500, policy.getErrorCode());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/IdentifierRateLimitingHandlerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.apache.servicecomb.governance.handler.IdentifierRateLimitingHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCheckedSupplier;\nimport io.github.resilience4j.ratelimiter.RateLimiter;\nimport io.github.resilience4j.ratelimiter.RequestNotPermitted;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class IdentifierRateLimitingHandlerTest {\n  private IdentifierRateLimitingHandler rateLimitingHandler;\n\n  @Autowired\n  public void setRateLimitingHandler(IdentifierRateLimitingHandler rateLimitingHandler) {\n    this.rateLimitingHandler = rateLimitingHandler;\n  }\n\n  public IdentifierRateLimitingHandlerTest() {\n  }\n\n  @Test\n  public void test_rate_limiting_work() throws Throwable {\n    DecorateCheckedSupplier<Object> ds = Decorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/hello\");\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"test\", \"1234\");\n    request.setHeaders(headers);\n\n    RateLimiter rateLimiter = rateLimitingHandler.getActuator(request);\n    ds.withRateLimiter(rateLimiter);\n\n    Assertions.assertEquals(\"test\", ds.get());\n\n    // flow control\n    CountDownLatch cd = new CountDownLatch(10);\n    AtomicBoolean expected = new AtomicBoolean(false);\n    AtomicBoolean notExpected = new AtomicBoolean(false);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        try {\n          Object result = ds.get();\n          if (!\"test\".equals(result)) {\n            notExpected.set(true);\n          }\n        } catch (Throwable e) {\n          if (e instanceof RequestNotPermitted) {\n            expected.set(true);\n          } else {\n            notExpected.set(true);\n          }\n        }\n        cd.countDown();\n      }).start();\n    }\n    cd.await(1, TimeUnit.SECONDS);\n    Assertions.assertTrue(expected.get());\n    Assertions.assertFalse(notExpected.get());\n  }\n\n  @Test\n  public void test_rate_limiting_service_name_work() throws Throwable {\n    DecorateCheckedSupplier<Object> ds = Decorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/helloServiceName\");\n    request.setServiceName(\"srcService\");\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"test\", \"1234\");\n    request.setHeaders(headers);\n\n    RateLimiter rateLimiter = rateLimitingHandler.getActuator(request);\n    ds.withRateLimiter(rateLimiter);\n\n    Assertions.assertEquals(\"test\", ds.get());\n\n    headers = new HashMap<>();\n    headers.put(\"test\", \"12345\");\n    request.setHeaders(headers);\n\n    RateLimiter rateLimiter2 = rateLimitingHandler.getActuator(request);\n    DecorateCheckedSupplier<Object> ds2 = Decorators.ofCheckedSupplier(() -> \"test2\");\n    ds2.withRateLimiter(rateLimiter2);\n    Assertions.assertEquals(\"test2\", ds2.get());\n\n    // flow control\n    CountDownLatch cd = new CountDownLatch(10);\n    AtomicBoolean expected = new AtomicBoolean(false);\n    AtomicBoolean notExpected = new AtomicBoolean(false);\n    for (int i = 0; i < 10; i++) {\n      new Thread(() -> {\n        try {\n          Object result = ds.get();\n          if (!\"test\".equals(result)) {\n            notExpected.set(true);\n          }\n        } catch (Throwable e) {\n          if (e instanceof RequestNotPermitted) {\n            expected.set(true);\n          } else {\n            notExpected.set(true);\n          }\n        }\n        cd.countDown();\n      }).start();\n    }\n    cd.await(1, TimeUnit.SECONDS);\n    Assertions.assertTrue(expected.get());\n    Assertions.assertFalse(notExpected.get());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/InstanceBulkheadHandlerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.governance.handler.InstanceBulkheadHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport io.github.resilience4j.bulkhead.Bulkhead;\nimport io.github.resilience4j.bulkhead.BulkheadFullException;\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCheckedSupplier;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class InstanceBulkheadHandlerTest {\n  private InstanceBulkheadHandler instanceBulkheadHandler;\n\n  @Autowired\n  public void setInstanceBulkheadHandler(InstanceBulkheadHandler instanceBulkheadHandler) {\n    this.instanceBulkheadHandler = instanceBulkheadHandler;\n  }\n\n  @Test\n  public void test_instance_bulkhead_work() throws Throwable {\n\n    // instance1\n    DecorateCheckedSupplier<String> dsInstance1 = Decorators.ofCheckedSupplier(() -> \"wake\");\n\n    GovernanceRequest requestInstance1 = new GovernanceRequest();\n    requestInstance1.setInstanceId(\"instance01\");\n    requestInstance1.setServiceName(\"service01\");\n    requestInstance1.setApiPath(\"/test\");\n\n    Bulkhead bulkheadInstance1 = instanceBulkheadHandler.getActuator(requestInstance1);\n    dsInstance1.withBulkhead(bulkheadInstance1);\n\n    // instance2\n    DecorateCheckedSupplier<String> dsInstance2 = Decorators.ofCheckedSupplier(() -> {\n      Thread.sleep(1000);\n      return \"sleep\";\n    });\n\n    GovernanceRequest requestInstance2 = new GovernanceRequest();\n    requestInstance2.setInstanceId(\"instance02\");\n    requestInstance2.setServiceName(\"service01\");\n    requestInstance2.setApiPath(\"/test\");\n\n    Bulkhead bulkheadInstance2 = instanceBulkheadHandler.getActuator(requestInstance2);\n    dsInstance2.withBulkhead(bulkheadInstance2);\n\n    Executor executor = Executors.newFixedThreadPool(4);\n    AtomicInteger wakeCount = new AtomicInteger(0);\n    AtomicInteger sleepCount = new AtomicInteger(0);\n    AtomicInteger errorCount = new AtomicInteger(0);\n    AtomicInteger rejectCount = new AtomicInteger(0);\n    CountDownLatch countDownLatch = new CountDownLatch(100);\n    for (int i = 0; i < 100; i++) {\n      final int num = i;\n      executor.execute(() -> {\n        // 50% for each server\n        if (num % 2 == 0) {\n          runCommand(dsInstance1, wakeCount, sleepCount, errorCount, rejectCount, countDownLatch);\n        } else {\n          runCommand(dsInstance2, wakeCount, sleepCount, errorCount, rejectCount, countDownLatch);\n        }\n      });\n    }\n    countDownLatch.await(100, TimeUnit.SECONDS);\n    Assertions.assertEquals(50, wakeCount.get());\n    Assertions.assertEquals(2, sleepCount.get());\n    Assertions.assertEquals(0, errorCount.get());\n    Assertions.assertEquals(48, rejectCount.get());\n  }\n\n  private void runCommand(DecorateCheckedSupplier<String> ds, AtomicInteger wakeCount, AtomicInteger sleepCount,\n      AtomicInteger errorCount, AtomicInteger rejectCount, CountDownLatch countDownLatch) {\n    try {\n      String result = ds.get();\n      if (\"wake\".equals(result)) {\n        wakeCount.incrementAndGet();\n      } else if (\"sleep\".equals(result)) {\n        sleepCount.incrementAndGet();\n      } else {\n        errorCount.incrementAndGet();\n      }\n    } catch (BulkheadFullException e) {\n      rejectCount.incrementAndGet();\n    } catch (Throwable e) {\n      errorCount.incrementAndGet();\n    }\n    countDownLatch.countDown();\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/InstanceIsolationTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.net.ConnectException;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.governance.handler.InstanceIsolationHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport io.github.resilience4j.circuitbreaker.CallNotPermittedException;\nimport io.github.resilience4j.circuitbreaker.CircuitBreaker;\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCheckedSupplier;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.prometheusmetrics.PrometheusMeterRegistry;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class InstanceIsolationTest {\n  private InstanceIsolationHandler instanceIsolationHandler;\n\n  private MeterRegistry meterRegistry;\n\n  @Autowired\n  public void setInstanceIsolationHandler(InstanceIsolationHandler instanceIsolationHandler,\n      MeterRegistry meterRegistry) {\n    this.instanceIsolationHandler = instanceIsolationHandler;\n    this.meterRegistry = meterRegistry;\n  }\n\n  @Test\n  public void test_instance_isolation_work() throws Throwable {\n    AtomicInteger counter = new AtomicInteger(0);\n\n    DecorateCheckedSupplier<Object> ds = Decorators.ofCheckedSupplier(() -> {\n      int run = counter.getAndIncrement();\n      if (run == 0) {\n        return \"test\";\n      }\n      if (run == 1) {\n        throw new ConnectException(\"test exception\");\n      }\n      return \"test\";\n    });\n\n    DecorateCheckedSupplier<Object> ds2 = Decorators.ofCheckedSupplier(() -> \"test\");\n\n    GovernanceRequest request = new GovernanceRequest();\n    request.setInstanceId(\"instance01\");\n    request.setServiceName(\"service01\");\n    request.setApiPath(\"/test\");\n\n    CircuitBreaker circuitBreaker = instanceIsolationHandler.getActuator(request);\n    ds.withCircuitBreaker(circuitBreaker);\n\n    // isolation from error\n    Assertions.assertEquals(\"test\", ds.get());\n    Assertions.assertThrows(ConnectException.class, ds::get);\n\n    Assertions.assertThrows(CallNotPermittedException.class, ds::get);\n    Assertions.assertThrows(CallNotPermittedException.class, ds::get);\n\n    Assertions.assertThrows(CallNotPermittedException.class, ds::get);\n    Assertions.assertThrows(CallNotPermittedException.class, ds::get);\n    Assertions.assertThrows(CallNotPermittedException.class, ds::get);\n\n    // isolation do not influence other instances\n    GovernanceRequest request2 = new GovernanceRequest();\n    request2.setInstanceId(\"instance02\");\n    request2.setServiceName(\"service01\");\n    request2.setApiPath(\"/test\");\n\n    CircuitBreaker circuitBreaker2 = instanceIsolationHandler.getActuator(request2);\n    ds2.withCircuitBreaker(circuitBreaker2);\n\n    Assertions.assertEquals(\"test\", ds2.get());\n    Assertions.assertEquals(\"test\", ds2.get());\n    Assertions.assertEquals(\"test\", ds2.get());\n    Assertions.assertEquals(\"test\", ds2.get());\n\n    assertMetricsNotFinish();\n\n    // recover from isolation\n    Thread.sleep(1000);\n\n    Assertions.assertEquals(\"test\", ds.get());\n    Assertions.assertEquals(\"test\", ds.get());\n    Assertions.assertEquals(\"test\", ds2.get());\n    Assertions.assertEquals(\"test\", ds2.get());\n\n    assertMetricsFinish();\n  }\n\n  private void assertMetricsNotFinish() {\n    String result = ((PrometheusMeterRegistry) meterRegistry).scrape();\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_state{name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\\\",state=\\\"open\\\"} 1.0\"));\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_state{name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\\\",state=\\\"closed\\\"} 1.0\"));\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_calls_seconds_count{kind=\\\"successful\\\",name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\\\"} 1\"));\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_calls_seconds_count{kind=\\\"successful\\\",name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\\\"} 4\"));\n  }\n\n  private void assertMetricsFinish() {\n    String result = ((PrometheusMeterRegistry) meterRegistry).scrape();\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_state{name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\\\",state=\\\"closed\\\"} 1.0\"));\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_state{name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\\\",state=\\\"closed\\\"} 1.0\"));\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_calls_seconds_count{kind=\\\"successful\\\",name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\\\"} 3\"));\n    Assertions.assertTrue(result.contains(\n        \"servicecomb_instanceIsolation_calls_seconds_count{kind=\\\"successful\\\",name=\\\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\\\"} 6\"));\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/LoadBalancerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.handler.LoadBalanceHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.processor.loadbanlance.LoadBalance;\nimport org.junit.Assert;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class LoadBalancerTest {\n  private LoadBalanceHandler loadBalanceHandler;\n\n  @Autowired\n  public void setLoadBalanceHandler(LoadBalanceHandler loadBalanceHandler) {\n    this.loadBalanceHandler = loadBalanceHandler;\n  }\n\n  public LoadBalancerTest() {\n\n  }\n\n  @Test\n  public void test_loadbalance_random() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/loadrandom\");\n    request.setServiceName(\"loadrandom\");\n    LoadBalance loadBalance = loadBalanceHandler.getActuator(request);\n    Assert.assertEquals(\"Random\", loadBalance.getRule());\n  }\n\n  @Test\n  public void test_loadbalance_roundRobin() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/loadroundRobin\");\n    request.setServiceName(\"loadroundRobin\");\n    LoadBalance loadBalance = loadBalanceHandler.getActuator(request);\n    Assert.assertEquals(\"RoundRobin\", loadBalance.getRule());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/MapperTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.governance.handler.MapperHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.processor.mapping.Mapper;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class MapperTest {\n  private MapperHandler mapperHandler;\n\n  private MapperHandler mapperHandler2;\n\n  @Autowired\n  public void setMapperHandler(MapperHandler scbMapperHandler, @Qualifier(\"mapperHandler2\") MapperHandler mapperHandler2) {\n    this.mapperHandler = scbMapperHandler;\n    this.mapperHandler2 = mapperHandler2;\n  }\n\n  @Test\n  public void test_mapper_work() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/mapper/v1\");\n    Mapper mapper = mapperHandler.getActuator(request);\n    Assertions.assertEquals(2, mapper.target().size());\n    Assertions.assertEquals(\"127.0.0.1\", mapper.target().get(\"host\"));\n    Assertions.assertEquals(\"8080\", mapper.target().get(\"port\"));\n  }\n\n  @Test\n  public void test_mapper_query_work() {\n    GovernanceRequest request = new GovernanceRequest();\n    Map<String, String> queries = new HashMap<>();\n    queries.put(\"name\", \"bob\");\n    request.setQueries(queries);\n    Mapper mapper = mapperHandler.getActuator(request);\n    Assertions.assertEquals(1, mapper.target().size());\n    Assertions.assertEquals(\"$Q{name}\", mapper.target().get(\"user-id\"));\n  }\n\n  @Test\n  public void test_mapper2_work() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/mapper/v1\");\n    Mapper mapper = mapperHandler2.getActuator(request);\n    Assertions.assertEquals(2, mapper.target().size());\n    Assertions.assertEquals(\"127.0.0.1\", mapper.target().get(\"host\"));\n    Assertions.assertEquals(\"9090\", mapper.target().get(\"port\"));\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/MockCircuitBreakerExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractCircuitBreakerExtension;\n\npublic class MockCircuitBreakerExtension extends AbstractCircuitBreakerExtension {\n  @Override\n  protected String extractStatusCode(Object result) {\n    return \"200\";\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/MockConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.handler.BulkheadHandler;\nimport org.apache.servicecomb.governance.handler.CircuitBreakerHandler;\nimport org.apache.servicecomb.governance.handler.FaultInjectionHandler;\nimport org.apache.servicecomb.governance.handler.MapperHandler;\nimport org.apache.servicecomb.governance.handler.ext.AbstractCircuitBreakerExtension;\nimport org.apache.servicecomb.governance.properties.BulkheadProperties;\nimport org.apache.servicecomb.governance.properties.CircuitBreakerProperties;\nimport org.apache.servicecomb.governance.properties.FaultInjectionProperties;\nimport org.apache.servicecomb.governance.properties.MapperProperties;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\nimport io.micrometer.prometheusmetrics.PrometheusConfig;\nimport io.micrometer.prometheusmetrics.PrometheusMeterRegistry;\n\n\n@Configuration\npublic class MockConfiguration {\n  @Bean\n  public MockMicroserviceMeta mockMicroserviceMeta() {\n    return new MockMicroserviceMeta();\n  }\n\n  @Bean\n  public MockRetryExtension mockRetryExtension() {\n    return new MockRetryExtension();\n  }\n\n  @Bean\n  public MockCircuitBreakerExtension circuitBreakerExtension() {\n    return new MockCircuitBreakerExtension();\n  }\n\n  @Bean\n  public MockInstanceIsolationExtension instanceIsolationExtension() {\n    return new MockInstanceIsolationExtension();\n  }\n\n  @Bean\n  public PrometheusMeterRegistry meterRegistry() {\n    return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);\n  }\n\n  @Bean\n  public MapperProperties mapperProperties2() {\n    return new MapperProperties(MapperProperties.MATCH_MAPPER_KEY + \"2\");\n  }\n\n  @Bean\n  public MapperHandler mapperHandler2(@Qualifier(\"mapperProperties2\") MapperProperties mapperProperties) {\n    return new MapperHandler(mapperProperties);\n  }\n\n  @Bean\n  public BulkheadProperties bulkheadProperties2() {\n    return new BulkheadProperties(BulkheadProperties.MATCH_BULKHEAD_KEY + \"2\");\n  }\n\n  @Bean\n  public BulkheadHandler bulkheadHandler2(@Qualifier(\"bulkheadProperties2\") BulkheadProperties bulkheadProperties) {\n    return new BulkheadHandler(bulkheadProperties);\n  }\n\n  @Bean\n  public CircuitBreakerProperties circuitBreakerProperties2() {\n    return new CircuitBreakerProperties(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + \"2\");\n  }\n\n  @Bean\n  public CircuitBreakerHandler circuitBreakerHandler2(\n      @Qualifier(\"circuitBreakerProperties2\") CircuitBreakerProperties circuitBreakerProperties,\n      AbstractCircuitBreakerExtension circuitBreakerExtension) {\n    return new CircuitBreakerHandler(circuitBreakerProperties, circuitBreakerExtension);\n  }\n\n  @Bean\n  public FaultInjectionProperties faultInjectionProperties2() {\n    return new FaultInjectionProperties(FaultInjectionProperties.MATCH_FAULT_INJECTION_KEY + \"2\");\n  }\n\n  @Bean\n  public FaultInjectionHandler faultInjectionHandler2(\n      @Qualifier(\"faultInjectionProperties2\") FaultInjectionProperties faultInjectionProperties) {\n    return new FaultInjectionHandler(faultInjectionProperties);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/MockInstanceIsolationExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractInstanceIsolationExtension;\n\npublic class MockInstanceIsolationExtension extends AbstractInstanceIsolationExtension {\n  @Override\n  protected String extractStatusCode(Object result) {\n    return \"200\";\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/MockMicroserviceMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\npublic class MockMicroserviceMeta implements MicroserviceMeta {\n  @Override\n  public String getName() {\n    return \"myself\";\n  }\n\n  @Override\n  public String getVersion() {\n    return \"1.0\";\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/MockRetryExtension.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.handler.ext.AbstractRetryExtension;\n\n\npublic class MockRetryExtension extends AbstractRetryExtension {\n  @Override\n  public boolean isFailedResult(List<String> statusList, Object result) {\n    return false;\n  }\n\n  @Override\n  protected String extractStatusCode(Object result) {\n    return null;\n  }\n\n  @Override\n  public boolean isFailedResult(List<String> statusList, Throwable e) {\n    return false;\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/OperatorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance;\n\nimport java.time.Duration;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.marker.Matcher;\nimport org.apache.servicecomb.governance.marker.RequestProcessor;\nimport org.apache.servicecomb.governance.marker.operator.RawOperator;\nimport org.apache.servicecomb.governance.policy.RetryPolicy;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class OperatorTest {\n  private RequestProcessor requestProcessor;\n\n  @Autowired\n  public void setRequestProcessor(RequestProcessor requestProcessor) {\n    this.requestProcessor = requestProcessor;\n  }\n\n  @Test\n  public void test_unknown_operator() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/test\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"unknown\", \"/test\");\n    matcher.setApiPath(apiPath);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_exact_api_path_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"exact\", \"/bulkhead\");\n    matcher.setApiPath(apiPath);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_prefix_api_path_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead/hello\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"prefix\", \"/bulkhead\");\n    matcher.setApiPath(apiPath);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_prefix_api_path_not_match_null() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead/hello\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"prefix\", null);\n    matcher.setApiPath(apiPath);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_suffix_api_path_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/api/bulkhead\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"suffix\", \"/bulkhead\");\n    matcher.setApiPath(apiPath);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_suffix_api_path_not_match_null() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/api/bulkhead\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"suffix\", null);\n    matcher.setApiPath(apiPath);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_exact_api_path_not_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead/\");\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"exact\", \"/bulkhead\");\n    matcher.setApiPath(apiPath);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    request.setApiPath(\"/bulkhead\");\n    request.setApiPath(null);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    request.setApiPath(\"/bulkhead\");\n    apiPath.clear();\n    matcher.setApiPath(apiPath);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_exact_api_path_match_header_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead\");\n    request.setMethod(\"GET\");\n    Map<String, String> reqHeaders = new HashMap<>();\n    reqHeaders.put(\"header1\", \"value1\");\n    request.setHeaders(reqHeaders);\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"exact\", \"/bulkhead\");\n    matcher.setApiPath(apiPath);\n    matcher.setMethod(Arrays.asList(\"GET\"));\n    Map<String, RawOperator> headers = new HashMap<>();\n    RawOperator header1 = new RawOperator();\n    header1.put(\"exact\", \"value1\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_exact_api_path_match_header_not_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/bulkhead\");\n    request.setMethod(\"GET\");\n    Map<String, String> reqHeaders = new HashMap<>();\n    reqHeaders.put(\"header1\", \"value2\");\n    request.setHeaders(reqHeaders);\n    Matcher matcher = new Matcher();\n    RawOperator apiPath = new RawOperator();\n    apiPath.put(\"exact\", \"/bulkhead\");\n    matcher.setApiPath(apiPath);\n    matcher.setMethod(Arrays.asList(\"GET\"));\n    Map<String, RawOperator> headers = new HashMap<>();\n    RawOperator header1 = new RawOperator();\n    header1.put(\"exact\", \"value1\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    reqHeaders.clear();\n    request.setHeaders(reqHeaders);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_header_low_case() {\n    GovernanceRequest request = new GovernanceRequest();\n    Map<String, String> reqHeaders = new HashMap<>();\n    reqHeaders.put(\"hEadeR\", \"100\");\n    request.setHeaders(reqHeaders);\n    Matcher matcher = new Matcher();\n    Map<String, RawOperator> headers = new HashMap<>();\n    RawOperator header1 = new RawOperator();\n    header1.put(\"compare\", \">10\");\n    headers.put(\"HeAder\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_compare_header_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    Map<String, String> reqHeaders = new HashMap<>();\n    reqHeaders.put(\"header1\", \"100\");\n    request.setHeaders(reqHeaders);\n    Matcher matcher = new Matcher();\n    Map<String, RawOperator> headers = new HashMap<>();\n\n    RawOperator header1 = new RawOperator();\n    header1.put(\"compare\", \">10\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \">=10\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \"<1000\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \"<=1000\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \"=100\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertTrue(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_compare_header_not_match() {\n    GovernanceRequest request = new GovernanceRequest();\n    Map<String, String> reqHeaders = new HashMap<>();\n    reqHeaders.put(\"header1\", \"100\");\n    request.setHeaders(reqHeaders);\n    Matcher matcher = new Matcher();\n    Map<String, RawOperator> headers = new HashMap<>();\n\n    RawOperator header1 = new RawOperator();\n    header1.put(\"compare\", \">1000\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \">=1000\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \"<10\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \"<=10\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n\n    header1 = new RawOperator();\n    header1.put(\"compare\", \"=200\");\n    headers.put(\"header1\", header1);\n    matcher.setHeaders(headers);\n    Assertions.assertFalse(requestProcessor.match(request, matcher));\n  }\n\n  @Test\n  public void test_time_changed_to_duration() {\n    RetryPolicy retryPolicy = new RetryPolicy();\n    String result;\n    result = retryPolicy.stringOfDuration(\"100\", Duration.ofMillis(10));\n    Assertions.assertEquals(\"PT0.1S\", result);\n    Assertions.assertEquals(100, Duration.parse(result).toMillis());\n\n    result = retryPolicy.stringOfDuration(\"3S\", Duration.ofMillis(10));\n    Assertions.assertEquals(\"PT3S\", result);\n    Assertions.assertEquals(3000, Duration.parse(result).toMillis());\n\n    result = retryPolicy.stringOfDuration(\"1M\", Duration.ofMillis(10));\n    Assertions.assertEquals(\"PT1M\", result);\n    Assertions.assertEquals(60000, Duration.parse(result).toMillis());\n\n    result = retryPolicy.stringOfDuration(\"1H\", Duration.ofMillis(10));\n    Assertions.assertEquals(\"PT1H\", result);\n    Assertions.assertEquals(3600000, Duration.parse(result).toMillis());\n\n    result = retryPolicy.stringOfDuration(\"3\", Duration.ofMillis(10));\n    Assertions.assertEquals(\"PT0.003S\", result);\n    Assertions.assertEquals(3, Duration.parse(result).toMillis());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/RetryHandlerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance;\n\nimport org.apache.servicecomb.governance.handler.Disposable;\nimport org.apache.servicecomb.governance.handler.RetryHandler;\nimport org.apache.servicecomb.governance.handler.ext.AbstractRetryExtension;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.policy.RetryPolicy;\nimport org.apache.servicecomb.governance.properties.RetryProperties;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.github.resilience4j.retry.MaxRetriesExceededException;\nimport io.github.resilience4j.retry.Retry;\n\npublic class RetryHandlerTest {\n  @Test\n  public void testNotFailAfterMaxAttemptsWhenThrow() {\n    AbstractRetryExtension retryExtension = Mockito.mock(AbstractRetryExtension.class);\n    RetryProperties retryProperties = Mockito.mock(RetryProperties.class);\n    GovernanceRequest governanceRequest = Mockito.mock(GovernanceRequest.class);\n    Mockito.when(retryExtension.isFailedResult(Mockito.any(), Mockito.any())).thenReturn(true);\n\n    RetryPolicy retryPolicy = new RetryPolicy();\n    retryPolicy.setName(\"test\");\n    retryPolicy.setFailAfterMaxAttempts(false);\n    RetryHandler retryHandler = new RetryHandler(retryProperties, retryExtension);\n\n    Disposable<Retry> retry = retryHandler.createProcessor(retryPolicy.getName(), governanceRequest, retryPolicy);\n    Assertions.assertThrows(IllegalStateException.class, () -> retry.get().<Integer>executeCheckedSupplier(() -> {\n      throw new IllegalStateException();\n    }));\n  }\n\n  @Test\n  public void testFailAfterMaxAttemptsWhenThrow() {\n    AbstractRetryExtension retryExtension = Mockito.mock(AbstractRetryExtension.class);\n    RetryProperties retryProperties = Mockito.mock(RetryProperties.class);\n    GovernanceRequest governanceRequest = Mockito.mock(GovernanceRequest.class);\n    Mockito.when(retryExtension.isFailedResult(Mockito.any(), Mockito.any())).thenReturn(true);\n\n    RetryPolicy retryPolicy = new RetryPolicy();\n    retryPolicy.setName(\"test\");\n    retryPolicy.setFailAfterMaxAttempts(true);\n    RetryHandler retryHandler = new RetryHandler(retryProperties, retryExtension);\n\n    Disposable<Retry> retry = retryHandler.createProcessor(retryPolicy.getName(), governanceRequest, retryPolicy);\n    Assertions.assertThrows(IllegalStateException.class, () -> retry.get().<Integer>executeCheckedSupplier(() -> {\n      throw new IllegalStateException();\n    }));\n  }\n\n  @Test\n  public void testFailAfterMaxAttemptsOnResult() {\n    AbstractRetryExtension retryExtension = Mockito.mock(AbstractRetryExtension.class);\n    RetryProperties retryProperties = Mockito.mock(RetryProperties.class);\n    GovernanceRequest governanceRequest = Mockito.mock(GovernanceRequest.class);\n    Mockito.when(retryExtension.isFailedResult(Mockito.any(), (Object) Mockito.any())).thenReturn(true);\n\n    RetryPolicy retryPolicy = new RetryPolicy();\n    retryPolicy.setName(\"test\");\n    retryPolicy.setFailAfterMaxAttempts(true);\n    RetryHandler retryHandler = new RetryHandler(retryProperties, retryExtension);\n\n    Disposable<Retry> retry = retryHandler.createProcessor(retryPolicy.getName(), governanceRequest, retryPolicy);\n    Assertions.assertThrows(MaxRetriesExceededException.class,\n        () -> retry.get().<Integer>executeCheckedSupplier(() -> -1));\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/TimeLimiterHandlerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.governance;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.governance.handler.TimeLimiterHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.policy.TimeLimiterPolicy;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport io.github.resilience4j.timelimiter.TimeLimiter;\n\n@SpringBootTest\n@ContextConfiguration(classes = {GovernanceCommonConfiguration.class, MockConfiguration.class})\npublic class TimeLimiterHandlerTest {\n  private TimeLimiterHandler timeLimiterHandler;\n\n  @Autowired\n  public void setInstanceIsolationHandler(TimeLimiterHandler timeLimiterHandler) {\n    this.timeLimiterHandler = timeLimiterHandler;\n  }\n\n  @Test\n  public void testMatchPriorityPolicy() {\n    GovernanceRequest request = new GovernanceRequest();\n    request.setApiPath(\"/timeLimiter\");\n    TimeLimiterPolicy policy = timeLimiterHandler.matchPolicy(request);\n    Assertions.assertEquals(\"demo-timeLimiter\", policy.getName());\n    TimeLimiter timeLimiter = timeLimiterHandler.getActuator(request);\n    Duration timeoutDuration = timeLimiter.getTimeLimiterConfig().getTimeoutDuration();\n    Assertions.assertEquals(2000, timeoutDuration.toMillis());\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/handler/ext/RetryExtensionTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.handler.ext;\n\nimport java.io.IOException;\nimport java.net.ConnectException;\nimport java.net.NoRouteToHostException;\nimport java.net.SocketTimeoutException;\nimport java.util.Arrays;\nimport java.util.List;\n\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport io.vertx.core.VertxException;\n\n@SpringBootTest\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RetryExtensionTest {\n\n  @Test\n  public void test_status_code_to_contains() {\n    List<String> statusList = Arrays.asList(\"502\", \"503\");\n    boolean result = AbstractRetryExtension.statusCodeContains(statusList, \"502\");\n    Assertions.assertTrue(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"504\");\n    Assertions.assertFalse(result);\n\n    statusList = Arrays.asList(\"5xx\", \"4x4\", \"4x\", \"x32\", \"xx6\");\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"502\");\n    Assertions.assertTrue(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"504\");\n    Assertions.assertTrue(result);\n\n    statusList = Arrays.asList(\"4x4\", \"x32\", \"xx6\");\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"402\");\n    Assertions.assertFalse(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"404\");\n    Assertions.assertTrue(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"332\");\n    Assertions.assertTrue(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"446\");\n    Assertions.assertTrue(result);\n\n    statusList = Arrays.asList(\"4x\", \"x3x\", \"x5\");\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"446\");\n    Assertions.assertFalse(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"455\");\n    Assertions.assertFalse(result);\n\n    result = AbstractRetryExtension.statusCodeContains(statusList, \"434\");\n    Assertions.assertTrue(result);\n  }\n\n  @Test\n  public void testRetryWithConnectionException() {\n    Exception target = new ConnectException(\"connection refused\");\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n  }\n\n  @Test\n  public void testRetryWithSocketTimeout() {\n    Exception target = new SocketTimeoutException(\"Read timed out\");\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n  }\n\n  @Test\n  public void testRetryWithIOException() {\n    Exception target = new IOException(\"Connection reset by peer\");\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n\n    target = new IOException(\"Target not exist\");\n    root = new Exception(target);\n    canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertFalse(canRetry);\n  }\n\n  @Test\n  public void testRetryVertxException() {\n    Exception target = new VertxException(\"Connection was closed\");\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n\n    target = new IOException(\"\");\n    root = new Exception(target);\n    canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertFalse(canRetry);\n  }\n\n  @Test\n  public void testRetryNoRouteToHostException() {\n    Exception target = new NoRouteToHostException(\"Host is unreachable\");\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n\n    target = new NoRouteToHostException(\"No route to host\");\n    root = new Exception(target);\n    canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n  }\n\n  @Test\n  public void testRetryEqualTen() {\n    Exception target = new ConnectException(\"connection refused\");\n    for (int i = 0; i < 8; i++) {\n      target = new Exception(\"Level\" + i, target);\n    }\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertTrue(canRetry);\n  }\n\n  @Test\n  public void testRetryOverTen() {\n    Exception target = new ConnectException(\"connection refused\");\n    for (int i = 0; i < 9; i++) {\n      target = new Exception(\"Level\" + i, target);\n    }\n    Exception root = new Exception(target);\n    boolean canRetry = FailurePredictor.canRetryForException(FailurePredictor.STRICT_RETRIABLE, root);\n    Assertions.assertFalse(canRetry);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/mockclasses/ClassNotImplements.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.mockclasses;\n\nimport org.springframework.stereotype.Component;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\n\n@Component\npublic class ClassNotImplements {\n    public boolean matchRequest(GovernanceRequest request, String parameters) {\n        return true;\n    }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/mockclasses/ClassWithAnnotation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.mockclasses;\n\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.mockclasses.service.MockProfileClassUserService;\nimport org.apache.servicecomb.governance.utils.CustomMatch;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ClassWithAnnotation implements CustomMatch {\n  @Autowired\n  MockProfileClassUserService service;\n\n  @Override\n  public boolean matchRequest(GovernanceRequestExtractor requestExtractor, String parameters) {\n    String profileValue = service.getUser();\n    return Stream.of(parameters.split(\",\")).collect(Collectors.toSet()).contains(profileValue);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/mockclasses/CustomMatchDemo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.mockclasses;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.utils.CustomMatch;\n\npublic class CustomMatchDemo implements CustomMatch {\n\n  private CustomMatchDemo() {\n\n  }\n\n  @Override\n  public boolean matchRequest(GovernanceRequestExtractor requestExtractor, String parameters) {\n    return true;\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/mockclasses/service/MockConfigurationForCustomMatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.mockclasses.service;\n\nimport org.springframework.context.annotation.ComponentScan;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ComponentScan(\"org.apache.servicecomb.governance.mockclasses\")\npublic class MockConfigurationForCustomMatcher {\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/governance/mockclasses/service/MockProfileClassUserService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.governance.mockclasses.service;\n\nimport org.springframework.stereotype.Service;\n\n@Service\npublic class MockProfileClassUserService {\n    public String getUser() {\n        return \"bill\";\n    }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/ExampleDistributor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.router;\n\nimport org.apache.servicecomb.router.distribute.AbstractRouterDistributor;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class ExampleDistributor extends AbstractRouterDistributor<ServiceIns> {\n  public ExampleDistributor() {\n    init(ServiceIns::getVersion, ServiceIns::getServerName, ServiceIns::getTags);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/RouterDistributorDynamicConfig2Test.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.router;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RouterDistributorDynamicConfig2Test {\n  private static final String TARGET_SERVICE_NAME = \"test_server\";\n\n  public static final String CONFIG_KEY = RouterRuleCache.ROUTE_RULE_PREFIX + TARGET_SERVICE_NAME;\n\n  private static final String RULE_STRING = \"\"\n      + \"      - precedence: 2\\n\"\n      + \"        route:\\n\"\n      + \"          - weight: 100\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 2.0\\n\"\n      + \"      - precedence: 1\\n\"\n      + \"        match:\\n\"\n      + \"          headers:\\n\"\n      + \"            appId:\\n\"\n      + \"              regex: 01\\n\"\n      + \"              caseInsensitive: false\\n\"\n      + \"            userId:\\n\"\n      + \"              exact: 01\\n\"\n      + \"        route:\\n\"\n      + \"          - weight: 100\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 1.0\\n\";\n\n  private Environment environment;\n\n  private RouterFilter routerFilter;\n\n  private RouterDistributor<ServiceIns> testDistributor;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setRouterFilter(RouterFilter routerFilter) {\n    this.routerFilter = routerFilter;\n  }\n\n  @Autowired\n  public void setTestDistributor(RouterDistributor<ServiceIns> testDistributor) {\n    this.testDistributor = testDistributor;\n  }\n\n  private final Map<String, Object> dynamicValues = new HashMap<>();\n\n  @BeforeEach\n  public void setUp() {\n    ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;\n\n    if (configurableEnvironment.getPropertySources().contains(\"testDynamicChange\")) {\n      configurableEnvironment.getPropertySources().remove(\"testDynamicChange\");\n    }\n\n    configurableEnvironment.getPropertySources()\n        .addFirst(new EnumerablePropertySource<Map<String, Object>>(\"testDynamicChange\", dynamicValues) {\n          @Override\n          public Object getProperty(String s) {\n            return this.getSource().get(s);\n          }\n\n          @Override\n          public String[] getPropertyNames() {\n            return this.getSource().keySet().toArray(new String[0]);\n          }\n        });\n\n    dynamicValues.put(CONFIG_KEY, RULE_STRING);\n\n    postConfigurationChangedEvent();\n  }\n\n  private void postConfigurationChangedEvent() {\n    Set<String> changedKeys = new HashSet<>();\n    changedKeys.add(CONFIG_KEY);\n    GovernanceConfigurationChangedEvent newEvent = new GovernanceConfigurationChangedEvent(changedKeys);\n    GovernanceEventManager.post(newEvent);\n  }\n\n  @Test\n  public void testMatchPrecedenceHigher() {\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"01\");\n    headers.put(\"appId\", \"01\");\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"2.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.setVersion(\"1.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(1, resultServerList.size());\n    Assertions.assertEquals(\"01\", resultServerList.get(0).getId());\n  }\n\n  @Test\n  public void testCaseSensitiveNotMatch() {\n    String rule = \"\"\n        + \"      - precedence: 1\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 2.0\\n\"\n        + \"      - precedence: 2\\n\"\n        + \"        match:\\n\"\n        + \"          headers:\\n\"\n        + \"            userId:\\n\"\n        + \"              exact: user01\\n\"\n        + \"              caseInsensitive: false\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 1.0\\n\";\n    dynamicValues.put(CONFIG_KEY, rule);\n    postConfigurationChangedEvent();\n\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"User01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"2.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.setVersion(\"1.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(1, resultServerList.size());\n    Assertions.assertEquals(\"01\", resultServerList.get(0).getId());\n    Assertions.assertEquals(\"2.0\", resultServerList.get(0).getVersion());\n  }\n\n  @Test\n  public void testNoneMatch() {\n    String rule = \"\"\n        + \"      - precedence: 1\\n\"\n        + \"        match:\\n\"\n        + \"          headers:\\n\"\n        + \"            userId:\\n\"\n        + \"              regex: user02\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 2.0\\n\"\n        + \"      - precedence: 2\\n\"\n        + \"        match:\\n\"\n        + \"          headers:\\n\"\n        + \"            userId:\\n\"\n        + \"              exact: user01\\n\"\n        + \"              caseInsensitive: false\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 1.0\\n\";\n    dynamicValues.put(CONFIG_KEY, rule);\n    postConfigurationChangedEvent();\n\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"User01\");\n    headers.put(\"appId\", \"App01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"2.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.setVersion(\"1.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(2, resultServerList.size());\n  }\n\n  @Test\n  public void testOneMatchButNoInstance() {\n    String rule = \"\"\n        + \"      - precedence: 1\\n\"\n        + \"        match:\\n\"\n        + \"          headers:\\n\"\n        + \"            appId:\\n\"\n        + \"              regex: app02\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 2.0\\n\"\n        + \"      - precedence: 2\\n\"\n        + \"        match:\\n\"\n        + \"          headers:\\n\"\n        + \"            userId:\\n\"\n        + \"              exact: user01\\n\"\n        + \"              caseInsensitive: false\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 1.0\\n\";\n    dynamicValues.put(CONFIG_KEY, rule);\n    postConfigurationChangedEvent();\n\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"user01\");\n    headers.put(\"appId\", \"app02\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"1.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.setVersion(\"1.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(2, resultServerList.size());\n  }\n\n  private List<ServiceIns> mainFilter(List<ServiceIns> serverList, GovernanceRequestExtractor requestExtractor) {\n    return routerFilter\n        .getFilteredListOfServers(serverList, TARGET_SERVICE_NAME, requestExtractor,\n            testDistributor);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/RouterDistributorDynamicConfigTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.router;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RouterDistributorDynamicConfigTest {\n  private static final String TARGET_SERVICE_NAME = \"test_server\";\n\n  private static final String RULE_STRING = \"\"\n      + \"      - precedence: 2 #优先级\\n\"\n      + \"        match:        #匹配策略\\n\"\n      + \"          headers:          #header匹配\\n\"\n      + \"            appId:\\n\"\n      + \"              exact: \\\"01\\\"\\n\"\n      + \"            userId:\\n\"\n      + \"              exact: \\\"01\\\"\\n\"\n      + \"        route: #路由规则\\n\"\n      + \"          - weight: 50\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 1.1\\n\"\n      + \"      - precedence: 1\\n\"\n      + \"        match:\\n\"\n      + \"          headers:          #header匹配\\n\"\n      + \"            appId:\\n\"\n      + \"              exact: \\\"01\\\"\\n\"\n      + \"            userId:\\n\"\n      + \"              exact: \\\"02\\\"\\n\"\n      + \"        route:\\n\"\n      + \"          - weight: 100\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 2.0\\n\"\n      + \"      - precedence: 3\\n\"\n      + \"        match:\\n\"\n      + \"          headers:          #header匹配\\n\"\n      + \"            appId:\\n\"\n      + \"              exact: \\\"01\\\"\\n\"\n      + \"            userId:\\n\"\n      + \"              exact: \\\"03\\\"\\n\"\n      + \"        route:\\n\"\n      + \"          - weight: 100\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 1.0\\n\";\n\n  private Environment environment;\n\n  private RouterFilter routerFilter;\n\n  private RouterDistributor<ServiceIns> testDistributor;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setRouterFilter(RouterFilter routerFilter) {\n    this.routerFilter = routerFilter;\n  }\n\n  @Autowired\n  public void setTestDistributor(RouterDistributor<ServiceIns> testDistributor) {\n    this.testDistributor = testDistributor;\n  }\n\n  public RouterDistributorDynamicConfigTest() {\n  }\n\n  private final Map<String, Object> dynamicValues = new HashMap<>();\n\n  @BeforeEach\n  public void setUp() {\n    ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;\n\n    if (configurableEnvironment.getPropertySources().contains(\"testDynamicChange\")) {\n      configurableEnvironment.getPropertySources().remove(\"testDynamicChange\");\n    }\n\n    configurableEnvironment.getPropertySources()\n        .addFirst(new EnumerablePropertySource<Map<String, Object>>(\"testDynamicChange\", dynamicValues) {\n          @Override\n          public Object getProperty(String s) {\n            return this.getSource().get(s);\n          }\n\n          @Override\n          public String[] getPropertyNames() {\n            return this.getSource().keySet().toArray(new String[0]);\n          }\n        });\n\n    dynamicValues.put(RouterRuleCache.ROUTE_RULE_PREFIX + TARGET_SERVICE_NAME, RULE_STRING);\n\n    Set<String> changedKeys = new HashSet<>();\n    changedKeys.add(RouterRuleCache.ROUTE_RULE_PREFIX + TARGET_SERVICE_NAME);\n    GovernanceConfigurationChangedEvent newEvent = new GovernanceConfigurationChangedEvent(changedKeys);\n    GovernanceEventManager.post(newEvent);\n  }\n\n\n  @Test\n  public void testHeaderIsEmpty() {\n    List<ServiceIns> list = getMockList();\n    List<ServiceIns> serverList = mainFilter(list, new GovernanceRequest());\n    Assertions.assertEquals(2, serverList.size());\n  }\n\n  @Test\n  public void testVersionNotMatch() {\n    Map<String, String> headerMap = new HashMap<>();\n    headerMap.put(\"userId\", \"02\");\n    headerMap.put(\"appId\", \"01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headerMap);\n    List<ServiceIns> list = getMockList();\n    list.remove(1);\n    List<ServiceIns> serverList = mainFilter(list, governanceRequest);\n    Assertions.assertEquals(1, serverList.size());\n    Assertions.assertEquals(\"01\", serverList.get(0).getId());\n  }\n\n  @Test\n  public void testVersionMatch() {\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"01\");\n    headers.put(\"appId\", \"01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n    List<ServiceIns> serverList = mainFilter(getMockList(), governanceRequest);\n    Assertions.assertEquals(1, serverList.size());\n    Assertions.assertEquals(\"02\", serverList.get(0).getId());\n  }\n\n  @Test\n  public void testMatchPrecedenceLower() {\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"02\");\n    headers.put(\"appId\", \"01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n    List<ServiceIns> serverList = mainFilter(getMockList(), governanceRequest);\n    Assertions.assertEquals(1, serverList.size());\n    Assertions.assertEquals(\"01\", serverList.get(0).getId());\n  }\n\n  @Test\n  public void testMatchPrecedenceHigher() {\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"03\");\n    headers.put(\"appId\", \"01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"2.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.addTags(\"app\", \"a\");\n    ins2.setVersion(\"1.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(1, resultServerList.size());\n    Assertions.assertEquals(\"02\", resultServerList.get(0).getId());\n  }\n\n  private List<ServiceIns> getMockList() {\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"2.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.addTags(\"app\", \"a\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n    return serverList;\n  }\n\n  private List<ServiceIns> mainFilter(List<ServiceIns> serverList,\n      GovernanceRequestExtractor governanceRequestExtractor) {\n    return routerFilter\n        .getFilteredListOfServers(serverList, TARGET_SERVICE_NAME, governanceRequestExtractor,\n            testDistributor);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/RouterDistributorFileConfigTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\n\n@SpringBootTest\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RouterDistributorFileConfigTest {\n  private static final String TARGET_SERVICE_NAME = \"test_server1\";\n\n  private RouterFilter routerFilter;\n\n  private RouterDistributor<ServiceIns> routerDistributor;\n\n  @Autowired\n  public void setRouterFilter(RouterFilter routerFilter) {\n    this.routerFilter = routerFilter;\n  }\n\n  @Autowired\n  public void setRouterDistributor(RouterDistributor<ServiceIns> routerDistributor) {\n    this.routerDistributor = routerDistributor;\n  }\n\n  @Test\n  public void testDistribute() {\n    List<ServiceIns> list = initServiceList();\n    HashMap<String, String> header = new HashMap<>();\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(header);\n\n    List<ServiceIns> listOfServers = routerFilter\n        .getFilteredListOfServers(list, TARGET_SERVICE_NAME, governanceRequest, routerDistributor);\n    Assertions.assertNotNull(listOfServers);\n    for (ServiceIns server : listOfServers) {\n      Assertions.assertEquals(TARGET_SERVICE_NAME, server.getServerName());\n    }\n    int serverNum1 = 0;\n    int serverNum2 = 0;\n\n    for (int i = 0; i < 10; i++) {\n      List<ServiceIns> serverList = routerFilter\n          .getFilteredListOfServers(list, TARGET_SERVICE_NAME, governanceRequest, routerDistributor);\n      for (ServiceIns serviceIns : serverList) {\n        if (\"01\".equals(serviceIns.getId())) {\n          serverNum1++;\n        } else if (\"02\".equals(serviceIns.getId())) {\n          serverNum2++;\n        }\n      }\n    }\n    boolean flag = false;\n    if (Math.round(serverNum2 * 1.0 / serverNum1) == 4) {\n      flag = true;\n    }\n    Assertions.assertTrue(flag);\n  }\n\n  List<ServiceIns> initServiceList() {\n    ServiceIns serviceIns1 = new ServiceIns(\"01\", \"test_server1\");\n    ServiceIns serviceIns2 = new ServiceIns(\"02\", \"test_server1\");\n    serviceIns1.setVersion(\"1.0\");\n    serviceIns2.setVersion(\"2.0\");\n    serviceIns1.addTags(\"x-group\", \"red\");\n    serviceIns2.addTags(\"x-group\", \"green\");\n    List<ServiceIns> list = new ArrayList<>();\n    list.add(serviceIns1);\n    list.add(serviceIns2);\n    return list;\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/RouterDistributorFileWeightLessTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RouterDistributorFileWeightLessTest {\n  private static final String TARGET_SERVICE_NAME = \"test_server2\";\n\n  private RouterFilter routerFilter;\n\n  private RouterDistributor<ServiceIns> routerDistributor;\n\n  @Autowired\n  public void setRouterFilter(RouterFilter routerFilter) {\n    this.routerFilter = routerFilter;\n  }\n\n  @Autowired\n  public void setRouterDistributor(RouterDistributor<ServiceIns> routerDistributor) {\n    this.routerDistributor = routerDistributor;\n  }\n\n  @Test\n  public void testDistribute() {\n    List<ServiceIns> list = initServiceList();\n    HashMap<String, String> header = new HashMap<>();\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(header);\n    List<ServiceIns> listOfServers = routerFilter\n        .getFilteredListOfServers(list, TARGET_SERVICE_NAME, governanceRequest, routerDistributor);\n    Assertions.assertNotNull(listOfServers);\n    for (ServiceIns server : listOfServers) {\n      Assertions.assertEquals(TARGET_SERVICE_NAME, server.getServerName());\n    }\n    int serverNum1 = 0;\n    int unSetTagNum = 0;\n\n    for (int i = 0; i < 10; i++) {\n      List<ServiceIns> serverList = routerFilter\n          .getFilteredListOfServers(list, TARGET_SERVICE_NAME, governanceRequest, routerDistributor);\n      for (ServiceIns serviceIns : serverList) {\n        if (\"01\".equals(serviceIns.getId())) {\n          serverNum1++;\n        } else if (\"02\".equals(serviceIns.getId())) {\n          unSetTagNum++;\n        }\n      }\n    }\n    boolean flag = false;\n    if (Math.round(unSetTagNum * 1.0 / serverNum1) == 4) {\n      flag = true;\n    }\n    Assertions.assertTrue(flag);\n  }\n\n  List<ServiceIns> initServiceList() {\n    ServiceIns serviceIns1 = new ServiceIns(\"01\", \"test_server2\");\n    ServiceIns serviceIns2 = new ServiceIns(\"02\", \"test_server2\");\n    serviceIns1.setVersion(\"1.0\");\n    serviceIns2.setVersion(\"2.0\");\n    serviceIns1.addTags(\"x-group\", \"red\");\n    serviceIns2.addTags(\"x-group\", \"green\");\n    List<ServiceIns> list = new ArrayList<>();\n    list.add(serviceIns1);\n    list.add(serviceIns2);\n    return list;\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/RouterDistributorFileWithFallbackTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.runner.RunWith;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.test.context.ContextConfiguration;\nimport org.springframework.test.context.junit4.SpringRunner;\n\n@RunWith(SpringRunner.class)\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RouterDistributorFileWithFallbackTest {\n  private static final String TARGET_SERVICE_NAME_WITHOUT_FALLBACK = \"test_server3\";\n\n  private static final String TARGET_SERVICE_NAME_WITH_FALLBACK = \"test_server4\";\n\n  private static final String TARGET_SERVICE_NAME_ROUTE_FALLBACK = \"test_server5\";\n\n  private RouterFilter routerFilter;\n\n  private RouterDistributor<ServiceIns> routerDistributor;\n\n  @Autowired\n  public void setRouterFilter(RouterFilter routerFilter) {\n    this.routerFilter = routerFilter;\n  }\n\n  @Autowired\n  public void setRouterDistributor(RouterDistributor<ServiceIns> routerDistributor) {\n    this.routerDistributor = routerDistributor;\n  }\n\n  @Test\n  public void testDistributeWithoutFallback() {\n    List<ServiceIns> list = initServiceList(TARGET_SERVICE_NAME_WITHOUT_FALLBACK);\n    HashMap<String, String> header = new HashMap<>();\n    header.put(\"canary\", \"canary\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(header);\n    List<ServiceIns> listOfServers = routerFilter\n        .getFilteredListOfServers(list, TARGET_SERVICE_NAME_WITHOUT_FALLBACK, governanceRequest, routerDistributor);\n    Assertions.assertNotNull(listOfServers);\n    for (ServiceIns server : listOfServers) {\n      Assertions.assertEquals(TARGET_SERVICE_NAME_WITHOUT_FALLBACK, server.getServerName());\n    }\n    int serverNum1 = 0;\n    int serverNum2 = 0;\n\n    for (int i = 0; i < 10; i++) {\n      List<ServiceIns> serverList = routerFilter\n          .getFilteredListOfServers(list, TARGET_SERVICE_NAME_WITHOUT_FALLBACK, governanceRequest, routerDistributor);\n      for (ServiceIns serviceIns : serverList) {\n        if (\"01\".equals(serviceIns.getId())) {\n          serverNum1++;\n        } else if (\"02\".equals(serviceIns.getId())) {\n          serverNum2++;\n        }\n      }\n    }\n    Assertions.assertTrue(serverNum2 == serverNum1);\n  }\n\n  @Test\n  public void testDistributeWithFallback() {\n    List<ServiceIns> list = initServiceList(TARGET_SERVICE_NAME_WITH_FALLBACK);\n    HashMap<String, String> header = new HashMap<>();\n    header.put(\"canary\", \"canary\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(header);\n    List<ServiceIns> listOfServers = routerFilter\n        .getFilteredListOfServers(list, TARGET_SERVICE_NAME_WITH_FALLBACK, governanceRequest, routerDistributor);\n    Assertions.assertNotNull(listOfServers);\n    for (ServiceIns server : listOfServers) {\n      Assertions.assertEquals(TARGET_SERVICE_NAME_WITH_FALLBACK, server.getServerName());\n    }\n    int serverNum1 = 0;\n    int serverNum2 = 0;\n\n    for (int i = 0; i < 10; i++) {\n      List<ServiceIns> serverList = routerFilter\n          .getFilteredListOfServers(list, TARGET_SERVICE_NAME_WITH_FALLBACK, governanceRequest, routerDistributor);\n      for (ServiceIns serviceIns : serverList) {\n        if (\"01\".equals(serviceIns.getId())) {\n          serverNum1++;\n        } else if (\"02\".equals(serviceIns.getId())) {\n          serverNum2++;\n        }\n      }\n    }\n    Assertions.assertTrue((serverNum2 + serverNum1) == serverNum1);\n  }\n\n  @Test\n  public void testDistributeRouteAndFallbackHaveSame() {\n    List<ServiceIns> list = initServiceList(TARGET_SERVICE_NAME_ROUTE_FALLBACK);\n    HashMap<String, String> header = new HashMap<>();\n    header.put(\"canary\", \"canary\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(header);\n    List<ServiceIns> listOfServers = routerFilter\n        .getFilteredListOfServers(list, TARGET_SERVICE_NAME_ROUTE_FALLBACK, governanceRequest, routerDistributor);\n    Assertions.assertNotNull(listOfServers);\n    for (ServiceIns server : listOfServers) {\n      Assertions.assertEquals(TARGET_SERVICE_NAME_ROUTE_FALLBACK, server.getServerName());\n    }\n    int serverNum1 = 0;\n    int serverNum2 = 0;\n\n    for (int i = 0; i < 20; i++) {\n      List<ServiceIns> serverList = routerFilter\n          .getFilteredListOfServers(list, TARGET_SERVICE_NAME_ROUTE_FALLBACK, governanceRequest, routerDistributor);\n      for (ServiceIns serviceIns : serverList) {\n        if (\"01\".equals(serviceIns.getId())) {\n          serverNum1++;\n        } else if (\"02\".equals(serviceIns.getId())) {\n          serverNum2++;\n        }\n      }\n    }\n    boolean flag = false;\n    if (Math.round(serverNum1 * 1.0 / serverNum2) == 3) {\n      flag = true;\n    }\n    Assertions.assertTrue(flag);\n  }\n\n  List<ServiceIns> initServiceList(String serviceName) {\n    ServiceIns serviceIns1 = new ServiceIns(\"01\", serviceName);\n    ServiceIns serviceIns2 = new ServiceIns(\"02\", serviceName);\n    serviceIns1.setVersion(\"1.0\");\n    serviceIns2.setVersion(\"2.0\");\n    serviceIns1.addTags(\"x-group\", \"red\");\n    serviceIns2.addTags(\"x-group\", \"green\");\n    List<ServiceIns> list = new ArrayList<>();\n    list.add(serviceIns1);\n    list.add(serviceIns2);\n    return list;\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/RouterDistributorGlobalConfigTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.router;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.governance.event.GovernanceConfigurationChangedEvent;\nimport org.apache.servicecomb.governance.event.GovernanceEventManager;\nimport org.apache.servicecomb.governance.marker.GovernanceRequest;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.router.cache.RouterRuleCache;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.test.context.ContextConfiguration;\n\n@SpringBootTest\n@ContextConfiguration(locations = \"classpath:META-INF/spring/*.xml\", initializers = ConfigDataApplicationContextInitializer.class)\npublic class RouterDistributorGlobalConfigTest {\n  private static final String TARGET_SERVICE_NAME = \"test_server\";\n\n  public static final String CONFIG_KEY = RouterRuleCache.ROUTE_RULE_PREFIX + TARGET_SERVICE_NAME;\n\n  private static final String RULE_STRING = \"\"\n      + \"      - precedence: 1\\n\"\n      + \"        match:\\n\"\n      + \"          headers:          #header匹配\\n\"\n      + \"            appId:\\n\"\n      + \"              exact: \\\"01\\\"\\n\"\n      + \"            userId:\\n\"\n      + \"              exact: \\\"02\\\"\\n\"\n      + \"        route:\\n\"\n      + \"          - weight: 100\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 2.0\\n\"\n      + \"      - precedence: 2\\n\"\n      + \"        match:\\n\"\n      + \"          headers:          #header匹配\\n\"\n      + \"            appId:\\n\"\n      + \"              exact: \\\"01\\\"\\n\"\n      + \"            userId:\\n\"\n      + \"              exact: \\\"03\\\"\\n\"\n      + \"        route:\\n\"\n      + \"          - weight: 100\\n\"\n      + \"            tags:\\n\"\n      + \"              version: 1.0\\n\";\n\n  private Environment environment;\n\n  private RouterFilter routerFilter;\n\n  private RouterDistributor<ServiceIns> testDistributor;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setRouterFilter(RouterFilter routerFilter) {\n    this.routerFilter = routerFilter;\n  }\n\n  @Autowired\n  public void setTestDistributor(RouterDistributor<ServiceIns> testDistributor) {\n    this.testDistributor = testDistributor;\n  }\n\n  public RouterDistributorGlobalConfigTest() {\n  }\n\n  private final Map<String, Object> dynamicValues = new HashMap<>();\n\n  @BeforeEach\n  public void setUp() {\n    ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;\n\n    if (configurableEnvironment.getPropertySources().contains(\"testDynamicChange\")) {\n      configurableEnvironment.getPropertySources().remove(\"testDynamicChange\");\n    }\n\n    configurableEnvironment.getPropertySources()\n        .addFirst(new EnumerablePropertySource<Map<String, Object>>(\"testDynamicChange\", dynamicValues) {\n          @Override\n          public Object getProperty(String s) {\n            return this.getSource().get(s);\n          }\n\n          @Override\n          public String[] getPropertyNames() {\n            return this.getSource().keySet().toArray(new String[0]);\n          }\n        });\n\n    dynamicValues.put(RouterRuleCache.GLOBAL_ROUTE_RULE_KEY, RULE_STRING);\n    postConfigurationChangedEvent(RouterRuleCache.GLOBAL_ROUTE_RULE_KEY);\n  }\n\n  @Test\n  public void testUseGlobalRouteRule() {\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"03\");\n    headers.put(\"appId\", \"01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"1.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.addTags(\"app\", \"a\");\n    ins2.setVersion(\"2.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(1, resultServerList.size());\n    Assertions.assertEquals(\"01\", resultServerList.get(0).getId());\n  }\n\n  @Test\n  public void testUseProviderRouteRule() {\n    String rule = \"\"\n        + \"      - precedence: 1\\n\"\n        + \"        match:\\n\"\n        + \"          headers:          #header匹配\\n\"\n        + \"            appId:\\n\"\n        + \"              exact: \\\"01\\\"\\n\"\n        + \"            userId:\\n\"\n        + \"              exact: \\\"03\\\"\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 2.0\\n\"\n        + \"      - precedence: 2\\n\"\n        + \"        match:\\n\"\n        + \"          headers:          #header匹配\\n\"\n        + \"            appId:\\n\"\n        + \"              exact: \\\"01\\\"\\n\"\n        + \"            userId:\\n\"\n        + \"              exact: \\\"02\\\"\\n\"\n        + \"        route:\\n\"\n        + \"          - weight: 100\\n\"\n        + \"            tags:\\n\"\n        + \"              version: 1.0\\n\";\n    dynamicValues.put(CONFIG_KEY, rule);\n    postConfigurationChangedEvent(CONFIG_KEY);\n\n    Map<String, String> headers = new HashMap<>();\n    headers.put(\"userId\", \"03\");\n    headers.put(\"appId\", \"01\");\n    GovernanceRequest governanceRequest = new GovernanceRequest();\n    governanceRequest.setHeaders(headers);\n\n    List<ServiceIns> serverList = new ArrayList<>();\n    ServiceIns ins1 = new ServiceIns(\"01\", TARGET_SERVICE_NAME);\n    ins1.setVersion(\"1.0\");\n    ServiceIns ins2 = new ServiceIns(\"02\", TARGET_SERVICE_NAME);\n    ins2.addTags(\"app\", \"a\");\n    ins2.setVersion(\"2.0\");\n    serverList.add(ins1);\n    serverList.add(ins2);\n\n    List<ServiceIns> resultServerList = mainFilter(serverList, governanceRequest);\n    Assertions.assertEquals(1, resultServerList.size());\n    Assertions.assertEquals(\"02\", resultServerList.get(0).getId());\n  }\n\n  private List<ServiceIns> mainFilter(List<ServiceIns> serverList,\n      GovernanceRequestExtractor governanceRequestExtractor) {\n    return routerFilter\n        .getFilteredListOfServers(serverList, TARGET_SERVICE_NAME, governanceRequestExtractor,\n            testDistributor);\n  }\n\n  private void postConfigurationChangedEvent(String changKey) {\n    Set<String> changedKeys = new HashSet<>();\n    changedKeys.add(changKey);\n    GovernanceConfigurationChangedEvent newEvent = new GovernanceConfigurationChangedEvent(changedKeys);\n    GovernanceEventManager.post(newEvent);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/ServiceIns.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.router;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ServiceIns {\n  String version = \"1.1\";\n\n  String serverName;\n\n  Map<String, String> tags = new HashMap<>();\n\n  private final String id;\n\n  public ServiceIns(String id, String serverName) {\n    this.id = id;\n    this.serverName = serverName;\n  }\n\n  public String getId() {\n    return id;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public String getServerName() {\n    return serverName;\n  }\n\n  public Map<String, String> getTags() {\n    return tags;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public void addTags(String key, String v) {\n    tags.put(key, v);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/java/org/apache/servicecomb/router/VersionCompareUtilTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router;\n\nimport org.apache.servicecomb.router.util.VersionCompareUtil;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class VersionCompareUtilTest {\n\n  @Test\n  public void testVersion() {\n    Assertions.assertTrue(VersionCompareUtil.compareVersion(\"0.0.1\", \"0.0.0\") > 0);\n    Assertions.assertEquals(0, VersionCompareUtil.compareVersion(\"0.0.0\", \"0.0.0\"));\n    Assertions.assertTrue(VersionCompareUtil.compareVersion(\"0.0.0\", \"0.0.1\") < 0);\n    Assertions.assertEquals(0, VersionCompareUtil.compareVersion(\"0.0.0\", \"0.0.0.0\"));\n    Assertions.assertTrue(VersionCompareUtil.compareVersion(\"0.0.1\", \"0.0.0.0\") > 0);\n    Assertions.assertTrue(VersionCompareUtil.compareVersion(\"0.0.1\", \"0.0.0.0\") > 0);\n  }\n}\n"
  },
  {
    "path": "governance/src/test/resources/META-INF/spring/bean.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:context=\"http://www.springframework.org/schema/context\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"\n\t\thttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n\t\thttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\">\n\n  <context:component-scan base-package=\"org.apache.servicecomb.router\"/>\n  <context:component-scan base-package=\"org.apache.servicecomb.governance\"/>\n</beans>\n"
  },
  {
    "path": "governance/src/test/resources/application.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  matchGroup:\n    demo-timeLimiter: |\n      matches:\n        - apiPath:\n            prefix: \"/timeLimiter\"\n    demo-governanceCache: |\n      matches:\n        - apiPath:\n            prefix: \"/governanceCache\"\n    demo-loadbalance-random: |\n      matches:\n        - serviceName: \"loadrandom\"\n    demo-loadbalance-roundRobin: |\n      matches:\n        - serviceName: \"loadroundRobin\"\n    demo-fallback-returnNull: |\n      matches:\n        - serviceName: \"returnNull\"\n    demo-fallback-ThrowException: |\n      matches:\n        - serviceName: \"ThrowException\"\n    demo-faultInject-forceClosed: |\n      matches:\n        - serviceName: \"forceClosed\"\n    demo-allOperation: |\n      matches:\n        - apiPath:\n            prefix: \"/\"\n    demo-rateLimiting: |\n      matches:\n        - apiPath:\n            exact: \"/hello\"\n    demo-rateLimiting-servicename: |\n      matches:\n        - apiPath:\n            exact: \"/helloServiceName\"\n          serviceName: \"srcService\"\n    wrong-name-inogred: |\n      wrong: some\n    demo-retry: |\n      matches:\n        - apiPath:\n            exact: \"/retry\"\n    demo-circuitBreaker: |\n      matches:\n        - apiPath:\n            exact: \"/circuitBreaker\"\n    demo-bulkhead: |\n      matches:\n        - name: matchPath\n          apiPath:\n            exact: \"/bulkhead\"\n        - name: matchHeader\n          headers:\n            x-token:\n              exact: token\n    demo-bulkhead-priority: |\n      matches:\n        - apiPath:\n          exact: \"/bulkhead\"\n    demo-bulkhead-other: |\n      matches:\n        - apiPath:\n          exact: \"/bulkhead\"\n      services: other:1.0\n    demo-faultInjectDelay: |\n      matches:\n        - apiPath:\n            contains: \"/faultInjectDelay\"\n    demo-faultInjectAbort: |\n      matches:\n        - apiPath:\n            contains: \"/faultInjectAbort\"\n    demo-mapper: |\n      matches:\n        - apiPath:\n            prefix: \"/mapper\"\n    demo-mapper-query: |\n      matches:\n        - queries:\n            name:\n              exact: \"bob\"\n  rateLimiting:\n    demo-rateLimiting: |\n      rate: 1\n    demo-rateLimiting-servicename: |\n      rate: 1\n    wrongIgnored: |\n      rate: 0\n  identifierRateLimiting:\n    demo-rateLimiting: |\n      rate: 1\n      identifier: test\n    demo-rateLimiting-servicename: |\n      rate: 1\n      identifier: test\n  timeLimiter:\n    demo-timeLimiter: |\n      timeoutDuration: 2000\n      cancelRunningFuture: true\n    demo-timeLimiter-other: |\n      timeoutDuration: 2000\n      cancelRunningFuture: false\n  cache:\n    demo-governanceCache: |\n      ttl: 36000000\n      maximumSize: 50000\n      concurrencyLevel: 10\n    demo-governanceCache-other: |\n      ttl: 666666\n      maximumSize: 50000\n      concurrencyLevel: 15\n  retry:\n    demo-retry: |\n      maxAttempts: 3\n    wrongIgnored: |\n      maxAttempts: -1\n  circuitBreaker:\n    demo-circuitBreaker: |\n      minimumNumberOfCalls: 2\n      slidingWindowSize: 2\n      slidingWindowType: COUNT_BASED\n      services: myself:1.0,other\n    wrongIgnored: |\n      rules:\n        match: demo-circuitBreaker.xx\n      minimumNumberOfCalls: -1\n  bulkhead:\n    demo-bulkhead: |\n      order: 1\n      maxConcurrentCalls: 1\n      maxWaitDuration: 3000\n      services: myself:1.0\n    demo-bulkhead-priority: |\n      order: 0\n      maxConcurrentCalls: 1\n      maxWaitDuration: 3000\n      services: myself:1.0\n    demo-bulkhead-other: |\n      maxConcurrentCalls: 1\n      maxWaitDuration: 3000\n      services: other:1.0\n    wrongIgnored: |\n      rules:\n        match: demo-bulkhead.xx\n      maxWaitDuration: -1\n  instanceIsolation:\n    demo-allOperation: |\n      minimumNumberOfCalls: 2\n      slidingWindowSize: 2\n      slidingWindowType: COUNT_BASED\n      waitDurationInOpenState: 1000\n  instanceBulkhead:\n    demo-allOperation: |\n      maxConcurrentCalls: 2\n      maxWaitDuration: 10\n  faultInjection:\n    demo-fallback-ThrowException: |\n      type: abort\n      percentage: 100\n    demo-fallback-returnNull: |\n      fallbackType: ReturnNull\n      type: abort\n      percentage: 100\n    demo-faultInject-forceClosed: |\n      forceClosed: true\n      fallbackType: ReturnNull\n    demo-faultInjectDelay: |\n      delayTime: 2S\n      type: delay\n      percentage: 100\n    demo-faultInjectAbort: |\n      type: abort\n      percentage: 50\n      errorCode: 500\n    wrongIgnored: |\n      delayTime: -1\n      type: ERROR\n  faultInjection2:\n    demo-fallback-ThrowException: |\n      type: abort\n      percentage: 100\n  loadbalance:\n    demo-loadbalance-random: |\n      rule: Random\n    demo-loadbalance-roundRobin: |\n      rule: RoundRobin\n  mapper:\n    demo-mapper: |\n      target:\n        host: 127.0.0.1\n        port: 8080\n    demo-mapper-query: |\n      target:\n        user-id: $Q{name}\n  mapper2:\n    demo-mapper: |\n      target:\n        host: 127.0.0.1\n        port: 9090\n  routeRule:\n    test_server1: |                              # 服务名\n      - precedence: 1                        # 优先级，数字越大，优先级越高。\n        match:                               # 请求匹配规则。0..N个，不配置表示匹配。\n          headers:                           # header 匹配\n            region:                          # 如果配置了多个 header，那么所有的 header 规则都必须和请求匹配\n              exact: 'providerRegion'\n            type:\n              regex: gray_[a-z]+             # java 正则表达式匹配\n        route:                               # 路由规则\n          - weight: 20                       # 权重值\n            tags:\n              version: 1.0.0                 # 实例标记。满足标记条件的实例放到这一组。\n          - weight: 80                       # 权重值\n            tags:\n              version: 2.0.0                 # 实例标记。满足标记条件的实例放到这一组。\n\n      - precedence: 2\n        route:\n          - weight: 20\n            tags:\n              x-group: red\n          - weight: 80\n            tags:\n              x-group: green\n\n    test_server2: |                              # 服务名\n      - precedence: 1\n        route:\n          - weight: 20\n            tags:\n              x-group: red\n\n    test_server3: |                              # 服务名\n      - precedence: 2\n        match:\n          headers:\n            canary:\n              exact: 'canary'\n        route:\n          - weight: 20\n            tags:\n              version: 1.0.0\n          - weight: 80\n            tags:\n              version: 2.0.0\n    test_server4: |                              # 服务名\n      - precedence: 2\n        match:\n          headers:\n            canary:\n              exact: 'canary'\n        route:\n          - weight: 20\n            tags:\n              version: 1.0.0\n          - weight: 80\n            tags:\n              version: 2.0.0\n        fallback:\n          - weight: 100\n            tags:\n              x-group: red\n    test_server5: |                              # 服务名\n      - precedence: 2\n        match:\n          headers:\n            canary:\n              exact: 'canary'\n        route:\n          - weight: 50\n            tags:\n              x-group: red\n        fallback:\n          - weight: 50\n            tags:\n              x-group: red\n          - weight: 50\n            tags:\n              x-group: green\n"
  },
  {
    "path": "handlers/handler-fault-injection/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>handlers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>handler-fault-injection</artifactId>\n  <name>Java Chassis::Handlers::Fault Injection</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/ConsumerAbortFaultFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.faultinjection;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class ConsumerAbortFaultFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerAbortFaultFilter.class);\n\n  private static final String SUCCESS_RESPONSE = \"success\";\n\n  public static final String ABORTED_ERROR_MSG = \"aborted by fault inject\";\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1020;\n  }\n\n  @Override\n  public String getName() {\n    return \"consumer-abort-fault\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (!shouldAbort(invocation)) {\n      return nextNode.onFilter(invocation);\n    }\n\n    // get the config values related to abort percentage.\n    int errorCode = FaultInjectionUtil.getFaultInjectionConfig(invocation, \"abort.httpStatus\");\n    if (errorCode == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: Abort error code is not configured\");\n      return CompletableFuture.completedFuture(Response.succResp(SUCCESS_RESPONSE));\n    }\n\n    // if request need to be abort then return failure with given error code\n    CommonExceptionData errorData = new CommonExceptionData(ABORTED_ERROR_MSG);\n    return CompletableFuture.failedFuture(new InvocationException(errorCode, ABORTED_ERROR_MSG, errorData));\n  }\n\n  private boolean shouldAbort(Invocation invocation) {\n    // get the config values related to abort.\n    int abortPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation, \"abort.percent\");\n    if (abortPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: Abort percentage is not configured\");\n      return false;\n    }\n\n    // check fault abort condition.\n    return FaultInjectionUtil.isFaultNeedToInject(abortPercent);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/ConsumerDelayFaultFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.faultinjection;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\n\npublic class ConsumerDelayFaultFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerDelayFaultFilter.class);\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1030;\n  }\n\n  @Override\n  public String getName() {\n    return \"consumer-delay-fault\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (!shouldDelay(invocation)) {\n      return nextNode.onFilter(invocation);\n    }\n\n    LOGGER.debug(\"Fault injection: delay is added for the request by fault inject handler\");\n    long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,\n        \"delay.fixedDelay\");\n    if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: delay is not configured\");\n      return nextNode.onFilter(invocation);\n    }\n\n    return executeDelay(invocation, nextNode, delay);\n  }\n\n  private CompletableFuture<Response> executeDelay(Invocation invocation, FilterNode nextNode,\n      long delay) {\n    Context currentContext = Vertx.currentContext();\n    if (currentContext != null && currentContext.isEventLoopContext()) {\n      CompletableFuture<Response> result = new CompletableFuture<>();\n      currentContext.owner().setTimer(delay, timeID -> nextNode.onFilter(invocation).whenComplete((r, e) -> {\n            if (e == null) {\n              result.complete(r);\n            } else {\n              result.completeExceptionally(e);\n            }\n          }\n      ));\n      return result;\n    }\n\n    try {\n      Thread.sleep(delay);\n    } catch (InterruptedException e) {\n      LOGGER.info(\"Interrupted exception is received\");\n    }\n    return nextNode.onFilter(invocation);\n  }\n\n  private boolean shouldDelay(Invocation invocation) {\n    int delayPercent = FaultInjectionUtil.getFaultInjectionConfig(invocation,\n        \"delay.percent\");\n    if (delayPercent == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {\n      LOGGER.debug(\"Fault injection: delay percentage is not configured\");\n      return false;\n    }\n\n    // check fault delay condition.\n    return FaultInjectionUtil.isFaultNeedToInject(delayPercent);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.faultinjection;\n\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ConditionalOnProperty(value = FaultInjectionConfiguration.FAULT_INJECTION_ENABLED,\n    havingValue = \"true\")\npublic class FaultInjectionConfiguration {\n  public static final String FAULT_INJECTION_PREFIX = \"servicecomb.faultInjection\";\n\n  public static final String FAULT_INJECTION_ENABLED = FAULT_INJECTION_PREFIX + \".enabled\";\n\n  @Bean\n  public ConsumerAbortFaultFilter scbConsumerAbortFaultFilter() {\n    return new ConsumerAbortFaultFilter();\n  }\n\n  @Bean\n  public ConsumerDelayFaultFilter scbConsumerDelayFaultFilter() {\n    return new ConsumerDelayFaultFilter();\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.faultinjection;\n\n/**\n * Handles the all constant values for fault injection.\n */\npublic class FaultInjectionConst {\n\n  public static final int FAULT_INJECTION_DEFAULT_VALUE = -1;\n\n  public static final int FAULT_INJECTION_ERROR = -1;\n\n  public static final String CONSUMER_FAULTINJECTION = \"servicecomb.governance.Consumer.\";\n\n  public static final String CONSUMER_FAULTINJECTION_GLOBAL = \"servicecomb.governance.Consumer._global.\";\n\n  public static final String CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS = \"policy.fault.protocols.\";\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultInjectionUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.faultinjection;\n\nimport static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION;\nimport static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION_GLOBAL;\nimport static org.apache.servicecomb.faultinjection.FaultInjectionConst.CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS;\nimport static org.apache.servicecomb.faultinjection.FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE;\n\nimport java.util.Map;\nimport java.util.concurrent.ThreadLocalRandom;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n * Handles the count for all request based key[transport + microservice qualified name].\n */\npublic class FaultInjectionUtil {\n  private FaultInjectionUtil() {\n  }\n\n  // key is config parameter\n  private static final Map<String, AtomicInteger> configCenterValue = new ConcurrentHashMapEx<>();\n\n  /**\n   * Returns the map of config parameter key and values.\n   * @return value of config parameter map\n   */\n  public static Map<String, AtomicInteger> getConfigCenterMap() {\n    return configCenterValue;\n  }\n\n  /**\n   * Sets the value for given config parameter.\n   * @param key\n   * @param value\n   */\n  public static void setConfigCenterValue(String key, AtomicInteger value) {\n    configCenterValue.put(key, value);\n  }\n\n  /**\n   * Handles the reading fault injection configuration.\n   *\n   * @param invocation\n   *            invocation of request\n   * @param key\n   *            configuration key\n   * @return configuration value\n   */\n  public static int getFaultInjectionConfig(Invocation invocation, String key) {\n    int value = 0;\n    String config;\n\n    // get the config base on priority. operationName-->schema-->service-->global\n    String operationName = invocation.getOperationName();\n    String schema = invocation.getSchemaId();\n    String serviceName = invocation.getMicroserviceName();\n\n    config = CONSUMER_FAULTINJECTION + serviceName + \".schemas.\" + schema + \".operations.\" + operationName + \".\"\n        + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS + invocation.getTransport().getName() + \".\" + key;\n\n    value = getConfigValue(config);\n    if ((value != FAULT_INJECTION_DEFAULT_VALUE)) {\n      return value;\n    }\n\n    config = CONSUMER_FAULTINJECTION + serviceName + \".schemas.\" + schema + \".\"\n        + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS + invocation.getTransport().getName() + \".\" + key;\n\n    value = getConfigValue(config);\n    if ((value != FAULT_INJECTION_DEFAULT_VALUE)) {\n      return value;\n    }\n\n    config = CONSUMER_FAULTINJECTION + serviceName + \".\" + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS\n        + invocation.getTransport().getName() + \".\" + key;\n    value = getConfigValue(config);\n    if ((value != FAULT_INJECTION_DEFAULT_VALUE)) {\n      return value;\n    }\n\n    config = CONSUMER_FAULTINJECTION_GLOBAL + CONSUMER_FAULTINJECTION_POLICY_PROTOCOLS\n        + invocation.getTransport().getName() + \".\" + key;\n\n    value = getConfigValue(config);\n    return value;\n  }\n\n  /**\n   * Get the configuration value\n   * @param config config parameter\n   * @return int value\n   */\n  private static int getConfigValue(String config) {\n    int value = 0;\n    //first need to check in config center map which has high priority.\n    Map<String, AtomicInteger> cfgMap = FaultInjectionUtil.getConfigCenterMap();\n\n    if (cfgMap.containsKey(config)) {\n      return cfgMap.get(config).get();\n    }\n\n    value = LegacyPropertyFactory.getIntProperty(config, FAULT_INJECTION_DEFAULT_VALUE);\n    return value;\n  }\n\n  /**\n   * It will check the delay/abort condition based on percentage.\n   *\n   * @return true: delay/abort is needed. false: delay/abort is not needed.\n   */\n  public static boolean isFaultNeedToInject(int percentage) {\n    if (percentage > 0) {\n      return ThreadLocalRandom.current().nextInt(100) < percentage;\n    }\n    return false;\n  }\n\n  @VisibleForTesting\n  static Map<String, AtomicInteger> getConfigCenterValue() {\n    return configCenterValue;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/java/org/apache/servicecomb/faultinjection/FaultParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.faultinjection;\n\nimport io.vertx.core.Vertx;\n\n/**\n * Fault injection parameters which decides the fault injection condition.\n */\npublic class FaultParam {\n  private Vertx vertx;\n\n  FaultParam() {\n\n  }\n\n  public Vertx getVertx() {\n    return vertx;\n  }\n\n  public void setVertx(Vertx vertx) {\n    this.vertx = vertx;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.faultinjection.FaultInjectionConfiguration\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestConsumerAbortFaultFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.faultinjection;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestConsumerAbortFaultFilter {\n  private Invocation invocation;\n\n  private Environment environment;\n\n  @BeforeEach\n  public void before() {\n    environment = Mockito.mock(Environment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4.operations.sayBye4\"\n            + \".policy.fault.protocols.rest.abort.percent\",\n        int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4.operations.sayBye4\"\n            + \".policy.fault.protocols.rest.abort.httpStatus\",\n        int.class, -1)).thenReturn(-1);\n\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4\"\n            + \".policy.fault.protocols.rest.abort.percent\",\n        int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4\"\n            + \".policy.fault.protocols.rest.abort.httpStatus\",\n        int.class, -1)).thenReturn(-1);\n\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6\"\n            + \".policy.fault.protocols.rest.abort.percent\",\n        int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6\"\n            + \".policy.fault.protocols.rest.abort.httpStatus\",\n        int.class, -1)).thenReturn(-1);\n\n    Mockito.when(environment.getProperty(\n            \"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.abort.percent\",\n            int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\n            \"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.abort.httpStatus\",\n            int.class, -1))\n        .thenReturn(-1);\n\n    FaultInjectionUtil.getConfigCenterValue().clear();\n\n    invocation = Mockito.mock(Invocation.class);\n    Transport transport = Mockito.mock(Transport.class);\n    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn(\"MicroserviceQualifiedName12\");\n    Mockito.when(invocation.getTransport()).thenReturn(transport);\n    Mockito.when(transport.getName()).thenReturn(\"rest\");\n    Mockito.when(invocation.getOperationName()).thenReturn(\"sayBye4\");\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"testSchema4\");\n    Mockito.when(invocation.getMicroserviceName()).thenReturn(\"carts6\");\n  }\n\n  @AfterEach\n  public void after() {\n  }\n\n  @AfterAll\n  public static void classTeardown() {\n    VertxUtils.blockCloseVertxByName(\"faultinjectionTest\");\n  }\n\n  @Test\n  public void injectFaultError() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.abort.httpStatus\",\n            int.class, -1))\n        .thenReturn(421);\n    Mockito.when(environment.getProperty(\n            \"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.abort.percent\",\n            int.class, -1))\n        .thenReturn(100);\n\n    ConsumerAbortFaultFilter abortFault = new ConsumerAbortFaultFilter();\n\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n\n    Holder<InvocationException> resultHolder = new Holder<>();\n    CompletableFuture<Response> result = abortFault.onFilter(invocation, filterNode);\n    result.whenComplete((r, e) -> {\n      if (e != null) {\n        resultHolder.value = (InvocationException) e;\n      }\n    });\n    Assertions.assertThrows(ExecutionException.class, () -> result.get());\n    Assertions.assertEquals(421, resultHolder.value.getStatusCode());\n    Assertions.assertEquals(\"aborted by fault inject\", resultHolder.value.getReasonPhrase());\n    Assertions.assertEquals(\"CommonExceptionData [message=aborted by fault inject]\",\n        resultHolder.value.getErrorData().toString());\n  }\n\n  @Test\n  public void injectFaultNoError() throws Exception {\n    ConsumerAbortFaultFilter abortFault = new ConsumerAbortFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = abortFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n\n  @Test\n  public void injectFaultNoPercentageConfig() throws Exception {\n    ConsumerAbortFaultFilter abortFault = new ConsumerAbortFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = abortFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n\n  @Test\n  public void injectFaultNoErrorCodeConfig() throws Exception {\n    ConsumerAbortFaultFilter abortFault = new ConsumerAbortFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = abortFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestConsumerDelayFaultFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.faultinjection;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestConsumerDelayFaultFilter {\n  private Invocation invocation;\n\n  private Environment environment;\n\n  @BeforeEach\n  public void before() {\n    environment = Mockito.mock(Environment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4.operations.sayBye4\"\n            + \".policy.fault.protocols.rest.delay.fixedDelay\",\n        int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4.operations.sayBye4\"\n            + \".policy.fault.protocols.rest.delay.percent\",\n        int.class, -1)).thenReturn(-1);\n\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4\"\n            + \".policy.fault.protocols.rest.delay.fixedDelay\",\n        int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6.schemas.testSchema4\"\n            + \".policy.fault.protocols.rest.delay.percent\",\n        int.class, -1)).thenReturn(-1);\n\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6\"\n            + \".policy.fault.protocols.rest.delay.fixedDelay\",\n        int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\n        \"servicecomb.governance.Consumer.carts6\"\n            + \".policy.fault.protocols.rest.delay.percent\",\n        int.class, -1)).thenReturn(-1);\n\n    Mockito.when(environment.getProperty(\n            \"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.delay.fixedDelay\",\n            int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\n            \"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.delay.percent\",\n            int.class, -1))\n        .thenReturn(-1);\n\n    FaultInjectionUtil.getConfigCenterValue().clear();\n\n    invocation = Mockito.mock(Invocation.class);\n    Transport transport = Mockito.mock(Transport.class);\n    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn(\"MicroserviceQualifiedName12\");\n    Mockito.when(invocation.getTransport()).thenReturn(transport);\n    Mockito.when(transport.getName()).thenReturn(\"rest\");\n    Mockito.when(invocation.getOperationName()).thenReturn(\"sayBye4\");\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"testSchema4\");\n    Mockito.when(invocation.getMicroserviceName()).thenReturn(\"carts6\");\n  }\n\n  @AfterEach\n  public void after() {\n  }\n\n  @AfterAll\n  public static void classTeardown() {\n    VertxUtils.blockCloseVertxByName(\"faultinjectionTest\");\n  }\n\n  @Test\n  public void injectFaultVertxDelay() throws Exception {\n    Mockito.when(environment.getProperty(\"servicecomb.governance.Consumer._global\"\n                + \".policy.fault.protocols.rest.delay.fixedDelay\",\n            int.class, -1))\n        .thenReturn(10);\n    Mockito.when(\n            environment.getProperty(\"servicecomb.governance.Consumer._global\"\n                    + \".policy.fault.protocols.rest.delay.percent\",\n                int.class, -1))\n        .thenReturn(100);\n\n    ConsumerDelayFaultFilter delayFault = new ConsumerDelayFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = delayFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n\n  @Test\n  public void injectFaultSystemDelay() throws Exception {\n    Mockito.when(\n            environment.getProperty(\"servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay\",\n                int.class, -1))\n        .thenReturn(10);\n    Mockito.when(\n            environment.getProperty(\"servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent\",\n                int.class, -1))\n        .thenReturn(100);\n\n    ConsumerDelayFaultFilter delayFault = new ConsumerDelayFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = delayFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n\n  @Test\n  public void injectFaultNotDelay() throws Exception {\n    Mockito.when(\n            environment.getProperty(\"servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.fixedDelay\",\n                int.class, -1))\n        .thenReturn(10);\n    Mockito.when(\n            environment.getProperty(\"servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent\",\n                int.class, -1))\n        .thenReturn(0);\n\n    ConsumerDelayFaultFilter delayFault = new ConsumerDelayFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = delayFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n\n  @Test\n  public void injectFaultNoPercentageConfig() throws Exception {\n    ConsumerDelayFaultFilter delayFault = new ConsumerDelayFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = delayFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n\n  @Test\n  public void injectFaultNoDelayMsConfig() throws Exception {\n    Mockito.when(\n            environment.getProperty(\"servicecomb.governance.Consumer._global.policy.fault.protocols.rest.delay.percent\",\n                int.class, -1))\n        .thenReturn(10);\n\n    ConsumerDelayFaultFilter delayFault = new ConsumerDelayFaultFilter();\n    FilterNode filterNode = Mockito.mock(FilterNode.class);\n    Mockito.when(filterNode.onFilter(invocation))\n        .thenReturn(CompletableFuture.completedFuture(Response.succResp(\"success\")));\n    CompletableFuture<Response> result = delayFault.onFilter(invocation, filterNode);\n    Assertions.assertEquals(\"success\", result.get().getResult());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.faultinjection;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\n/**\n * Tests the fault inject util functionality.\n */\npublic class TestFaultInjectUtil {\n  @Test\n  public void testFaultInjectUtil() {\n    FaultInjectionUtil.setConfigCenterValue(\"sayHi\", new AtomicInteger(123));\n    int value = FaultInjectionUtil.getConfigCenterMap().get(\"sayHi\").get();\n    Assertions.assertEquals(123, value);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>handlers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>handler-flowcontrol-qps</artifactId>\n  <name>Java Chassis::Handlers::Flow Control QPS</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\n\npublic final class Config {\n  public static final String CONFIG_PREFIX = \"servicecomb.flowcontrol.\";\n\n  public static final String STRATEGY_KEY = \"servicecomb.flowcontrol.strategy\";\n\n  public static final String ANY_SERVICE = \"ANY\";\n\n  public static final String CONSUMER_BUCKET_KEY_PREFIX = \"servicecomb.flowcontrol.Consumer.qps.bucket.\";\n\n  public static final String PROVIDER_BUCKET_KEY_PREFIX = \"servicecomb.flowcontrol.Provider.qps.bucket.\";\n\n  public static final String PROVIDER_BUCKET_KEY_GLOBAL =\n      \"servicecomb.flowcontrol.Provider.qps.global.bucket\";\n\n  public static final String CONSUMER_BUCKET_KEY_GLOBAL =\n      \"servicecomb.flowcontrol.Consumer.qps.global.bucket\";\n\n  public static final String CONSUMER_LIMIT_KEY_PREFIX = \"servicecomb.flowcontrol.Consumer.qps.limit.\";\n\n  public static final String PROVIDER_LIMIT_KEY_PREFIX = \"servicecomb.flowcontrol.Provider.qps.limit.\";\n\n  public static final String PROVIDER_LIMIT_KEY_GLOBAL =\n      \"servicecomb.flowcontrol.Provider.qps.global.limit\";\n\n  public static final String CONSUMER_LIMIT_KEY_GLOBAL =\n      \"servicecomb.flowcontrol.Consumer.qps.global.limit\";\n\n  public static final String CONSUMER_ENABLED = \"servicecomb.flowcontrol.Consumer.qps.enabled\";\n\n  public static final String PROVIDER_ENABLED = \"servicecomb.flowcontrol.Provider.qps.enabled\";\n\n  public static Config INSTANCE = new Config();\n\n  public Config() {\n\n  }\n\n  public boolean isConsumerEnabled() {\n    return LegacyPropertyFactory.getBooleanProperty(CONSUMER_ENABLED, true);\n  }\n\n  public boolean isProviderEnabled() {\n    return LegacyPropertyFactory.getBooleanProperty(PROVIDER_ENABLED, true);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ConsumerFlowControlFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class ConsumerFlowControlFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private final QpsControllerManager qpsControllerMgr;\n\n  public ConsumerFlowControlFilter(Environment environment) {\n    qpsControllerMgr = new QpsControllerManager(false, environment);\n  }\n\n  @VisibleForTesting\n  public QpsControllerManager getQpsControllerMgr() {\n    return qpsControllerMgr;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER - 1990;\n  }\n\n  @Override\n  public String getName() {\n    return \"consumer-flow-control\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (!Config.INSTANCE.isConsumerEnabled()) {\n      return nextNode.onFilter(invocation);\n    }\n\n    QpsStrategy qpsStrategy = qpsControllerMgr.getOrCreate(invocation.getMicroserviceName(), invocation);\n    if (qpsStrategy.isLimitNewRequest()) {\n      CommonExceptionData errorData = new CommonExceptionData(\n          \"consumer request rejected by flow control.\");\n      return CompletableFuture.failedFuture(new InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData));\n    }\n\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/FlowControlQpsConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.qps;\n\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\n@ConditionalOnProperty(value = FlowControlQpsConfiguration.FLOW_CONTROL_ENABLED,\n    havingValue = \"true\")\npublic class FlowControlQpsConfiguration {\n  public static final String FLOW_CONTROL_PREFIX = \"servicecomb.flowcontrol\";\n\n  public static final String FLOW_CONTROL_ENABLED = FLOW_CONTROL_PREFIX + \".enabled\";\n\n  @Bean\n  public ProviderFlowControlFilter scbProviderFlowControlFilter(Environment environment) {\n    return new ProviderFlowControlFilter(environment);\n  }\n\n  @Bean\n  public ConsumerFlowControlFilter scbConsumerFlowControlFilter(Environment environment) {\n    return new ConsumerFlowControlFilter(environment);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/ProviderFlowControlFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class ProviderFlowControlFilter extends AbstractFilter implements ProviderFilter {\n  private final QpsControllerManager qpsControllerMgr;\n\n  public ProviderFlowControlFilter(Environment environment) {\n    qpsControllerMgr = new QpsControllerManager(true, environment);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 1990;\n  }\n\n  @Override\n  public String getName() {\n    return \"provider-flow-control\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (!Config.INSTANCE.isProviderEnabled()) {\n      return nextNode.onFilter(invocation);\n    }\n\n    String microserviceName = invocation.getContext(CoreConst.SRC_MICROSERVICE);\n    QpsStrategy qpsStrategy = qpsControllerMgr.getOrCreate(microserviceName, invocation);\n    if (qpsStrategy.isLimitNewRequest()) {\n      CommonExceptionData errorData = new CommonExceptionData(\n          \"provider request rejected by flow control.\");\n      return CompletableFuture.failedFuture(new InvocationException(QpsConst.TOO_MANY_REQUESTS_STATUS, errorData));\n    }\n    return nextNode.onFilter(invocation);\n  }\n\n  @VisibleForTesting\n  public QpsControllerManager getQpsControllerMgr() {\n    return qpsControllerMgr;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.qps;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\n\npublic final class QpsConst {\n  public static final StatusType TOO_MANY_REQUESTS_STATUS = new HttpStatus(429, \"Too Many Requests\");\n\n  private QpsConst() {\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsControllerManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.qps.strategy.AbstractQpsStrategy;\nimport org.apache.servicecomb.qps.strategy.IStrategyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.eventbus.Subscribe;\n\npublic final class QpsControllerManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(QpsControllerManager.class);\n\n  public static final String SEPARATOR = \".\";\n\n  /**\n   * Describe the relationship between configuration and qpsController.\n   */\n  private final Map<String, AbstractQpsStrategy> configQpsControllerMap = new ConcurrentHashMapEx<>();\n\n  /**\n   * Describe the relationship between qualifiedKey(format is \"microservice.schema.operation\") and qpsController.\n   */\n  private final Map<String, AbstractQpsStrategy> qualifiedNameControllerMap = new ConcurrentHashMapEx<>();\n\n  private AbstractQpsStrategy globalQpsStrategy;\n\n  private final String limitKeyPrefix;\n\n  private final String bucketKeyPrefix;\n\n  private final String globalLimitKey;\n\n  private final String globalBucketKey;\n\n  private final Environment environment;\n\n  public QpsControllerManager(boolean isProvider, Environment environment) {\n    this.environment = environment;\n    if (isProvider) {\n      limitKeyPrefix = Config.PROVIDER_LIMIT_KEY_PREFIX;\n      bucketKeyPrefix = Config.PROVIDER_BUCKET_KEY_PREFIX;\n      globalLimitKey = Config.PROVIDER_LIMIT_KEY_GLOBAL;\n      globalBucketKey = Config.PROVIDER_BUCKET_KEY_GLOBAL;\n    } else {\n      limitKeyPrefix = Config.CONSUMER_LIMIT_KEY_PREFIX;\n      bucketKeyPrefix = Config.CONSUMER_BUCKET_KEY_PREFIX;\n      globalLimitKey = Config.CONSUMER_LIMIT_KEY_GLOBAL;\n      globalBucketKey = Config.CONSUMER_BUCKET_KEY_GLOBAL;\n    }\n\n    initGlobalQpsController();\n    EventManager.register(this);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(Config.CONFIG_PREFIX)) {\n        configQpsControllerMap.clear();\n        qualifiedNameControllerMap.clear();\n        initGlobalQpsController();\n        break;\n      }\n    }\n  }\n\n  @VisibleForTesting\n  public Map<String, AbstractQpsStrategy> getQualifiedNameControllerMap() {\n    return qualifiedNameControllerMap;\n  }\n\n  public QpsStrategy getOrCreate(String microserviceName, Invocation invocation) {\n    final String name = validatedName(microserviceName);\n    return qualifiedNameControllerMap\n        .computeIfAbsent(\n            name + SEPARATOR + invocation.getOperationMeta().getSchemaQualifiedName(),\n            key -> create(key, name, invocation));\n  }\n\n  private String validatedName(String microserviceName) {\n    String name = microserviceName;\n    if (StringUtils.isEmpty(microserviceName)) {\n      name = Config.ANY_SERVICE;\n    }\n    return name;\n  }\n\n  /**\n   * Create relevant qpsLimit dynamicProperty and watch the configuration change.\n   * Search and return a valid qpsController.\n   */\n  @VisibleForTesting\n  AbstractQpsStrategy create(String qualifiedNameKey, String microserviceName,\n      Invocation invocation) {\n    createForService(qualifiedNameKey, microserviceName, invocation);\n    String qualifiedAnyServiceName = Config.ANY_SERVICE + qualifiedNameKey.substring(microserviceName.length());\n    createForService(qualifiedAnyServiceName, Config.ANY_SERVICE, invocation);\n\n    AbstractQpsStrategy strategy = searchQpsController(qualifiedNameKey);\n    if (strategy == null) {\n      strategy = searchQpsController(qualifiedAnyServiceName);\n    }\n    if (strategy == null) {\n      return globalQpsStrategy;\n    }\n    return strategy;\n  }\n\n  private void createForService(String qualifiedNameKey, String microserviceName,\n      Invocation invocation) {\n    // create \"microservice\"\n    createQpsControllerIfNotExist(microserviceName);\n    // create \"microservice.schema\"\n    createQpsControllerIfNotExist(\n        qualifiedNameKey.substring(0, microserviceName.length() + invocation.getSchemaId().length() + 1));\n    // create \"microservice.schema.operation\"\n    createQpsControllerIfNotExist(qualifiedNameKey);\n  }\n\n  /**\n   * <p> Use qualifiedNameKey to search {@link QpsStrategy}.\n   * Firstly try to search \"microservice.schema.operation\". If no valid result found, then try \"microservice.schema\",\n   * and then \"microservice\" or global qpsController(If there is a global qpsController).</p>\n   * <p> This method ensures that there is always an existing qpsController returned, as the relevant qpsController has\n   * been created and stored in {@link #create(String, String, Invocation)}</p>\n   *\n   * @param qualifiedNameKey qualifiedNameKey in {@link #qualifiedNameControllerMap}\n   * @return a qps controller, lower level controllers with valid qpsLimit have priority.\n   */\n  private AbstractQpsStrategy searchQpsController(String qualifiedNameKey) {\n    AbstractQpsStrategy qpsStrategy = configQpsControllerMap.get(qualifiedNameKey);\n    if (isValidQpsController(qpsStrategy)) {\n      return qpsStrategy;\n    }\n\n    int index = qualifiedNameKey.lastIndexOf(SEPARATOR);\n    while (index > 0) {\n      qpsStrategy = configQpsControllerMap.get(qualifiedNameKey.substring(0, index));\n      if (isValidQpsController(qpsStrategy)) {\n        return qpsStrategy;\n      }\n\n      index = qualifiedNameKey.lastIndexOf(SEPARATOR, index - 1);\n    }\n\n    if (isValidQpsController(qpsStrategy)) {\n      return qpsStrategy;\n    }\n\n    return null;\n  }\n\n  private boolean isValidQpsController(AbstractQpsStrategy qpsStrategy) {\n    return null != qpsStrategy && null != qpsStrategy.getQpsLimit();\n  }\n\n  private void createQpsControllerIfNotExist(String configKey) {\n    if (configQpsControllerMap.containsKey(configKey)) {\n      return;\n    }\n\n    LOGGER.info(\"Create qpsController, configKey = [{}]\", configKey);\n    AbstractQpsStrategy qpsStrategy = chooseStrategy(configKey,\n        environment.getProperty(limitKeyPrefix + configKey, Long.class),\n        environment.getProperty(bucketKeyPrefix + configKey, Long.class),\n        environment.getProperty(Config.STRATEGY_KEY));\n\n    configQpsControllerMap.put(configKey, qpsStrategy);\n  }\n\n  private void initGlobalQpsController() {\n    globalQpsStrategy = chooseStrategy(globalLimitKey,\n        environment.getProperty(globalLimitKey, Long.class, (long) Integer.MAX_VALUE),\n        environment.getProperty(globalBucketKey, Long.class),\n        environment.getProperty(Config.STRATEGY_KEY));\n  }\n\n  private AbstractQpsStrategy chooseStrategy(String configKey, Long limit, Long bucket,\n      String strategyName) {\n    if (StringUtils.isEmpty(strategyName)) {\n      strategyName = \"FixedWindow\";\n    }\n    AbstractQpsStrategy strategy = null;\n    List<IStrategyFactory> strategyFactories = SPIServiceUtils\n        .getOrLoadSortedService(IStrategyFactory.class);\n    for (IStrategyFactory strategyFactory : strategyFactories) {\n      strategy = strategyFactory.createStrategy(strategyName);\n      if (strategy != null) {\n        break;\n      }\n    }\n    if (strategy == null) {\n      throw new ServiceCombException(\n          \"the qps strategy name \" + strategyName + \" is not exist , please check.\");\n    }\n    strategy.setKey(configKey);\n    strategy.setQpsLimit(limit);\n    strategy.setBucketLimit(bucket);\n    return strategy;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/QpsStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\npublic interface QpsStrategy {\n\n  boolean isLimitNewRequest();\n\n  String name();\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/AbstractQpsStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps.strategy;\n\nimport org.apache.servicecomb.qps.QpsStrategy;\n\n\npublic abstract class AbstractQpsStrategy implements QpsStrategy {\n\n  private Long qpsLimit;\n\n  private Long bucketLimit;\n\n  private String key;\n\n  public Long getBucketLimit() {\n    return bucketLimit;\n  }\n\n  public void setBucketLimit(Long bucketLimit) {\n    this.bucketLimit = bucketLimit;\n  }\n\n  @Override\n  public abstract boolean isLimitNewRequest();\n\n  @Override\n  public abstract String name();\n\n  public void setQpsLimit(Long qpsLimit) {\n    this.qpsLimit = qpsLimit;\n  }\n\n  public Long getQpsLimit() {\n    return qpsLimit;\n  }\n\n  public String getKey() {\n    return key;\n  }\n\n  public void setKey(String key) {\n    this.key = key;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/DefaultStrategyFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.qps.strategy;\n\npublic class DefaultStrategyFactory implements IStrategyFactory {\n\n  public AbstractQpsStrategy createStrategy(String strategyName) {\n    switch (strategyName) {\n      case \"TokenBucket\":\n        return new TokenBucketStrategy();\n      case \"LeakyBucket\":\n        return new LeakyBucketStrategy();\n      case \"FixedWindow\":\n        return new FixedWindowStrategy();\n      default:\n        return null;\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/FixedWindowStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.qps.strategy;\n\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class FixedWindowStrategy extends AbstractQpsStrategy {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(FixedWindowStrategy.class);\n\n  // Interval begin time\n  private volatile long msCycleBegin;\n\n  // Request count between Interval begin and now in one interval\n  private final AtomicLong requestCount = new AtomicLong();\n\n  // request count  before an interval\n  private volatile long lastRequestCount = 1;\n\n  private static final int CYCLE_LENGTH = 1000;\n\n  private static final String STRATEGY_NAME = \"FixedWindow\";\n\n  // return true means new request need to be rejected\n  public boolean isLimitNewRequest() {\n    if (this.getQpsLimit() == null) {\n      throw new IllegalStateException(\"should not happen\");\n    }\n    long newCount = requestCount.incrementAndGet();\n    long msNow = System.currentTimeMillis();\n    //Time jump cause the new request injected\n    if (msNow - msCycleBegin > CYCLE_LENGTH || msNow < msCycleBegin) {\n      //no need worry about concurrency problem\n      lastRequestCount = newCount;\n      msCycleBegin = msNow;\n    }\n\n    // Configuration update and use is at the situation of multi-thread concurrency\n    // It is possible that operation level updated to null,but schema level or microservice level does not updated\n    boolean isLimitRequest = newCount - lastRequestCount >= this.getQpsLimit();\n    if (isLimitRequest){\n      LOGGER.warn(\"qps flowcontrol open, qpsLimit is {} and tps is {}\", this.getQpsLimit(), newCount - lastRequestCount + 1);\n    }\n    return isLimitRequest;\n  }\n\n  @Override\n  public String name() {\n    return STRATEGY_NAME;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/IStrategyFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps.strategy;\n\npublic interface IStrategyFactory {\n\n  AbstractQpsStrategy createStrategy(String strategyName);\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/LeakyBucketStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps.strategy;\n\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * leaky bucket algorithm include 2 implementation :\n * 1. as a meter : it's same as the token bucket.\n * 2. as a queue : the bucket size equal to qpsLimit.\n *\n **/\npublic class LeakyBucketStrategy extends AbstractQpsStrategy {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(LeakyBucketStrategy.class);\n\n  // Request count between Interval begin and now in one interval\n  private final AtomicLong requestCount = new AtomicLong();\n\n  private volatile long lastTime;\n\n  private long remainder = 0;\n\n  private static final String STRATEGY_NAME = \"LeakyBucket\";\n\n  @Override\n  public boolean isLimitNewRequest() {\n    if (this.getQpsLimit() == null) {\n      throw new IllegalStateException(\"should not happen\");\n    }\n    if (this.getBucketLimit() == null) {\n      this.setBucketLimit(Math.min(2 * this.getQpsLimit(), Integer.MAX_VALUE));\n    }\n    long nowTime = System.currentTimeMillis();\n    //get the num of te period time\n    long leakCount = ((nowTime - lastTime + remainder) / 1000) * this.getQpsLimit();\n    remainder = (nowTime - lastTime + remainder) % 1000;\n    // leak the request\n    if (requestCount.longValue() > leakCount) {\n      requestCount.addAndGet(-leakCount);\n    } else {\n      requestCount.set(0);\n    }\n    lastTime = nowTime;\n    //compute this time\n    if (requestCount.longValue() < this.getBucketLimit()) {\n      requestCount.incrementAndGet();\n      return false;\n    }\n    LOGGER.warn(\"qps flowcontrol open, qpsLimit is {} and tps is {}\", this.getQpsLimit(), requestCount.longValue() + 1);\n    return true;\n  }\n\n  @Override\n  public String name() {\n    return STRATEGY_NAME;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/java/org/apache/servicecomb/qps/strategy/TokenBucketStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps.strategy;\n\npublic class TokenBucketStrategy extends LeakyBucketStrategy {\n\n  private static final String STRATEGY_NAME = \"TokenBucket\";\n\n  @Override\n  public String name() {\n    return STRATEGY_NAME;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/resources/META-INF/services/org.apache.servicecomb.qps.strategy.IStrategyFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.qps.strategy.DefaultStrategyFactory\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.qps.FlowControlQpsConfiguration\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/QpsControllerManagerTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\nimport java.util.HashMap;\n\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.config.InMemoryDynamicPropertiesSource;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.qps.strategy.AbstractQpsStrategy;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class QpsControllerManagerTest {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void beforeTest() {\n    Mockito.when(environment.getProperty(Config.PROVIDER_LIMIT_KEY_GLOBAL, Long.class, (long) Integer.MAX_VALUE))\n        .thenReturn((long) Integer.MAX_VALUE);\n    Mockito.when(environment.getProperty(Config.CONSUMER_LIMIT_KEY_GLOBAL, Long.class, (long) Integer.MAX_VALUE))\n        .thenReturn((long) Integer.MAX_VALUE);\n  }\n\n  @AfterEach\n  public void afterTest() {\n\n  }\n\n  @Test\n  public void testGetOrCreate() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n\n    QpsControllerManager testQpsControllerManager = new QpsControllerManager(false, environment);\n    initTestQpsControllerManager(false, testQpsControllerManager, invocation, operationMeta);\n\n    // pojo\n    setConfigWithDefaultPrefix(false, \"pojo\", 100);\n    QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(100, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo2\", invocation);\n    Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"poj\", invocation);\n    Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    Mockito.when(environment.getProperty(\"servicecomb.flowcontrol.Consumer.qps.limit.poj.server\",\n        Long.class)).thenReturn(Long.valueOf(10000));\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(\"servicecomb.flowcontrol.Consumer.qps.limit.poj.server\", Long.valueOf(10000));\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"poj\", invocation);\n    Assertions.assertEquals(\"poj.server\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(((AbstractQpsStrategy) qpsStrategy).getQpsLimit(), (Long) 10000L);\n\n    InMemoryDynamicPropertiesSource.update(\"servicecomb.flowcontrol.Consumer.qps.limit.poj.server.test\", 20000);\n    Mockito.when(environment.getProperty(\"servicecomb.flowcontrol.Consumer.qps.limit.poj.server.test\",\n        Long.class)).thenReturn(Long.valueOf(20000));\n    updated = new HashMap<>();\n    updated.put(\"servicecomb.flowcontrol.Consumer.qps.limit.poj.server.test\", Long.valueOf(20000));\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"poj\", invocation);\n    Assertions.assertEquals(\"poj.server.test\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(((AbstractQpsStrategy) qpsStrategy).getQpsLimit(), (Long) 20000L);\n\n    testGetOrCreateCommon(false, testQpsControllerManager, invocation, operationMeta);\n  }\n\n  @Test\n  public void testGetOrCreateWithGlobalConfig() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n\n    QpsControllerManager testQpsControllerManager = new QpsControllerManager(true, environment);\n\n    // global\n    Mockito.when(environment.getProperty(Config.PROVIDER_LIMIT_KEY_GLOBAL, Long.class,\n        (long) Integer.MAX_VALUE)).thenReturn(50L);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(Config.PROVIDER_LIMIT_KEY_GLOBAL, 50L);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n\n    QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(50, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo2\", invocation);\n    Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(50, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"poj\", invocation);\n    Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(50, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n\n    // pojo\n    setConfigWithDefaultPrefix(true, \"pojo\", 100);\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(100, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo2\", invocation);\n    Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(50, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"poj\", invocation);\n    Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(50, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n\n    testGetOrCreateCommon(true, testQpsControllerManager, invocation, operationMeta);\n  }\n\n  @Test\n  public void testQualifiedNameKey() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"schema\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"schema.opr\");\n    QpsControllerManager qpsControllerManager = new QpsControllerManager(true, environment);\n    QpsStrategy qpsStrategy = qpsControllerManager.getOrCreate(\"service\", invocation);\n    Assertions.assertEquals(\"servicecomb.flowcontrol.Provider.qps.global.limit\",\n        ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"test_schema\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"test_schema.test_opr\");\n    qpsStrategy = qpsControllerManager.getOrCreate(\"test_service\", invocation);\n    Assertions.assertEquals(\"servicecomb.flowcontrol.Provider.qps.global.limit\",\n        ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"test_schema\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"test-schema.test-opr\");\n    qpsStrategy = qpsControllerManager.getOrCreate(\"test-service\", invocation);\n    Assertions.assertEquals(\"servicecomb.flowcontrol.Provider.qps.global.limit\",\n        ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"schema\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"schema.opr.tail\");\n    qpsStrategy = qpsControllerManager.getOrCreate(\"svc\", invocation);\n    Assertions.assertEquals(\"servicecomb.flowcontrol.Provider.qps.global.limit\",\n        ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"schema.opr2\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"schema.opr2.tail\");\n    qpsStrategy = qpsControllerManager.getOrCreate(\"svc\", invocation);\n    Assertions.assertEquals(\"servicecomb.flowcontrol.Provider.qps.global.limit\",\n        ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n  }\n\n  private void testGetOrCreateCommon(boolean isProvider, QpsControllerManager testQpsControllerManager,\n      Invocation invocation,\n      OperationMeta operationMeta) {\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n\n    setConfigWithDefaultPrefix(isProvider, \"pojo.server\", 200);\n    QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo.server\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(200, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server2.test\");\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(100, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"serve.test\");\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(100, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n\n    // pojo.server.test\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n    setConfigWithDefaultPrefix(isProvider, \"pojo.server.test\", 300);\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo.server.test\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(300, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test2\");\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo.server\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(200, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.tes\");\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    Assertions.assertEquals(\"pojo.server\", ((AbstractQpsStrategy) qpsStrategy).getKey());\n    Assertions.assertEquals(200, (long) ((AbstractQpsStrategy) qpsStrategy).getQpsLimit());\n  }\n\n  /**\n   * Init testQpsControllerManager to test search function.\n   */\n  private void initTestQpsControllerManager(boolean isProvider, QpsControllerManager testQpsControllerManager,\n      Invocation invocation,\n      OperationMeta operationMeta) {\n    // pojo.server.test\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n    QpsStrategy qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    // pojo.server.test2\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test2\");\n    testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    // pojo.server.tes\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.tes\");\n    testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    // pojo.server2.test\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server2\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server2.test\");\n    testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    // pojo.serve.test\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"serve\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"serve.test\");\n    testQpsControllerManager.getOrCreate(\"pojo\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    // pojo2.server.test\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"pojo2\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n\n    // poj.server.test\n    Mockito.when(invocation.getSchemaId()).thenReturn(\"server\");\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"server.test\");\n    qpsStrategy = testQpsControllerManager.getOrCreate(\"poj\", invocation);\n    if (isProvider) {\n      Assertions.assertEquals(Config.PROVIDER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    } else {\n      Assertions.assertEquals(Config.CONSUMER_LIMIT_KEY_GLOBAL, ((AbstractQpsStrategy) qpsStrategy).getKey());\n    }\n    Assertions.assertEquals(Integer.MAX_VALUE, ((AbstractQpsStrategy) qpsStrategy).getQpsLimit().intValue());\n  }\n\n  @Test\n  public void testMock() {\n    Invocation invocation = getMockInvocation(\"service\", \"schema\", \"oper\");\n    OperationMeta operationMeta = invocation.getOperationMeta();\n    SchemaMeta schemaMeta = operationMeta.getSchemaMeta();\n\n    Assertions.assertEquals(\"service\", operationMeta.getMicroserviceName());\n    Assertions.assertEquals(\"service.schema.oper\", operationMeta.getMicroserviceQualifiedName());\n    Assertions.assertEquals(\"schema.oper\", operationMeta.getSchemaQualifiedName());\n    Assertions.assertEquals(\"schema\", schemaMeta.getSchemaId());\n  }\n\n  public static Invocation getMockInvocation(String microserviceName, String schemaId, String operationId) {\n    return getMockInvocation(\n        getMockOperationMeta(microserviceName, schemaId, operationId));\n  }\n\n  private static Invocation getMockInvocation(OperationMeta mockOperationMeta) {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(mockOperationMeta);\n    return invocation;\n  }\n\n  public static OperationMeta getMockOperationMeta(String microserviceName, String schemaId, String operationId) {\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n\n    Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n    Mockito.when(operationMeta.getSchemaQualifiedName())\n        .thenReturn(schemaId + QpsControllerManager.SEPARATOR + operationId);\n    Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn(\n        microserviceName + QpsControllerManager.SEPARATOR + schemaId + QpsControllerManager.SEPARATOR\n            + operationId);\n    Mockito.when(operationMeta.getMicroserviceName()).thenReturn(microserviceName);\n    Mockito.when(schemaMeta.getSchemaId()).thenReturn(schemaId);\n\n    return operationMeta;\n  }\n\n  private static void setConfigWithDefaultPrefix(boolean isProvider, String key, int value) {\n    String configKey = Config.CONSUMER_LIMIT_KEY_PREFIX + key;\n    if (isProvider) {\n      configKey = Config.PROVIDER_LIMIT_KEY_PREFIX + key;\n    }\n\n    Mockito.when(environment.getProperty(configKey, Long.class)).thenReturn(Long.valueOf(value));\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(configKey, value);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n  }\n\n  private static void deleteConfigWithDefaultPrefix(boolean isProvider, String key) {\n    String configKey = Config.CONSUMER_LIMIT_KEY_PREFIX + key;\n    if (isProvider) {\n      configKey = Config.PROVIDER_LIMIT_KEY_PREFIX + key;\n    }\n\n    Mockito.when(environment.getProperty(configKey, Long.class)).thenReturn(null);\n    HashMap<String, Object> updated = new HashMap<>();\n    updated.put(configKey, null);\n    EventManager.post(ConfigurationChangedEvent.createIncremental(updated));\n  }\n\n  @Test\n  public void testDeleteQpsController() {\n\n    final String microserviceName = \"springmvcClient\";\n    final String schemaId = \"controller\";\n    final String operationId = \"add\";\n    final String configKey = \"springmvcClient.controller.add\";\n\n    QpsControllerManager testManager = new QpsControllerManager(true, environment);\n    Invocation testInvocation = getMockInvocation(microserviceName, schemaId, operationId);\n    Mockito.when(testInvocation.getSchemaId()).thenReturn(schemaId);\n\n    QpsStrategy strategy1 = testManager.getOrCreate(microserviceName, testInvocation);\n\n    setConfigWithDefaultPrefix(true, configKey, 1);\n\n    deleteConfigWithDefaultPrefix(true, configKey);\n\n    QpsStrategy strategy2 = testManager.getOrCreate(microserviceName, testInvocation);\n\n    Assertions.assertEquals(((AbstractQpsStrategy) strategy1).getQpsLimit(),\n        ((AbstractQpsStrategy) strategy2).getQpsLimit());\n    Assertions.assertEquals(((AbstractQpsStrategy) strategy1).getQpsLimit(), Long.valueOf(Integer.MAX_VALUE));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestQpsStrategy.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.qps;\n\nimport org.apache.servicecomb.qps.strategy.AbstractQpsStrategy;\nimport org.apache.servicecomb.qps.strategy.FixedWindowStrategy;\nimport org.apache.servicecomb.qps.strategy.LeakyBucketStrategy;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\n/**\n * @author GuoYl123\n * @since 2020/7/16\n **/\npublic class TestQpsStrategy {\n\n  @Test\n  public void testFixedWindowStrategy() {\n    AbstractQpsStrategy qpsStrategy = new FixedWindowStrategy();\n    qpsStrategy.setKey(\"abc\");\n    qpsStrategy.setQpsLimit(100L);\n    Assertions.assertFalse(qpsStrategy.isLimitNewRequest());\n\n    qpsStrategy.setQpsLimit(1L);\n    Assertions.assertTrue(qpsStrategy.isLimitNewRequest());\n  }\n\n\n  @Test\n  public void testLeakyBucketStrategy() {\n    LeakyBucketStrategy qpsStrategy = new LeakyBucketStrategy();\n    qpsStrategy.setKey(\"abc\");\n    qpsStrategy.setQpsLimit(100L);\n    Assertions.assertFalse(qpsStrategy.isLimitNewRequest());\n\n    qpsStrategy.setQpsLimit(1L);\n    qpsStrategy.setBucketLimit(1L);\n    Assertions.assertTrue(qpsStrategy.isLimitNewRequest());\n  }\n\n}\n"
  },
  {
    "path": "handlers/handler-governance/README.md",
    "content": "Enable governance features by handler.\n\nGovernance can be enabled in any different process layer, enable it in handler is most portable way.\n"
  },
  {
    "path": "handlers/handler-governance/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>handlers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>handler-governance</artifactId>\n  <name>Java Chassis::Handlers::Governance</name>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicecomb-governance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerInstanceBulkheadFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.handler.governance;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.governance.handler.InstanceBulkheadHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.github.resilience4j.bulkhead.Bulkhead;\nimport io.github.resilience4j.bulkhead.BulkheadFullException;\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCompletionStage;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ConsumerInstanceBulkheadFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerInstanceBulkheadFilter.class);\n\n  private final InstanceBulkheadHandler instanceBulkheadHandler;\n\n  @Autowired\n  public ConsumerInstanceBulkheadFilter(InstanceBulkheadHandler instanceBulkheadHandler) {\n    this.instanceBulkheadHandler = instanceBulkheadHandler;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1060;\n  }\n\n  @Override\n  public String getName() {\n    return \"instance-bulkhead\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (invocation.getEndpoint() == null) {\n      return CompletableFuture.failedFuture(new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          new CommonExceptionData(\"instance bulkhead should work after load balancer.\")));\n    }\n    Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation, nextNode);\n    DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n\n    addBulkhead(dcs, request);\n\n    CompletableFuture<Response> future = new CompletableFuture<>();\n\n    dcs.get().whenComplete((r, e) -> {\n      if (e == null) {\n        future.complete(r);\n        return;\n      }\n\n      if (e instanceof BulkheadFullException) {\n        // return 503 so that consumer can retry\n        future.completeExceptionally(new InvocationException(503, \"bulkhead is full and does not permit further calls.\",\n            new CommonExceptionData(\"bulkhead is full and does not permit further calls.\")));\n        LOGGER.warn(\"bulkhead is full and does not permit further calls by policy : {}\", e.getMessage());\n      } else {\n        future.completeExceptionally(e);\n      }\n    });\n\n    return future;\n  }\n\n  private void addBulkhead(DecorateCompletionStage<Response> dcs, GovernanceRequestExtractor request) {\n    Bulkhead bulkhead = instanceBulkheadHandler.getActuator(request);\n    if (bulkhead != null) {\n      dcs.withBulkhead(bulkhead);\n    }\n  }\n\n  private Supplier<CompletionStage<Response>> createBusinessCompletionStageSupplier(Invocation invocation,\n      FilterNode nextNode) {\n    return () -> nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerInstanceIsolationFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.handler.governance;\n\nimport java.time.Duration;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.governance.handler.InstanceIsolationHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.governance.policy.CircuitBreakerPolicy;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.github.resilience4j.circuitbreaker.CallNotPermittedException;\nimport io.github.resilience4j.circuitbreaker.CircuitBreaker;\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCompletionStage;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ConsumerInstanceIsolationFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerInstanceIsolationFilter.class);\n\n  private final InstanceIsolationHandler instanceIsolationHandler;\n\n  private DiscoveryManager discoveryManager;\n\n  @Autowired\n  public ConsumerInstanceIsolationFilter(InstanceIsolationHandler instanceIsolationHandler) {\n    this.instanceIsolationHandler = instanceIsolationHandler;\n  }\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1050;\n  }\n\n  @Override\n  public String getName() {\n    return \"instance-isolation\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    if (invocation.getEndpoint() == null) {\n      return CompletableFuture.failedFuture(new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          new CommonExceptionData(\"instance isolation should work after load balancer.\")));\n    }\n\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n    CircuitBreakerPolicy circuitBreakerPolicy = instanceIsolationHandler.matchPolicy(request);\n    if (circuitBreakerPolicy != null && circuitBreakerPolicy.isForceOpen()) {\n      return CompletableFuture.failedFuture(new InvocationException(Status.SERVICE_UNAVAILABLE,\n          new CommonExceptionData(\"Policy \\\" + circuitBreakerPolicy.getName() + \\\" forced open and deny requests\\\"\")));\n    }\n\n    Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation, nextNode);\n    DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);\n\n    addCircuitBreaker(dcs, request);\n\n    CompletableFuture<Response> future = new CompletableFuture<>();\n\n    dcs.get().whenComplete((r, e) -> {\n      if (e == null) {\n        future.complete(r);\n        return;\n      }\n\n      if (e instanceof CallNotPermittedException) {\n        LOGGER.warn(\"instance isolation circuitBreaker is open by policy : {}\", e.getMessage());\n        discoveryManager.onInstanceIsolated(invocation.getEndpoint().getMicroserviceInstance(),\n            Duration.parse(circuitBreakerPolicy.getWaitDurationInOpenState()).toMillis());\n        // return 503 so that consumer can retry\n        future.complete(Response.failResp(new InvocationException(Status.SERVICE_UNAVAILABLE,\n            new CommonExceptionData(\"instance isolation circuitBreaker is open.\"))));\n      } else {\n        future.completeExceptionally(e);\n      }\n    });\n\n    return future;\n  }\n\n  private void addCircuitBreaker(DecorateCompletionStage<Response> dcs, GovernanceRequestExtractor request) {\n    CircuitBreaker circuitBreaker = instanceIsolationHandler.getActuator(request);\n    if (circuitBreaker != null) {\n      dcs.withCircuitBreaker(circuitBreaker);\n    }\n  }\n\n  private Supplier<CompletionStage<Response>> createBusinessCompletionStageSupplier(Invocation invocation,\n      FilterNode nextNode) {\n    return () -> nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/HandlerGovernanceConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.handler.governance;\n\nimport org.apache.servicecomb.governance.handler.BulkheadHandler;\nimport org.apache.servicecomb.governance.handler.CircuitBreakerHandler;\nimport org.apache.servicecomb.governance.handler.InstanceBulkheadHandler;\nimport org.apache.servicecomb.governance.handler.InstanceIsolationHandler;\nimport org.apache.servicecomb.governance.handler.RateLimitingHandler;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ConditionalOnProperty(value = HandlerGovernanceConfiguration.GOVERNANCE_ENABLED,\n    havingValue = \"true\", matchIfMissing = true)\npublic class HandlerGovernanceConfiguration {\n  public static final String GOVERNANCE_PREFIX = \"servicecomb.governance\";\n\n  public static final String GOVERNANCE_ENABLED = GOVERNANCE_PREFIX + \".enabled\";\n\n  @Bean\n  public ConsumerInstanceBulkheadFilter scbConsumerInstanceBulkheadFilter(\n      InstanceBulkheadHandler instanceBulkheadHandler) {\n    return new ConsumerInstanceBulkheadFilter(instanceBulkheadHandler);\n  }\n\n  @Bean\n  public ConsumerInstanceIsolationFilter scbConsumerInstanceIsolationFilter(\n      InstanceIsolationHandler instanceIsolationHandler) {\n    return new ConsumerInstanceIsolationFilter(instanceIsolationHandler);\n  }\n\n  @Bean\n  public ProviderBulkheadFilter scbProviderBulkheadFilter(BulkheadHandler bulkheadHandler) {\n    return new ProviderBulkheadFilter(bulkheadHandler);\n  }\n\n  @Bean\n  public ProviderCircuitBreakerFilter scbProviderCircuitBreakerFilter(CircuitBreakerHandler circuitBreakerHandler) {\n    return new ProviderCircuitBreakerFilter(circuitBreakerHandler);\n  }\n\n  @Bean\n  public ProviderRateLimitingFilter scbProviderRateLimitingFilter(RateLimitingHandler rateLimitingHandler) {\n    return new ProviderRateLimitingFilter(rateLimitingHandler);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderBulkheadFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.handler.governance;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.governance.handler.BulkheadHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.github.resilience4j.bulkhead.Bulkhead;\nimport io.github.resilience4j.bulkhead.BulkheadFullException;\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCompletionStage;\n\npublic class ProviderBulkheadFilter extends AbstractFilter implements ProviderFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProviderBulkheadFilter.class);\n\n  private final BulkheadHandler bulkheadHandler;\n\n  @Autowired\n  public ProviderBulkheadFilter(BulkheadHandler bulkheadHandler) {\n    this.bulkheadHandler = bulkheadHandler;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 1880;\n  }\n\n  @Override\n  public String getName() {\n    return \"provider-bulkhead\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n\n    Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation, nextNode);\n    DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n\n    addBulkhead(dcs, request);\n\n    CompletableFuture<Response> future = new CompletableFuture<>();\n\n    dcs.get().whenComplete((r, e) -> {\n      if (e == null) {\n        future.complete(r);\n        return;\n      }\n\n      if (e instanceof BulkheadFullException) {\n        future.completeExceptionally(\n            new InvocationException(429, \"bulkhead is full and does not permit further calls.\",\n                new CommonExceptionData(\"bulkhead is full and does not permit further calls.\")));\n        LOGGER.warn(\"bulkhead is full and does not permit further calls by policy : {}\", e.getMessage());\n      } else {\n        future.completeExceptionally(e);\n      }\n    });\n\n    return future;\n  }\n\n  private void addBulkhead(DecorateCompletionStage<Response> dcs, GovernanceRequestExtractor request) {\n    Bulkhead bulkhead = bulkheadHandler.getActuator(request);\n    if (bulkhead != null) {\n      dcs.withBulkhead(bulkhead);\n    }\n  }\n\n  private Supplier<CompletionStage<Response>> createBusinessCompletionStageSupplier(Invocation invocation,\n      FilterNode nextNode) {\n    return () -> nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderCircuitBreakerFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.handler.governance;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.governance.handler.CircuitBreakerHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.github.resilience4j.circuitbreaker.CallNotPermittedException;\nimport io.github.resilience4j.circuitbreaker.CircuitBreaker;\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCompletionStage;\n\npublic class ProviderCircuitBreakerFilter extends AbstractFilter implements ProviderFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProviderCircuitBreakerFilter.class);\n\n  private final CircuitBreakerHandler circuitBreakerHandler;\n\n  @Autowired\n  public ProviderCircuitBreakerFilter(CircuitBreakerHandler circuitBreakerHandler) {\n    this.circuitBreakerHandler = circuitBreakerHandler;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 1890;\n  }\n\n  @Override\n  public String getName() {\n    return \"provider-circuit-breaker\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation, nextNode);\n    DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n\n    addCircuitBreaker(dcs, request);\n\n    CompletableFuture<Response> future = new CompletableFuture<>();\n\n    dcs.get().whenComplete((r, e) -> {\n      if (e == null) {\n        future.complete(r);\n        return;\n      }\n\n      if (e instanceof CallNotPermittedException) {\n        future.completeExceptionally(new InvocationException(429, \"circuitBreaker is open.\",\n            new CommonExceptionData(\"circuitBreaker is open.\")));\n        LOGGER.warn(\"circuitBreaker is open by policy : {}\", e.getMessage());\n      } else {\n        future.completeExceptionally(e);\n      }\n    });\n\n    return future;\n  }\n\n  private void addCircuitBreaker(DecorateCompletionStage<Response> dcs, GovernanceRequestExtractor request) {\n    CircuitBreaker circuitBreaker = circuitBreakerHandler.getActuator(request);\n    if (circuitBreaker != null) {\n      dcs.withCircuitBreaker(circuitBreaker);\n    }\n  }\n\n  private Supplier<CompletionStage<Response>> createBusinessCompletionStageSupplier(Invocation invocation,\n      FilterNode nextNode) {\n    return () -> nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderRateLimitingFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.handler.governance;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\nimport java.util.function.Supplier;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.governance.handler.RateLimitingHandler;\nimport org.apache.servicecomb.governance.marker.GovernanceRequestExtractor;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.github.resilience4j.decorators.Decorators;\nimport io.github.resilience4j.decorators.Decorators.DecorateCompletionStage;\nimport io.github.resilience4j.ratelimiter.RateLimiter;\nimport io.github.resilience4j.ratelimiter.RequestNotPermitted;\n\npublic class ProviderRateLimitingFilter extends AbstractFilter implements ProviderFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProviderRateLimitingFilter.class);\n\n  private final RateLimitingHandler rateLimitingHandler;\n\n  @Autowired\n  public ProviderRateLimitingFilter(RateLimitingHandler rateLimitingHandler) {\n    this.rateLimitingHandler = rateLimitingHandler;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 1900;\n  }\n\n  @Override\n  public String getName() {\n    return \"rate-limiting\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n\n    Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation, nextNode);\n    DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);\n    GovernanceRequestExtractor request = MatchType.createGovHttpRequest(invocation);\n\n    addRateLimiting(dcs, request);\n\n    CompletableFuture<Response> future = new CompletableFuture<>();\n\n    dcs.get().whenComplete((r, e) -> {\n      if (e == null) {\n        future.complete(r);\n        return;\n      }\n\n      if (e instanceof RequestNotPermitted) {\n        future.completeExceptionally(\n            new InvocationException(429, \"rate limited.\", new CommonExceptionData(\"rate limited.\")));\n        LOGGER.warn(\"the request is rate limit by policy : {}\", e.getMessage());\n      } else {\n        future.completeExceptionally(e);\n      }\n    });\n\n    return future;\n  }\n\n  private void addRateLimiting(DecorateCompletionStage<Response> dcs, GovernanceRequestExtractor request) {\n    RateLimiter rateLimiter = rateLimitingHandler.getActuator(request);\n    if (rateLimiter != null) {\n      dcs.withRateLimiter(rateLimiter);\n    }\n  }\n\n  private Supplier<CompletionStage<Response>> createBusinessCompletionStageSupplier(Invocation invocation,\n      FilterNode nextNode) {\n    return () -> nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-governance/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.handler.governance.HandlerGovernanceConfiguration\n"
  },
  {
    "path": "handlers/handler-loadbalance/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>handlers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>handler-loadbalance</artifactId>\n  <name>Java Chassis::Handlers::Loadbalance</name>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.github.resilience4j</groupId>\n      <artifactId>resilience4j-all</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "handlers/handler-loadbalance/readme.MD",
    "content": "参考： https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers\nLoadBalancer\nRule\nPing\nServerList\nServerListFilter\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\n\n/**\n * configuration items\n */\npublic final class Configuration {\n  //// 2.1 configuration items\n  public static final String ROOT = \"servicecomb.loadbalance.\";\n\n  public static final String RULE_STRATEGY_GLOBAL = \"servicecomb.loadbalance.strategy.name\";\n\n  public static final String RULE_STRATEGY_NAME = \"strategy.name\";\n\n  // 2.0 configuration items\n  public static final String ROOT_20 = \"ribbon.\";\n\n  // SessionStickinessRule configuration\n  public static final String SESSION_TIMEOUT_IN_SECONDS = \"SessionStickinessRule.sessionTimeoutInSeconds\";\n\n  public static final String SUCCESSIVE_FAILED_TIMES = \"SessionStickinessRule.successiveFailedTimes\";\n\n  public static final String FILTER_ISOLATION = \"isolation.\";\n\n  public static final String FILTER_MAX_SINGLE_TEST_WINDOW = \"maxSingleTestWindow\";\n\n  public static final String TRANSACTIONCONTROL_OPTIONS_PREFIX_PATTERN =\n      \"servicecomb.loadbalance.%s.transactionControl.options\";\n\n  public static final Configuration INSTANCE = new Configuration();\n\n  public record RuleType(int type, String value) {\n    public static final int TYPE_SCHEMA = 1;\n\n    public static final int TYPE_OPERATION = 2;\n\n    public String getValue() {\n      return value;\n    }\n\n    public int getType() {\n      return type;\n    }\n  }\n\n  private Configuration() {\n  }\n\n  public RuleType getRuleStrategyName(Invocation invocation) {\n    String value = getStringProperty(null, ROOT + invocation.getMicroserviceName() + \".\" +\n        invocation.getSchemaId() + \".\" + invocation.getOperationName() + \".\" + RULE_STRATEGY_NAME);\n    if (value != null) {\n      return new RuleType(RuleType.TYPE_OPERATION, value);\n    }\n    value = getStringProperty(null, ROOT + invocation.getMicroserviceName() + \".\" +\n        invocation.getSchemaId() + \".\" + RULE_STRATEGY_NAME);\n    if (value != null) {\n      return new RuleType(RuleType.TYPE_SCHEMA, value);\n    }\n    value = getStringProperty(null, ROOT + invocation.getMicroserviceName() + \".\" +\n        RULE_STRATEGY_NAME);\n    if (value != null) {\n      return new RuleType(RuleType.TYPE_SCHEMA, value);\n    }\n    return new RuleType(RuleType.TYPE_SCHEMA,\n        getStringProperty(\"RoundRobin\", RULE_STRATEGY_GLOBAL));\n  }\n\n  public int getSessionTimeoutInSeconds(String microservice) {\n    final int defaultValue = 30;\n    String p = getStringProperty(\"30\",\n        ROOT + microservice + \".\" + SESSION_TIMEOUT_IN_SECONDS,\n        ROOT + SESSION_TIMEOUT_IN_SECONDS);\n    try {\n      return Integer.parseInt(p); // can be negative\n    } catch (NumberFormatException e) {\n      return defaultValue;\n    }\n  }\n\n  public int getSuccessiveFailedTimes(String microservice) {\n    final int defaultValue = 5;\n    String p = getStringProperty(\"5\",\n        ROOT + microservice + \".\" + SUCCESSIVE_FAILED_TIMES,\n        ROOT + SUCCESSIVE_FAILED_TIMES);\n    try {\n      return Integer.parseInt(p); // can be negative\n    } catch (NumberFormatException e) {\n      return defaultValue;\n    }\n  }\n\n  public int getMaxSingleTestWindow() {\n    final int defaultValue = 60000;\n    String p = getStringProperty(Integer.toString(defaultValue),\n        ROOT + FILTER_ISOLATION + FILTER_MAX_SINGLE_TEST_WINDOW);\n    try {\n      int result = Integer.parseInt(p);\n      if (result >= 0) {\n        return result;\n      }\n      return defaultValue;\n    } catch (NumberFormatException e) {\n      return defaultValue;\n    }\n  }\n\n  public Map<String, String> getFlowsplitFilterOptions(String microservice) {\n    String keyPrefix = String.format(TRANSACTIONCONTROL_OPTIONS_PREFIX_PATTERN, microservice);\n    return ConfigUtil.stringPropertiesWithPrefix(LegacyPropertyFactory.getEnvironment(), keyPrefix);\n  }\n\n  public static String getStringProperty(String defaultValue, String... keys) {\n    String property;\n    for (String key : keys) {\n      property = LegacyPropertyFactory.getStringProperty(key);\n      if (property != null) {\n        return property;\n      }\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance;\n\n/**\n * By implements ExtensionsFactory, users can add new extends for rules, filters, etc.\n */\npublic interface ExtensionsFactory {\n  boolean isSupport(String key, String value);\n\n  default RuleExt createLoadBalancerRule(String ruleName) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\n\npublic class ExtensionsManager {\n  private final List<ExtensionsFactory> extensionsFactories;\n\n  public ExtensionsManager(List<ExtensionsFactory> extensionsFactories) {\n    this.extensionsFactories = extensionsFactories;\n  }\n\n  public RuleExt createLoadBalancerRule(String ruleStrategyName) {\n    RuleExt rule = null;\n\n    for (ExtensionsFactory factory : extensionsFactories) {\n      if (factory.isSupport(Configuration.RULE_STRATEGY_NAME, ruleStrategyName)) {\n        rule = factory.createLoadBalancerRule(ruleStrategyName);\n        break;\n      }\n    }\n\n    if (rule == null) {\n      rule = new RoundRobinRuleExt();\n    }\n\n    return rule;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalanceConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.loadbalance.filter.InstancePropertyDiscoveryFilter;\nimport org.apache.servicecomb.loadbalance.filter.PriorityInstancePropertyDiscoveryFilter;\nimport org.apache.servicecomb.loadbalance.filter.ServerDiscoveryFilter;\nimport org.apache.servicecomb.loadbalance.filter.ZoneAwareDiscoveryFilter;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ConditionalOnProperty(value = LoadBalanceConfiguration.LOAD_BALANCE_ENABLED,\n    havingValue = \"true\", matchIfMissing = true)\npublic class LoadBalanceConfiguration {\n  public static final String LOAD_BALANCE_PREFIX = \"servicecomb.loadbalance\";\n\n  public static final String LOAD_BALANCE_ENABLED = LOAD_BALANCE_PREFIX + \".enabled\";\n\n  @Bean\n  public LoadBalanceFilter scbLoadBalanceFilter(ExtensionsManager extensionsManager, DiscoveryTree discoveryTree,\n      SCBEngine scbEngine) {\n    return new LoadBalanceFilter(extensionsManager, discoveryTree, scbEngine);\n  }\n\n  @Bean\n  public RuleNameExtensionsFactory scbRuleNameExtensionsFactory() {\n    return new RuleNameExtensionsFactory();\n  }\n\n  @Bean\n  public ExtensionsManager scbExtensionsManager(List<ExtensionsFactory> extensionsFactories) {\n    return new ExtensionsManager(extensionsFactories);\n  }\n\n  @Bean\n  public PriorityInstancePropertyDiscoveryFilter scbPriorityInstancePropertyDiscoveryFilter() {\n    return new PriorityInstancePropertyDiscoveryFilter();\n  }\n\n  @Bean\n  public InstancePropertyDiscoveryFilter scbInstancePropertyDiscoveryFilter() {\n    return new InstancePropertyDiscoveryFilter();\n  }\n\n  @Bean\n  public ServerDiscoveryFilter scbServerDiscoveryFilter() {\n    return new ServerDiscoveryFilter();\n  }\n\n  @Bean\n  public ZoneAwareDiscoveryFilter scbZoneAwareDiscoveryFilter() {\n    return new ZoneAwareDiscoveryFilter();\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalanceFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance;\n\nimport java.net.URI;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.governance.RetryContext;\nimport org.apache.servicecomb.foundation.common.cache.VersionedCache;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.loadbalance.Configuration.RuleType;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.eventbus.Subscribe;\n\nimport io.github.resilience4j.core.metrics.Metrics.Outcome;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class LoadBalanceFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  public static final String CONTEXT_KEY_LAST_SERVER = \"x-context-last-server\";\n\n  // Enough times to make sure to choose a different server in high volume.\n  private static final int COUNT = 17;\n\n  public static final String CONTEXT_KEY_SERVER_LIST = \"x-context-server-list\";\n\n  public static final String SERVICECOMB_SERVER_ENDPOINT = \"scb-endpoint\";\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(LoadBalanceFilter.class);\n\n  private final DiscoveryTree discoveryTree;\n\n  // key为grouping filter qualified name\n  private final Map<String, LoadBalancer> loadBalancerMap = new ConcurrentHashMapEx<>();\n\n  private final Object lock = new Object();\n\n  private final ExtensionsManager extensionsManager;\n\n  private final SCBEngine scbEngine;\n\n  // set endpoint in invocation.localContext\n  // ignore logic of loadBalance\n  public boolean supportDefinedEndpoint;\n\n  @Autowired\n  public LoadBalanceFilter(ExtensionsManager extensionsManager,\n      DiscoveryTree discoveryTree, SCBEngine scbEngine) {\n    preCheck(scbEngine);\n    this.scbEngine = scbEngine;\n    this.supportDefinedEndpoint = this.scbEngine.getEnvironment()\n        .getProperty(\"servicecomb.loadbalance.userDefinedEndpoint.enabled\",\n            boolean.class, false);\n    this.extensionsManager = extensionsManager;\n    this.discoveryTree = discoveryTree;\n    EventManager.register(this);\n  }\n\n  @Subscribe\n  @SuppressWarnings(\"unused\")\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    Set<String> changedKeys = event.getChanged();\n    for (String key : changedKeys) {\n      if (key.startsWith(Configuration.ROOT)) {\n        synchronized (lock) {\n          clearLoadBalancer();\n        }\n        LOGGER.info(\"clear load balance rule for configuration changed, {}\", key);\n        break;\n      }\n    }\n  }\n\n  private void preCheck(SCBEngine scbEngine) {\n    // Old configurations check.Just print an error, because configurations may given in dynamic and fail on runtime.\n    String policyName = scbEngine.getEnvironment()\n        .getProperty(\"servicecomb.loadbalance.NFLoadBalancerRuleClassName\");\n    if (!StringUtils.isEmpty(policyName)) {\n      LOGGER.error(\"[servicecomb.loadbalance.NFLoadBalancerRuleClassName] is not supported anymore.\" +\n          \"use [servicecomb.loadbalance.strategy.name] instead.\");\n    }\n\n    String filterNames = scbEngine.getEnvironment()\n        .getProperty(\"servicecomb.loadbalance.serverListFilters\");\n    if (!StringUtils.isEmpty(filterNames)) {\n      LOGGER.error(\n          \"Server list implementation changed to SPI. Configuration [servicecomb.loadbalance.serverListFilters]\" +\n              \" is not used any more. For ServiceComb defined filters, you do not need config and can \"\n              + \"remove this configuration safely. If you define your own filter, need to change it to SPI to make it work.\");\n    }\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER;\n  }\n\n  @Override\n  public String getName() {\n    return \"load-balance\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    try {\n      if (handleSuppliedEndpoint(invocation)) {\n        invocation.addLocalContext(RetryContext.RETRY_LOAD_BALANCE, false);\n        return nextNode.onFilter(invocation);\n      }\n    } catch (Exception e) {\n      return CompletableFuture.failedFuture(e);\n    }\n\n    invocation.addLocalContext(RetryContext.RETRY_LOAD_BALANCE, true);\n\n    LoadBalancer loadBalancer = getOrCreateLoadBalancer(invocation);\n\n    return send(invocation, nextNode, loadBalancer);\n  }\n\n  // user's can invoke a service by supplying target Endpoint.\n  // in this case, do not use load balancer, and no stats of server calculated, no retrying.\n  private boolean handleSuppliedEndpoint(Invocation invocation) throws Exception {\n    if (invocation.isEdge()) {\n      return false;\n    }\n    if (invocation.getEndpoint() != null) {\n      return true;\n    }\n\n    if (supportDefinedEndpoint) {\n      return defineEndpointAndHandle(invocation);\n    }\n\n    return false;\n  }\n\n  private Endpoint parseEndpoint(String endpointUri) throws Exception {\n    URI formatUri = new URI(endpointUri);\n    Transport transport = scbEngine.getTransportManager().findTransport(formatUri.getScheme());\n    if (transport == null) {\n      LOGGER.error(\"not deployed transport {}, ignore {}.\", formatUri.getScheme(), endpointUri);\n      throw new InvocationException(Status.BAD_REQUEST,\n          \"the endpoint's transport is not found.\");\n    }\n    return new Endpoint(transport, endpointUri);\n  }\n\n  private boolean defineEndpointAndHandle(Invocation invocation) throws Exception {\n    Object endpoint = invocation.getLocalContext(SERVICECOMB_SERVER_ENDPOINT);\n    if (endpoint == null) {\n      return false;\n    }\n    if (endpoint instanceof String) {\n      // compatible to old usage\n      endpoint = parseEndpoint((String) endpoint);\n    }\n\n    invocation.setEndpoint((Endpoint) endpoint);\n    return true;\n  }\n\n  private void clearLoadBalancer() {\n    loadBalancerMap.clear();\n  }\n\n  @VisibleForTesting\n  CompletableFuture<Response> send(Invocation invocation, FilterNode filterNode, LoadBalancer chosenLB) {\n    long time = System.currentTimeMillis();\n    ServiceCombServer server = chooseServer(invocation, chosenLB);\n    if (null == server) {\n      return CompletableFuture.failedFuture(\n          new InvocationException(Status.INTERNAL_SERVER_ERROR,\n              String.format(\"No available address found for %s/%s.\", invocation.getAppId(),\n                  invocation.getMicroserviceName())));\n    }\n    invocation.setEndpoint(server.getEndpoint());\n    return filterNode.onFilter(invocation).whenComplete((r, e) -> {\n      if (e != null || isFailedResponse(r)) {\n        server.getServerMetrics().record((System.currentTimeMillis() - time), TimeUnit.MILLISECONDS, Outcome.ERROR);\n      } else {\n        server.getServerMetrics().record((System.currentTimeMillis() - time), TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n      }\n    });\n  }\n\n  private ServiceCombServer chooseServer(Invocation invocation, LoadBalancer chosenLB) {\n    RetryContext retryContext = invocation.getLocalContext(RetryContext.RETRY_CONTEXT);\n    if (retryContext == null) {\n      return chosenLB.chooseServer(invocation);\n    }\n\n    if (!retryContext.isRetry()) {\n      ServiceCombServer server = chosenLB.chooseServer(invocation);\n      invocation.addLocalContext(CONTEXT_KEY_LAST_SERVER, server);\n      return server;\n    }\n\n    ServiceCombServer lastServer = invocation.getLocalContext(CONTEXT_KEY_LAST_SERVER);\n    ServiceCombServer nextServer = lastServer;\n    if (!retryContext.trySameServer()) {\n      for (int i = 0; i < COUNT; i++) {\n        ServiceCombServer s = chosenLB.chooseServer(invocation);\n        if (s == null) {\n          break;\n        }\n        if (!s.equals(nextServer)) {\n          nextServer = s;\n          break;\n        }\n      }\n    }\n\n    LOGGER.warn(\"operation failed {}, retry to instance [{}], last instance [{}], trace id {}\",\n        invocation.getMicroserviceQualifiedName(),\n        nextServer == null ? \"\" : nextServer.getEndpoint().getEndpoint(),\n        lastServer == null ? \"\" : nextServer.getEndpoint().getEndpoint(),\n        invocation.getTraceId());\n    invocation.addLocalContext(CONTEXT_KEY_LAST_SERVER, nextServer);\n    return nextServer;\n  }\n\n  protected boolean isFailedResponse(Response resp) {\n    if (resp.isFailed()) {\n      if (resp.getResult() instanceof InvocationException) {\n        InvocationException e = resp.getResult();\n        return e.getStatusCode() == ExceptionFactory.CONSUMER_INNER_STATUS_CODE\n            || e.getStatusCode() == Status.SERVICE_UNAVAILABLE.getStatusCode()\n            || e.getStatusCode() == Status.REQUEST_TIMEOUT.getStatusCode();\n      } else {\n        return true;\n      }\n    } else {\n      return false;\n    }\n  }\n\n  protected LoadBalancer getOrCreateLoadBalancer(Invocation invocation) {\n    DiscoveryContext context = new DiscoveryContext();\n    context.setInputParameters(invocation);\n    VersionedCache serversVersionedCache = discoveryTree.discovery(context,\n        invocation.getAppId(),\n        invocation.getMicroserviceName());\n    invocation.addLocalContext(CONTEXT_KEY_SERVER_LIST, serversVersionedCache.data());\n\n    RuleType ruleType = Configuration.INSTANCE.getRuleStrategyName(invocation);\n    String cacheKey;\n    if (ruleType.getType() == RuleType.TYPE_SCHEMA) {\n      cacheKey = invocation.getAppId() + \"-\" +\n          invocation.getMicroserviceName() + \"-\" + invocation.getSchemaId();\n    } else {\n      cacheKey = invocation.getAppId() + \"-\" +\n          invocation.getMicroserviceName() + \"-\" + invocation.getSchemaId() + \"-\" + invocation.getOperationName();\n    }\n    return loadBalancerMap.computeIfAbsent(cacheKey,\n        key -> createLoadBalancer(ruleType, key, invocation.getMicroserviceName()));\n  }\n\n  private LoadBalancer createLoadBalancer(RuleType ruleType, String cacheKey, String microserviceName) {\n    RuleExt rule = extensionsManager.createLoadBalancerRule(ruleType.getValue());\n    LOGGER.info(\"Using load balance rule {} for microservice {}.\", rule.getClass().getName(), cacheKey);\n    return new LoadBalancer(rule, microserviceName);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n *  A load balancer with RuleExt and ServerListFilterExt\n */\npublic class LoadBalancer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(LoadBalancer.class);\n\n  private static final AtomicInteger id = new AtomicInteger(0);\n\n  private final RuleExt rule;\n\n  private final String microServiceName;\n\n  private List<ServerListFilterExt> filters;\n\n  public LoadBalancer(RuleExt rule, String microServiceName) {\n    this.microServiceName = microServiceName;\n    this.rule = rule;\n    // load new instances, because filters work on service information\n    this.filters = SPIServiceUtils.loadSortedService(ServerListFilterExt.class);\n    this.rule.setLoadBalancer(this);\n    this.filters.forEach((item) -> item.setLoadBalancer(this));\n  }\n\n  public ServiceCombServer chooseServer(Invocation invocation) {\n    List<ServiceCombServer> servers = invocation.getLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST);\n    int serversCount = servers.size();\n    for (ServerListFilterExt filterExt : filters) {\n      if (!filterExt.enabled()) {\n        continue;\n      }\n      servers = filterExt.getFilteredListOfServers(servers, invocation);\n      if (servers.isEmpty() && serversCount > 0) {\n        LOGGER.warn(\"There are not servers exist after filtered by {}.\", filterExt.getClass());\n        break;\n      }\n    }\n    ServiceCombServer server = rule.choose(servers, invocation);\n    if (null == server) {\n      return null;\n    }\n    return server;\n  }\n\n  public String getMicroServiceName() {\n    return microServiceName;\n  }\n\n  @VisibleForTesting\n  void setFilters(List<ServerListFilterExt> filters) {\n    this.filters = filters;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\nimport java.util.concurrent.ThreadLocalRandom;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n * A random rule.\n */\npublic class RandomRuleExt implements RuleExt {\n  @Override\n  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {\n    if (servers.isEmpty()) {\n      return null;\n    }\n    int index = ThreadLocalRandom.current().nextInt(servers.size());\n    return servers.get(index);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n * A round robin rule\n */\npublic class RoundRobinRuleExt implements RuleExt {\n  private final AtomicInteger counter = new AtomicInteger(0);\n\n  @Override\n  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {\n    if (servers.isEmpty()) {\n      return null;\n    }\n    int index = Math.abs(counter.getAndIncrement()) % servers.size();\n    return servers.get(index);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n * Load balance rule to support invocation based filters.\n */\npublic interface RuleExt {\n  default void setLoadBalancer(LoadBalancer loadBalancer) {\n  }\n\n  ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation);\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtensionsFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.Collection;\n\nimport com.google.common.collect.Lists;\n\npublic class RuleNameExtensionsFactory implements ExtensionsFactory {\n  private static final Collection<String> ACCEPT_KEYS = Lists.newArrayList(\n      Configuration.RULE_STRATEGY_NAME);\n\n  private static final String RULE_RoundRobin = \"RoundRobin\";\n\n  private static final String RULE_Random = \"Random\";\n\n  private static final String RULE_WeightedResponse = \"WeightedResponse\";\n\n  private static final String RULE_SessionStickiness = \"SessionStickiness\";\n\n  private static final Collection<String> ACCEPT_VALUES = Lists.newArrayList(\n      RULE_RoundRobin,\n      RULE_Random,\n      RULE_WeightedResponse,\n      RULE_SessionStickiness);\n\n  @Override\n  public boolean isSupport(String key, String value) {\n    return ACCEPT_KEYS.contains(key) && ACCEPT_VALUES.contains(value);\n  }\n\n  @Override\n  public RuleExt createLoadBalancerRule(String ruleName) {\n    if (RULE_RoundRobin.equals(ruleName)) {\n      return new RoundRobinRuleExt();\n    } else if (RULE_Random.equals(ruleName)) {\n      return new RandomRuleExt();\n    } else if (RULE_WeightedResponse.equals(ruleName)) {\n      return new WeightedResponseTimeRuleExt();\n    } else if (RULE_SessionStickiness.equals(ruleName)) {\n      return new SessionStickinessRule();\n    } else {\n      throw new IllegalStateException(\"unexpected code to reach here, value is \" + ruleName);\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n *  Base interface for server list filters.\n *\n *  Robin ServerListFilter can not support invocation based filter strategies, so we create a new one to\n *  support this.\n */\npublic interface ServerListFilterExt {\n  int ORDER_NORMAL = 0;\n\n  default int getOrder() {\n    return ORDER_NORMAL;\n  }\n\n  default boolean enabled() {\n    return true;\n  }\n\n  default void setLoadBalancer(LoadBalancer loadBalancer) {\n  }\n\n  List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> servers, Invocation invocation);\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.concurrent.TimeUnit;\n\nimport io.github.resilience4j.core.metrics.FixedSizeSlidingWindowMetrics;\nimport io.github.resilience4j.core.metrics.Metrics.Outcome;\nimport io.github.resilience4j.core.metrics.Snapshot;\n\n/**\n * ServiceCombServer states\n */\npublic class ServerMetrics {\n  private final FixedSizeSlidingWindowMetrics metrics = new FixedSizeSlidingWindowMetrics(50);\n\n  public Snapshot record(long duration, TimeUnit durationUnit, Outcome outcome) {\n    return metrics.record(duration, durationUnit, outcome);\n  }\n\n  public Snapshot getSnapshot() {\n    return metrics.getSnapshot();\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.Objects;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\n\n/**\n *  Server object used for transports and load balancer.\n *\n */\npublic class ServiceCombServer {\n  private final Endpoint endpoint;\n\n  private final String microserviceName;\n\n  private final ServerMetrics serverMetrics;\n\n  public ServiceCombServer(String microserviceName, Endpoint endpoint) {\n    this.microserviceName = microserviceName;\n    this.endpoint = endpoint;\n    this.serverMetrics = new ServerMetrics();\n  }\n\n  public String getMicroserviceName() {\n    return this.microserviceName;\n  }\n\n  public Endpoint getEndpoint() {\n    return endpoint;\n  }\n\n  public DiscoveryInstance getInstance() {\n    return endpoint.getMicroserviceInstance();\n  }\n\n  @Override\n  public String toString() {\n    return endpoint.getEndpoint();\n  }\n\n  public String getHost() {\n    return endpoint.getEndpoint();\n  }\n\n  public ServerMetrics getServerMetrics() {\n    return serverMetrics;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (o instanceof ServiceCombServer) {\n      return this.getInstance().getInstanceId()\n          .equals(((ServiceCombServer) o).getInstance().getInstanceId())\n          && StringUtils.equals(endpoint.getEndpoint(), ((ServiceCombServer) o).getEndpoint().getEndpoint());\n    } else {\n      return false;\n    }\n  }\n\n  @Override\n  public int hashCode() {\n    return Objects.hash(this.getInstance().getInstanceId(), this.endpoint);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\n/**\n * 会话保持策略：优先选择上一次选中的服务器，保证请求都发送到同一个服务器上去。\n * 提供当会话过期或者失败次数超过限制后，轮询选择其他服务器的能力。\n *\n */\npublic class SessionStickinessRule implements RuleExt {\n  private static final Logger LOG = LoggerFactory.getLogger(SessionStickinessRule.class);\n\n  private final Object lock = new Object();\n\n  // use random rule as the trigger rule, to prevent consumer instance select the same producer instance.\n  private final RuleExt triggerRule;\n\n  private volatile ServiceCombServer lastServer = null;\n\n  private volatile long lastAccessedTime = 0;\n\n  private volatile boolean errorThresholdMet = false;\n\n  private static final int MILLI_COUNT_IN_SECOND = 1000;\n\n  private String microserviceName;\n\n  public SessionStickinessRule() {\n    triggerRule = new RoundRobinRuleExt();\n  }\n\n  @Override\n  public void setLoadBalancer(LoadBalancer loadBalancer) {\n    this.microserviceName = loadBalancer.getMicroServiceName();\n  }\n\n  private ServiceCombServer chooseNextServer(List<ServiceCombServer> servers, Invocation invocation) {\n    lastServer = triggerRule.choose(servers, invocation);\n    lastAccessedTime = System.currentTimeMillis();\n    return lastServer;\n  }\n\n  private ServiceCombServer chooseInitialServer(List<ServiceCombServer> servers, Invocation invocation) {\n    synchronized (lock) {\n      if (lastServer == null) {\n        chooseNextServer(servers, invocation);\n      }\n    }\n    return lastServer;\n  }\n\n  @VisibleForTesting\n  ServiceCombServer chooseServerWhenTimeout(List<ServiceCombServer> servers, Invocation invocation) {\n    synchronized (lock) {\n      if (isTimeOut()) {\n        chooseNextServer(servers, invocation);\n      }\n    }\n    return lastServer;\n  }\n\n  private ServiceCombServer chooseServerErrorThresholdMet(List<ServiceCombServer> servers, Invocation invocation) {\n    synchronized (lock) {\n      if (errorThresholdMet) {\n        chooseNextServer(servers, invocation);\n        errorThresholdMet = false;\n      }\n    }\n    return lastServer;\n  }\n\n  private boolean isTimeOut() {\n    return Configuration.INSTANCE.getSessionTimeoutInSeconds(microserviceName) > 0\n        && System.currentTimeMillis()\n        - this.lastAccessedTime > ((long) Configuration.INSTANCE.getSessionTimeoutInSeconds(microserviceName)\n        * MILLI_COUNT_IN_SECOND);\n  }\n\n  private boolean isErrorThresholdMet(ServiceCombServer server) {\n    int successiveFailedCount = server.getServerMetrics().getSnapshot().getNumberOfFailedCalls();\n    return Configuration.INSTANCE.getSuccessiveFailedTimes(microserviceName) > 0\n        && successiveFailedCount >= Configuration.INSTANCE.getSuccessiveFailedTimes(microserviceName);\n  }\n\n  @Override\n  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {\n    if (lastServer == null) {\n      return chooseInitialServer(servers, invocation);\n    }\n\n    if (isTimeOut()) {\n      LOG.warn(\"session timeout. choose another server.\");\n      return chooseServerWhenTimeout(servers, invocation);\n    } else {\n      this.lastAccessedTime = System.currentTimeMillis();\n    }\n\n    if (isErrorThresholdMet(lastServer)) {\n      LOG.warn(\"reached max error. choose another server.\");\n      errorThresholdMet = true;\n      return chooseServerErrorThresholdMet(servers, invocation);\n    }\n\n    if (!servers.contains(lastServer)) {\n      return chooseNextServer(servers, invocation);\n    }\n\n    return lastServer;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ThreadLocalRandom;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n * Rule based on response time.\n */\npublic class WeightedResponseTimeRuleExt extends RoundRobinRuleExt {\n  // when all servers are very fast(less than MIN_GAP), use round-robin rule.\n  private static final double MIN_GAP = 10d;\n\n  // calculate stats once per RANDOM_PERCENT requests.\n  private static final int RANDOM_PERCENT = 1000;\n\n  private final Object lock = new Object();\n\n  private final AtomicInteger counter = new AtomicInteger(0);\n\n  // notices: rule will always use as a fixed group of instance, see LoadBalancer for details.\n  private volatile int size = -1;\n\n  private volatile List<Double> cacheStates = new ArrayList<>();\n\n  @Override\n  public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {\n    int count = counter.getAndIncrement();\n    if (count % RANDOM_PERCENT == 0 || size != servers.size()) {\n      synchronized (lock) {\n        this.cacheStates = doCalculateTotalWeights(servers);\n        this.size = servers.size();\n      }\n    }\n\n    List<Double> stats = this.cacheStates;\n    if (stats.size() > 0) {\n      double finalTotal = stats.get(stats.size() - 1);\n      List<Double> weights = new ArrayList<>(servers.size());\n      for (int i = 0; i < stats.size() - 1; i++) {\n        weights.add(finalTotal - stats.get(i));\n      }\n      double ran = ThreadLocalRandom.current().nextDouble() * finalTotal * (servers.size() - 1);\n      for (int i = 0; i < weights.size(); i++) {\n        ran -= weights.get(i);\n        if (ran < 0) {\n          return servers.get(i);\n        }\n      }\n      return servers.get(servers.size() - 1);\n    }\n    return super.choose(servers, invocation);\n  }\n\n  private static List<Double> doCalculateTotalWeights(List<ServiceCombServer> servers) {\n    List<Double> stats = new ArrayList<>(servers.size() + 1);\n    double totalWeights = 0;\n    boolean needRandom = false;\n    for (ServiceCombServer server : servers) {\n      // this method will create new instance, so we cache the states.\n      double avgTime = server.getServerMetrics().getSnapshot().getAverageDuration().toMillis();\n      if (!needRandom && avgTime > MIN_GAP) {\n        needRandom = true;\n      }\n      totalWeights += avgTime;\n      stats.add(avgTime);\n    }\n    stats.add(totalWeights);\n    if (needRandom) {\n      return stats;\n    } else {\n      return new ArrayList<>();\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/exception/LoadbalanceExceptionUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.exception;\n\nimport org.apache.servicecomb.core.exception.CseException;\nimport org.apache.servicecomb.core.exception.ExceptionUtils;\n\npublic class LoadbalanceExceptionUtils extends ExceptionUtils {\n\n  public static final String CSE_HANDLER_LB_WRONG_RULE = \"servicecomb.handler.lb.wrong.rule\";\n\n  static {\n    ERROR_DESC_MGR.register(CSE_HANDLER_LB_WRONG_RULE, \"Configured rule name is wrong.\");\n  }\n\n  public static CseException createLoadbalanceException(String code, Throwable cause, Object... args) {\n    String msg = String.format(ERROR_DESC_MGR.ensureFindValue(code), args);\n    return new CseException(code, msg, cause);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/InstancePropertyDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.loadbalance.Configuration;\nimport org.apache.servicecomb.registry.discovery.AbstractDiscoveryFilter;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\n\n/**\n * Instance property based filter\n */\npublic class InstancePropertyDiscoveryFilter extends AbstractDiscoveryFilter {\n\n  private static final String MATCHED = \"matched\";\n\n  public static final String SERVICECOMB_LOADBALANCE_FILTER_INSTANCE_PROPERTY_ENABLED = \"servicecomb.loadbalance.filter.instanceProperty.enabled\";\n\n  @Override\n  public int getOrder() {\n    return 400;\n  }\n\n  @Override\n  public boolean enabled() {\n\n    if (enabled == null) {\n      enabled = dynamicProperties.getBooleanProperty(SERVICECOMB_LOADBALANCE_FILTER_INSTANCE_PROPERTY_ENABLED,\n          value -> enabled = value,\n          true);\n    }\n    return enabled;\n  }\n\n  @Override\n  public boolean isGroupingFilter() {\n    return false;\n  }\n\n  @Override\n  protected void init(DiscoveryContext context, DiscoveryTreeNode parent) {\n    List<StatefulDiscoveryInstance> matchedInstance = new ArrayList<>();\n    Invocation invocation = context.getInputParameters();\n    List<StatefulDiscoveryInstance> instances = parent.data();\n    Map<String, String> filterOptions =\n        Configuration.INSTANCE.getFlowsplitFilterOptions(invocation.getMicroserviceName());\n    instances.forEach((target) -> {\n      if (allowVisit(target, filterOptions)) {\n        matchedInstance.add(target);\n      }\n    });\n    parent.child(MATCHED, new DiscoveryTreeNode()\n        .subName(parent, MATCHED)\n        .data(matchedInstance));\n  }\n\n  @Override\n  protected String findChildName(DiscoveryContext context, DiscoveryTreeNode parent) {\n    return MATCHED;\n  }\n\n  protected boolean allowVisit(StatefulDiscoveryInstance instance, Map<String, String> filterOptions) {\n    Map<String, String> propertiesMap = instance.getProperties();\n    for (Entry<String, String> entry : filterOptions.entrySet()) {\n      if (!entry.getValue().equals(propertiesMap.get(entry.getKey()))) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Optional;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.registry.discovery.AbstractDiscoveryFilter;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.validation.constraints.NotNull;\n\n/**\n * Instance property with priority filter\n */\npublic class PriorityInstancePropertyDiscoveryFilter extends AbstractDiscoveryFilter {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(PriorityInstancePropertyDiscoveryFilter.class);\n\n  private static final String ALL_INSTANCE = \"allInstance\";\n\n  public static final String SERVICECOMB_LOADBALANCE_FILTER_PRIORITY_INSTANCE_PROPERTY_KEY = \"servicecomb.loadbalance.filter.priorityInstanceProperty.key\";\n\n  private String propertyKey;\n\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  protected void init(DiscoveryContext context, DiscoveryTreeNode parent) {\n\n    propertyKey = dynamicProperties.getStringProperty(SERVICECOMB_LOADBALANCE_FILTER_PRIORITY_INSTANCE_PROPERTY_KEY,\n        value -> propertyKey = value,\n        \"environment\");\n\n    // group all instance by property\n    List<StatefulDiscoveryInstance> instances = parent.data();\n    Map<String, List<StatefulDiscoveryInstance>> groupByProperty = new HashMap<>();\n    for (StatefulDiscoveryInstance microserviceInstance : instances) {\n      String propertyValue = new PriorityInstanceProperty(propertyKey, microserviceInstance).getPropertyValue();\n      groupByProperty.computeIfAbsent(propertyValue, key -> new ArrayList<>())\n          .add(microserviceInstance);\n    }\n    Map<String, DiscoveryTreeNode> children = new HashMap<>();\n    for (Map.Entry<String, List<StatefulDiscoveryInstance>> entry : groupByProperty.entrySet()) {\n      children.put(entry.getKey(),\n          new DiscoveryTreeNode().subName(parent, entry.getKey()).data(entry.getValue()));\n    }\n    children.put(ALL_INSTANCE, new DiscoveryTreeNode().subName(parent, ALL_INSTANCE).data(instances));\n    parent.children(children);\n  }\n\n  @Override\n  protected String findChildName(DiscoveryContext context, DiscoveryTreeNode parent) {\n    Invocation invocation = context.getInputParameters();\n\n    // context property has precedence over instance property\n    String initPropertyValue = invocation.getContext()\n        .computeIfAbsent(\"x-\" + propertyKey,\n            key -> new PriorityInstanceProperty(propertyKey,\n                BootStrapProperties.readServiceProperties(environment).get(propertyKey))\n                .getPropertyValue());\n\n    PriorityInstanceProperty currentProperty = context.getContextParameter(propertyKey);\n    // start with initial value, then search with priority\n    if (Objects.isNull(currentProperty)) {\n      currentProperty = new PriorityInstanceProperty(propertyKey, initPropertyValue);\n      while (!parent.children().containsKey(currentProperty.getPropertyValue())\n          && currentProperty.hasChildren()) {\n        currentProperty = currentProperty.child();\n      }\n    } else {\n      if (currentProperty.hasChildren()) {\n        currentProperty = currentProperty.child();\n      }\n    }\n    LOGGER.debug(\"Discovery instance filter by {}\", currentProperty);\n    context.putContextParameter(propertyKey, currentProperty);\n\n    // stop push filter stack if property is empty\n    if (currentProperty.isEmpty()) {\n      return currentProperty.getPropertyValue();\n    }\n    context.pushRerunFilter();\n    return currentProperty.getPropertyValue();\n  }\n\n  @Override\n  public boolean enabled() {\n\n    if (enabled == null) {\n      enabled = dynamicProperties.getBooleanProperty(\"servicecomb.loadbalance.filter.priorityInstanceProperty.enabled\",\n          value -> enabled = value,\n          false);\n    }\n    return enabled;\n  }\n\n  @Override\n  public int getOrder() {\n    return new InstancePropertyDiscoveryFilter().getOrder() + 1;\n  }\n\n  static class PriorityInstanceProperty {\n    private static final int MAX_LENGTH = 10000;\n\n    private static final String SEPARATOR = \".\";\n\n    private final String propertyKey;\n\n    private final String propertyVal;\n\n    /**\n     * Constructor\n     *\n     * @param key   property key\n     * @param value property value\n     */\n    public PriorityInstanceProperty(@NotNull String key, String value) {\n      propertyKey = key;\n      if (Objects.isNull(value)) {\n        value = StringUtils.EMPTY;\n      }\n      if (value.length() > MAX_LENGTH) {\n        throw new IllegalArgumentException(\"property value exceed max length\");\n      }\n      propertyVal = value;\n    }\n\n    /**\n     * Constructor\n     *\n     * @param key                  property key\n     * @param microserviceInstance instance\n     */\n    public PriorityInstanceProperty(@NotNull String key, @NotNull StatefulDiscoveryInstance microserviceInstance) {\n      this(key, Optional.ofNullable(microserviceInstance.getProperties().get(key))\n          .orElse(StringUtils.EMPTY));\n    }\n\n    /**\n     * whether property is empty\n     *\n     * @return result\n     */\n    public boolean isEmpty() {\n      return StringUtils.isEmpty(propertyVal);\n    }\n\n    /**\n     * does property have lower priority children\n     *\n     * @return result\n     */\n    public boolean hasChildren() {\n      return StringUtils.isNotEmpty(propertyVal);\n    }\n\n    /**\n     * get lower priority child\n     *\n     * @return result\n     */\n    public PriorityInstanceProperty child() {\n      if (propertyVal.contains(SEPARATOR)) {\n        return new PriorityInstanceProperty(propertyKey, StringUtils.substringBeforeLast(propertyVal, SEPARATOR));\n      }\n      return new PriorityInstanceProperty(propertyKey, StringUtils.EMPTY);\n    }\n\n    /**\n     * get property value\n     *\n     * @return propertyVal\n     */\n    public String getPropertyValue() {\n      return propertyVal;\n    }\n\n    @Override\n    public String toString() {\n      return \"PriorityInstanceProperty{key=\" + propertyKey + \", value=\" + propertyVal + '}';\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ServerDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.registry.discovery.EndpointDiscoveryFilter;\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class ServerDiscoveryFilter extends EndpointDiscoveryFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServerDiscoveryFilter.class);\n\n  public ServerDiscoveryFilter() {\n  }\n\n  @Override\n  protected Object createEndpoint(DiscoveryContext context, String transportName, String endpoint,\n      StatefulDiscoveryInstance instance) {\n    Transport transport = scbEngine.getTransportManager().findTransport(transportName);\n    if (transport == null) {\n      LOGGER.info(\"not deployed transport {}, ignore {}.\", transportName, endpoint);\n      return null;\n    }\n    Invocation invocation = context.getInputParameters();\n    return new ServiceCombServer(invocation.getMicroserviceName(),\n        new Endpoint(transport, endpoint, instance));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.registry.discovery.AbstractGroupDiscoveryFilter;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class ZoneAwareDiscoveryFilter extends AbstractGroupDiscoveryFilter {\n  public static final String PARAMETER = \"zone_aware_level\";\n\n  public static final String GROUP_PREFIX = \"zone_aware_group_\";\n\n  public static final String GROUP_SIZE = \"zone_aware_group_size\";\n\n  public static final String CONFIG_ENABLED = \"servicecomb.loadbalance.filter.zoneaware.enabled\";\n\n  public static final String CONFIG_RATIO = \"servicecomb.loadbalance.filter.zoneaware.ratio\";\n\n  public static final String CONFIG_RATIO_CEILING = \"servicecomb.loadbalance.filter.zoneaware.ratioCeiling\";\n\n  private DataCenterProperties dataCenterProperties;\n\n  private Integer ratio;\n\n  private Integer ratioCeiling;\n\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setDataCenterProperties(DataCenterProperties dataCenterProperties) {\n    this.dataCenterProperties = dataCenterProperties;\n  }\n\n  @Override\n  public int getOrder() {\n    return -9000;\n  }\n\n  @Override\n  public boolean enabled() {\n\n    if (enabled == null) {\n      enabled = dynamicProperties.getBooleanProperty(CONFIG_ENABLED,\n          value -> enabled = value,\n          true);\n    }\n    return enabled;\n  }\n\n  private int getRatio() {\n\n    if (ratio == null) {\n      ratio = dynamicProperties.getIntProperty(CONFIG_RATIO,\n          value -> ratio = value,\n          30);\n    }\n    return ratio;\n  }\n\n  private int getRatioCeiling(int defaultValue) {\n\n    if (ratioCeiling == null) {\n      ratioCeiling = dynamicProperties.getIntProperty(CONFIG_RATIO_CEILING,\n          value -> ratioCeiling = value,\n          defaultValue);\n    }\n    return ratioCeiling;\n  }\n\n  @Override\n  protected String contextParameter() {\n    return PARAMETER;\n  }\n\n  @Override\n  protected String groupsSizeParameter() {\n    return GROUP_SIZE;\n  }\n\n  @Override\n  protected String groupPrefix() {\n    return GROUP_PREFIX;\n  }\n\n  @Override\n  public void init(DiscoveryContext context, DiscoveryTreeNode parent) {\n    List<StatefulDiscoveryInstance> instances = parent.data();\n    List<StatefulDiscoveryInstance> instancesRegionAndAZMatch = new ArrayList<>();\n    List<StatefulDiscoveryInstance> instancesAZMatch = new ArrayList<>();\n    List<StatefulDiscoveryInstance> instancesNoMatch = new ArrayList<>();\n\n    int groups = 1;\n\n    for (StatefulDiscoveryInstance server : instances) {\n      if (regionAndAZMatch(server)) {\n        instancesRegionAndAZMatch.add(server);\n      } else if (regionMatch(server)) {\n        instancesAZMatch.add(server);\n      } else {\n        instancesNoMatch.add(server);\n      }\n    }\n\n    int ratio = getRatio();\n    int ratioCeiling = getRatioCeiling(100 - ratio);\n\n    if (hasEnoughMembers(instances.size(), instancesRegionAndAZMatch.size(), ratio, ratioCeiling)) {\n      parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n          .subName(parent, GROUP_PREFIX + groups).data(instancesRegionAndAZMatch));\n      groups++;\n    } else {\n      instancesAZMatch.addAll(instancesRegionAndAZMatch);\n    }\n\n    if (hasEnoughMembers(instances.size(), instancesAZMatch.size(), ratio, ratioCeiling)) {\n      parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n          .subName(parent, GROUP_PREFIX + groups).data(instancesAZMatch));\n      groups++;\n    } else {\n      instancesNoMatch.addAll(instancesAZMatch);\n    }\n\n    parent.child(GROUP_PREFIX + groups, new DiscoveryTreeNode()\n        .subName(parent, GROUP_PREFIX + groups).data(instancesNoMatch));\n\n    parent.attribute(GROUP_SIZE, groups);\n  }\n\n  private boolean hasEnoughMembers(int totalSize, int groupSize, int ratio, int ratioCeiling) {\n    if (totalSize == 0 || groupSize == 0) {\n      return false;\n    }\n    int actual = Math.floorDiv(groupSize * 100, totalSize);\n    return actual >= ratio && actual <= ratioCeiling;\n  }\n\n  private boolean regionAndAZMatch(StatefulDiscoveryInstance target) {\n    if (dataCenterProperties.getRegion() != null\n        && dataCenterProperties.getAvailableZone() != null && target.getDataCenterInfo() != null) {\n      return dataCenterProperties.getRegion()\n          .equals(target.getDataCenterInfo().getRegion()) &&\n          dataCenterProperties.getAvailableZone()\n              .equals(target.getDataCenterInfo().getAvailableZone());\n    }\n    return false;\n  }\n\n  private boolean regionMatch(StatefulDiscoveryInstance target) {\n    if (dataCenterProperties.getRegion() != null && target.getDataCenterInfo() != null) {\n      return dataCenterProperties.getRegion()\n          .equals(target.getDataCenterInfo().getRegion());\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.loadbalance.LoadBalanceConfiguration\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\n\n/**\n * @author l00168639\n *\n */\npublic class MyServerListFilterExt implements ServerListFilterExt {\n  @Override\n  public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList, Invocation invocation) {\n    if (invocation.getAppId().equals(\"test\")) {\n      return new ArrayList<>();\n    }\n    return serverList;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\n/**\n *\n */\npublic class TestConfiguration {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @After\n  public void after() {\n  }\n\n  @Test\n  public void testConstants() {\n\n    Assertions.assertEquals(\"servicecomb.loadbalance.\", Configuration.ROOT);\n    Assertions.assertEquals(\"ribbon.\", Configuration.ROOT_20);\n    Assertions.assertEquals(\"SessionStickinessRule.successiveFailedTimes\", Configuration.SUCCESSIVE_FAILED_TIMES);\n    Assertions.assertEquals(\"maxSingleTestWindow\", Configuration.FILTER_MAX_SINGLE_TEST_WINDOW);\n\n    Assertions.assertNotNull(Configuration.INSTANCE);\n  }\n\n  @Test\n  public void testFullConfigurationWithArgsString() {\n    Assertions.assertNotNull(Configuration.INSTANCE.getSuccessiveFailedTimes(\"test\"));\n    Assertions.assertNotNull(Configuration.INSTANCE.getSessionTimeoutInSeconds(\"test\"));\n  }\n\n  @Test\n  public void testGetSuccessiveFailedTimes() {\n    Assertions.assertNotNull(Configuration.INSTANCE.getSuccessiveFailedTimes(\"test\"));\n  }\n\n  @Test\n  public void testGetSessionTimeoutInSeconds() {\n    Assertions.assertNotNull(Configuration.INSTANCE.getSessionTimeoutInSeconds(\"test\"));\n  }\n\n  @Test\n  public void testGetMaxSingleTestWindow() {\n    Assertions.assertEquals(60000, Configuration.INSTANCE.getMaxSingleTestWindow());\n    Mockito.when(environment.getProperty(\"servicecomb.loadbalance.isolation.maxSingleTestWindow\")).thenReturn(\"5000\");\n    Assertions.assertEquals(5000, Configuration.INSTANCE.getMaxSingleTestWindow());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestExtensionsManager {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @AfterEach\n  public void tearDown() {\n  }\n\n  @Test\n  public void testRuleName() {\n    List<ExtensionsFactory> extensionsFactories = new ArrayList<>();\n    extensionsFactories.add(new RuleNameExtensionsFactory());\n    ExtensionsManager extensionsManager = new ExtensionsManager(extensionsFactories);\n\n    Assertions.assertEquals(RoundRobinRuleExt.class.getName(),\n        extensionsManager.createLoadBalancerRule(\"RoundRobin\").getClass().getName());\n    Assertions.assertEquals(RandomRuleExt.class.getName(),\n        extensionsManager.createLoadBalancerRule(\"Random\").getClass().getName());\n    Assertions.assertEquals(WeightedResponseTimeRuleExt.class.getName(),\n        extensionsManager.createLoadBalancerRule(\"WeightedResponse\").getClass().getName());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\nimport mockit.Expectations;\nimport mockit.Injectable;\n\npublic class TestLoadBalanceCreator {\n  @Test\n  public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation invocation,\n      @Injectable Transport transport) {\n    // Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.\n    RoundRobinRuleExt rule = new RoundRobinRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance1 = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"instance1\");\n    Endpoint host1 = new Endpoint(transport, \"host1\", instance1);\n    ServiceCombServer server = new ServiceCombServer(null, host1);\n\n    DiscoveryInstance discoveryInstance2 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance2 = new StatefulDiscoveryInstance(discoveryInstance2);\n    Mockito.when(discoveryInstance2.getInstanceId()).thenReturn(\"instance2\");\n    Endpoint host2 = new Endpoint(transport, \"host2\", instance2);\n    ServiceCombServer server2 = new ServiceCombServer(null, host2);\n\n    servers.add(server);\n    servers.add(server2);\n    LoadBalancer lb = new LoadBalancer(rule, \"test\");\n\n    List<ServerListFilterExt> filters = new ArrayList<>();\n\n    filters.add((serverList, invocation1) -> {\n      List<ServiceCombServer> filteredServers = new ArrayList<>();\n      for (ServiceCombServer server1 : servers) {\n        if (server1.getHost().equals(\"host1\")) {\n          continue;\n        }\n        filteredServers.add(server1);\n      }\n      return filteredServers;\n    });\n    lb.setFilters(filters);\n\n    new Expectations() {\n      {\n        invocation.getLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST);\n        result = servers;\n      }\n    };\n    ServiceCombServer s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n    s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n    s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n  }\n\n  @Test\n  public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invocation,\n      @Injectable Transport transport) {\n    // Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.\n    RandomRuleExt rule = new RandomRuleExt();\n    LoadBalancer lb = new LoadBalancer(rule, \"service\");\n\n    List<ServiceCombServer> servers = new ArrayList<>();\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance1 = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"instance1\");\n    Endpoint host1 = new Endpoint(transport, \"host1\", instance1);\n    ServiceCombServer server = new ServiceCombServer(null, host1);\n\n    DiscoveryInstance discoveryInstance2 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance2 = new StatefulDiscoveryInstance(discoveryInstance2);\n    Mockito.when(discoveryInstance2.getInstanceId()).thenReturn(\"instance2\");\n    Endpoint host2 = new Endpoint(transport, \"host2\", instance2);\n    ServiceCombServer server2 = new ServiceCombServer(null, host2);\n\n    servers.add(server);\n    servers.add(server2);\n\n    List<ServerListFilterExt> filters = new ArrayList<>();\n    filters.add((serverList, invocation1) -> {\n      List<ServiceCombServer> filteredServers = new ArrayList<>();\n      for (ServiceCombServer server1 : servers) {\n        if (server1.getHost().equals(\"host1\")) {\n          continue;\n        }\n        filteredServers.add(server1);\n      }\n      return filteredServers;\n    });\n    lb.setFilters(filters);\n    new Expectations() {\n      {\n        invocation.getLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST);\n        result = servers;\n      }\n    };\n    ServiceCombServer s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n    s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n    s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n  }\n\n  @Test\n  public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Injectable Endpoint endpoint1,\n      @Injectable Endpoint endpoint2, @Injectable Invocation invocation) {\n    // Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.\n    WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();\n    LoadBalancer lb = new LoadBalancer(rule, \"service\");\n\n    List<ServiceCombServer> servers = new ArrayList<>();\n\n    DiscoveryInstance discoveryInstance1 = Mockito.mock(DiscoveryInstance.class);\n//    StatefulDiscoveryInstance instance1 = new StatefulDiscoveryInstance(discoveryInstance1);\n    Mockito.when(discoveryInstance1.getInstanceId()).thenReturn(\"ii01\");\n\n    DiscoveryInstance discoveryInstance2 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance2 = new StatefulDiscoveryInstance(discoveryInstance2);\n    Mockito.when(discoveryInstance2.getInstanceId()).thenReturn(\"ii02\");\n\n    new Expectations() {\n      {\n        endpoint1.getEndpoint();\n        result = \"host1\";\n//        endpoint1.getMicroserviceInstance();\n//        result = instance1;\n        endpoint2.getEndpoint();\n        result = \"host2\";\n        endpoint2.getMicroserviceInstance();\n        result = instance2;\n      }\n    };\n\n    ServiceCombServer server = new ServiceCombServer(null, endpoint1);\n    ServiceCombServer server2 = new ServiceCombServer(null, endpoint2);\n\n    servers.add(server);\n    servers.add(server2);\n    List<ServerListFilterExt> filters = new ArrayList<>();\n    filters.add((serverList, invocation1) -> {\n      List<ServiceCombServer> filteredServers = new ArrayList<>();\n      for (ServiceCombServer server1 : servers) {\n        if (server1.getHost().equals(\"host1\")) {\n          continue;\n        }\n        filteredServers.add(server1);\n      }\n      return filteredServers;\n    });\n    lb.setFilters(filters);\n    new Expectations() {\n      {\n        invocation.getLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST);\n        result = servers;\n      }\n    };\n    ServiceCombServer s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n    s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n    s = lb.chooseServer(invocation);\n    Assertions.assertEquals(server2, s);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\nimport org.apache.servicecomb.registry.discovery.TelnetInstancePing;\nimport org.apache.servicecomb.swagger.invocation.AsyncResponse;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport mockit.Deencapsulation;\nimport mockit.Injectable;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\n/**\n *\n *\n */\npublic class TestLoadBalanceFilter {\n  static SCBEngine scbEngine;\n\n  static TransportManager transportManager;\n\n  String microserviceName = \"ms\";\n\n  LoadBalanceFilter handler;\n\n  Map<String, LoadBalancer> loadBalancerMap;\n\n  @Injectable\n  Invocation invocation;\n\n  @Mocked\n  Transport restTransport;\n\n  Response sendResponse;\n\n  @Before\n  public void setUp() {\n    Environment environment = Mockito.mock(Environment.class);\n    scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION))\n        .thenReturn(BootStrapProperties.DEFAULT_APPLICATION);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_NAME);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_ENVIRONMENT))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_ENVIRONMENT);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(\"servicecomb.loadbalance.userDefinedEndpoint.enabled\",\n        boolean.class, false)).thenReturn(false);\n    scbEngine.run();\n    transportManager = scbEngine.getTransportManager();\n\n    new MockUp<Invocation>(invocation) {\n      @Mock\n      String getMicroserviceName() {\n        return microserviceName;\n      }\n\n      @Mock\n      void next(AsyncResponse asyncResp) throws Exception {\n        asyncResp.handle(sendResponse);\n      }\n\n      @Mock\n      public <T> T getLocalContext(String key) {\n        return (T) null;\n      }\n    };\n\n    new MockUp<TransportManager>(transportManager) {\n      @Mock\n      Transport findTransport(String transportName) {\n        return restTransport;\n      }\n    };\n\n    List<ExtensionsFactory> extensionsFactories = new ArrayList<>();\n    extensionsFactories.add(new RuleNameExtensionsFactory());\n    ExtensionsManager extensionsManager = new ExtensionsManager(extensionsFactories);\n\n    DiscoveryTree discoveryTree = new DiscoveryTree(\n        new DiscoveryManager(Collections.emptyList(), List.of(new TelnetInstancePing())));\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()),\n        discoveryTree, scbEngine);\n    loadBalancerMap = Deencapsulation.getField(handler, \"loadBalancerMap\");\n  }\n\n  @After\n  public void teardown() {\n    scbEngine.destroy();\n  }\n\n  @Test\n  public void testIsFailedResponse() {\n    Assertions.assertFalse(handler.isFailedResponse(Response.create(400, \"\", \"\")));\n    Assertions.assertFalse(handler.isFailedResponse(Response.create(500, \"\", \"\")));\n    Assertions.assertTrue(handler.isFailedResponse(Response.create(490, \"\", \"\")));\n    Assertions.assertTrue(handler.isFailedResponse(Response.consumerFailResp(new NullPointerException())));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceFilter2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport static org.mockito.Mockito.when;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.NonSwaggerInvocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.loadbalance.filter.ServerDiscoveryFilter;\nimport org.apache.servicecomb.loadbalance.filter.ZoneAwareDiscoveryFilter;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTree;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\n\npublic class TestLoadBalanceFilter2 {\n  DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class);\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n\n    Mockito.when(environment.getProperty(\"servicecomb.loadbalance.userDefinedEndpoint.enabled\",\n        boolean.class, false)).thenReturn(false);\n\n    Mockito.when(dynamicProperties.getBooleanProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.enabled\"),\n            Mockito.any(),\n            Mockito.eq(true)))\n        .thenReturn(true);\n    Mockito.when(dynamicProperties.getIntProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.ratio\"),\n            Mockito.any(),\n            Mockito.eq(30)))\n        .thenReturn(0);\n    Mockito.when(dynamicProperties.getIntProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.ratioCeiling\"),\n            Mockito.any(),\n            Mockito.eq(100)))\n        .thenReturn(100);\n\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testZoneAwareFilterWorks() {\n    ReferenceConfig referenceConfig = Mockito.mock(ReferenceConfig.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    InvocationRuntimeType invocationRuntimeType = Mockito.mock(InvocationRuntimeType.class);\n    SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n    when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n    Operation operation = Mockito.mock(Operation.class);\n    when(operationMeta.getSwaggerOperation()).thenReturn(operation);\n    when(operation.getExtensions()).thenReturn(null);\n    OpenAPI openAPI = Mockito.mock(OpenAPI.class);\n    when(schemaMeta.getSwagger()).thenReturn(openAPI);\n    when(openAPI.getExtensions()).thenReturn(null);\n    MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n    when(schemaMeta.getMicroserviceName()).thenReturn(\"testMicroserviceName\");\n    when(microserviceMeta.getAppId()).thenReturn(\"testApp\");\n    when(referenceConfig.getTransport()).thenReturn(\"rest\");\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, new HashMap<>());\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    Transport transport = Mockito.mock(Transport.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getEnvironment()).thenReturn(environment);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test-Region\");\n    myself.setAvailableZone(\"test-zone\");\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance allmatchInstance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test-Region\");\n    info.setAvailableZone(\"test-zone\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:9090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"allmatchInstance\");\n\n    DiscoveryInstance regionMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance regionMatchInstance = new StatefulDiscoveryInstance(regionMatchDiscoveryInstance);\n    DataCenterInfo regionMatchInfo = new DataCenterInfo();\n    regionMatchInfo.setName(\"test\");\n    regionMatchInfo.setRegion(\"test-Region\");\n    regionMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> regionMatchEndpoint = new ArrayList<>();\n    regionMatchEndpoint.add(\"rest://localhost:9091\");\n    Mockito.when(regionMatchDiscoveryInstance.getEndpoints()).thenReturn(regionMatchEndpoint);\n    Mockito.when(regionMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(regionMatchInfo);\n    Mockito.when(regionMatchDiscoveryInstance.getInstanceId()).thenReturn(\"regionMatchInstance\");\n\n    DiscoveryInstance noneMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance noneMatchInstance = new StatefulDiscoveryInstance(noneMatchDiscoveryInstance);\n    DataCenterInfo noneMatchInfo = new DataCenterInfo();\n    noneMatchInfo.setName(\"test\");\n    noneMatchInfo.setRegion(\"test-Region2\");\n    noneMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> noMatchEndpoint = new ArrayList<>();\n    noMatchEndpoint.add(\"rest://localhost:9092\");\n    Mockito.when(noneMatchDiscoveryInstance.getEndpoints()).thenReturn(noMatchEndpoint);\n    Mockito.when(noneMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(noneMatchInfo);\n    Mockito.when(noneMatchDiscoveryInstance.getInstanceId()).thenReturn(\"noneMatchInstance\");\n\n    List<StatefulDiscoveryInstance> data = new ArrayList<>();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n    when(transportManager.findTransport(\"rest\")).thenReturn(transport);\n\n    LoadBalanceFilter handler;\n    LoadBalancer loadBalancer;\n    ServiceCombServer server;\n\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"testApp\", \"testMicroserviceName\"))\n        .thenReturn(parent);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter();\n    zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties);\n    zoneAwareDiscoveryFilter.setDataCenterProperties(myself);\n    ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter();\n    serverDiscoveryFilter.setScbEngine(scbEngine);\n    discoveryTree.setDiscoveryFilters(Arrays.asList(zoneAwareDiscoveryFilter,\n        serverDiscoveryFilter));\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()),\n        discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertNull(server);\n\n    data.add(noneMatchInstance);\n    parent.cacheVersion(1);\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()),\n        discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9092\", server.getEndpoint().getEndpoint());\n\n    data.add(regionMatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9091\", server.getEndpoint().getEndpoint());\n\n    data.add(allmatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9090\", server.getEndpoint().getEndpoint());\n  }\n\n\n  @Test\n  public void testIsolationEventWithEndpoint() {\n    ReferenceConfig referenceConfig = Mockito.mock(ReferenceConfig.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    InvocationRuntimeType invocationRuntimeType = Mockito.mock(InvocationRuntimeType.class);\n    SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n    when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n    Operation operation = Mockito.mock(Operation.class);\n    when(operationMeta.getSwaggerOperation()).thenReturn(operation);\n    when(operation.getExtensions()).thenReturn(null);\n    OpenAPI openAPI = Mockito.mock(OpenAPI.class);\n    when(schemaMeta.getSwagger()).thenReturn(openAPI);\n    when(openAPI.getExtensions()).thenReturn(null);\n    MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n    when(schemaMeta.getMicroserviceName()).thenReturn(\"testMicroserviceName\");\n    when(microserviceMeta.getAppId()).thenReturn(\"testApp\");\n    when(referenceConfig.getTransport()).thenReturn(\"rest\");\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, new HashMap<>());\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    Transport transport = Mockito.mock(Transport.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getEnvironment()).thenReturn(environment);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test\");\n    myself.setAvailableZone(\"test\");\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test\");\n    info.setAvailableZone(\"test\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:9090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"instance\");\n\n    List<StatefulDiscoveryInstance> data = new ArrayList<>();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n\n    when(transportManager.findTransport(\"rest\")).thenReturn(transport);\n\n    LoadBalanceFilter handler;\n    LoadBalancer loadBalancer;\n    ServiceCombServer server;\n\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"testApp\", \"testMicroserviceName\"))\n        .thenReturn(parent);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter();\n    zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties);\n    zoneAwareDiscoveryFilter.setDataCenterProperties(myself);\n    ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter();\n    serverDiscoveryFilter.setScbEngine(scbEngine);\n    discoveryTree.setDiscoveryFilters(Arrays.asList(zoneAwareDiscoveryFilter,\n        serverDiscoveryFilter));\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()),\n        discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertNull(server);\n\n    data.add(instance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9090\", server.getEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testZoneAwareFilterWorksEmptyInstanceProtectionEnabled() {\n    ReferenceConfig referenceConfig = Mockito.mock(ReferenceConfig.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    InvocationRuntimeType invocationRuntimeType = Mockito.mock(InvocationRuntimeType.class);\n    SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);\n    when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);\n    MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);\n    when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);\n    when(schemaMeta.getMicroserviceName()).thenReturn(\"testMicroserviceName\");\n    Operation operation = Mockito.mock(Operation.class);\n    when(operationMeta.getSwaggerOperation()).thenReturn(operation);\n    when(operation.getExtensions()).thenReturn(null);\n    OpenAPI openAPI = Mockito.mock(OpenAPI.class);\n    when(schemaMeta.getSwagger()).thenReturn(openAPI);\n    when(openAPI.getExtensions()).thenReturn(null);\n    when(microserviceMeta.getAppId()).thenReturn(\"testApp\");\n    when(referenceConfig.getTransport()).thenReturn(\"rest\");\n    Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, new HashMap<>());\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    Transport transport = Mockito.mock(Transport.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    Mockito.when(scbEngine.getEnvironment()).thenReturn(environment);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test-Region\");\n    myself.setAvailableZone(\"test-zone\");\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance allmatchInstance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test-Region\");\n    info.setAvailableZone(\"test-zone\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:9090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"allmatchInstance\");\n\n    DiscoveryInstance regionMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance regionMatchInstance = new StatefulDiscoveryInstance(regionMatchDiscoveryInstance);\n    DataCenterInfo regionMatchInfo = new DataCenterInfo();\n    regionMatchInfo.setName(\"test\");\n    regionMatchInfo.setRegion(\"test-Region\");\n    regionMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> regionMatchEndpoint = new ArrayList<>();\n    regionMatchEndpoint.add(\"rest://localhost:9091\");\n    Mockito.when(regionMatchDiscoveryInstance.getEndpoints()).thenReturn(regionMatchEndpoint);\n    Mockito.when(regionMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(regionMatchInfo);\n    Mockito.when(regionMatchDiscoveryInstance.getInstanceId()).thenReturn(\"regionMatchInstance\");\n\n    DiscoveryInstance noneMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance noneMatchInstance = new StatefulDiscoveryInstance(noneMatchDiscoveryInstance);\n    DataCenterInfo noneMatchInfo = new DataCenterInfo();\n    noneMatchInfo.setName(\"test\");\n    noneMatchInfo.setRegion(\"test-Region2\");\n    noneMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> noMatchEndpoint = new ArrayList<>();\n    noMatchEndpoint.add(\"rest://localhost:9092\");\n    Mockito.when(noneMatchDiscoveryInstance.getEndpoints()).thenReturn(noMatchEndpoint);\n    Mockito.when(noneMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(noneMatchInfo);\n    Mockito.when(noneMatchDiscoveryInstance.getInstanceId()).thenReturn(\"noneMatchInstance\");\n\n    List<StatefulDiscoveryInstance> data = new ArrayList<>();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n\n    when(transportManager.findTransport(\"rest\")).thenReturn(transport);\n\n    LoadBalanceFilter handler;\n    LoadBalancer loadBalancer;\n    ServiceCombServer server;\n\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"testApp\", \"testMicroserviceName\"))\n        .thenReturn(parent);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter();\n    zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties);\n    zoneAwareDiscoveryFilter.setDataCenterProperties(myself);\n    ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter();\n    serverDiscoveryFilter.setScbEngine(scbEngine);\n    discoveryTree.setDiscoveryFilters(Arrays.asList(zoneAwareDiscoveryFilter,\n        serverDiscoveryFilter));\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()), discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertNull(server);\n\n    data.add(noneMatchInstance);\n    parent.cacheVersion(1);\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()), discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9092\", server.getEndpoint().getEndpoint());\n\n    data.add(regionMatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9091\", server.getEndpoint().getEndpoint());\n\n    data.add(allmatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:9090\", server.getEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testZoneAwareFilterUsingMockedInvocationWorks() {\n    Invocation invocation = new NonSwaggerInvocation(\"testApp\", \"testMicroserviceName\");\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    Transport transport = Mockito.mock(Transport.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    Mockito.when(scbEngine.getEnvironment()).thenReturn(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.loadbalance.filter.operation.enabled\",\n        boolean.class, true)).thenReturn(false);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test-Region\");\n    myself.setAvailableZone(\"test-zone\");\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance allmatchInstance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test-Region\");\n    info.setAvailableZone(\"test-zone\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:7090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"allmatchInstance\");\n\n    DiscoveryInstance regionMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance regionMatchInstance = new StatefulDiscoveryInstance(regionMatchDiscoveryInstance);\n    DataCenterInfo regionMatchInfo = new DataCenterInfo();\n    regionMatchInfo.setName(\"test\");\n    regionMatchInfo.setRegion(\"test-Region\");\n    regionMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> regionMatchEndpoint = new ArrayList<>();\n    regionMatchEndpoint.add(\"rest://localhost:7091\");\n    Mockito.when(regionMatchDiscoveryInstance.getEndpoints()).thenReturn(regionMatchEndpoint);\n    Mockito.when(regionMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(regionMatchInfo);\n    Mockito.when(regionMatchDiscoveryInstance.getInstanceId()).thenReturn(\"regionMatchInstance\");\n\n    DiscoveryInstance noneMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance noneMatchInstance = new StatefulDiscoveryInstance(noneMatchDiscoveryInstance);\n    DataCenterInfo noneMatchInfo = new DataCenterInfo();\n    noneMatchInfo.setName(\"test\");\n    noneMatchInfo.setRegion(\"test-Region2\");\n    noneMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> noMatchEndpoint = new ArrayList<>();\n    noMatchEndpoint.add(\"rest://localhost:7092\");\n    Mockito.when(noneMatchDiscoveryInstance.getEndpoints()).thenReturn(noMatchEndpoint);\n    Mockito.when(noneMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(noneMatchInfo);\n    Mockito.when(noneMatchDiscoveryInstance.getInstanceId()).thenReturn(\"noneMatchInstance\");\n\n    List<StatefulDiscoveryInstance> data = new ArrayList<>();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n\n    when(transportManager.findTransport(\"rest\")).thenReturn(transport);\n\n    LoadBalanceFilter handler;\n    LoadBalancer loadBalancer;\n    ServiceCombServer server;\n\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"testApp\", \"testMicroserviceName\"))\n        .thenReturn(parent);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter();\n    zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties);\n    zoneAwareDiscoveryFilter.setDataCenterProperties(myself);\n    ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter();\n    serverDiscoveryFilter.setScbEngine(scbEngine);\n    discoveryTree.setDiscoveryFilters(Arrays.asList(zoneAwareDiscoveryFilter,\n        serverDiscoveryFilter));\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()), discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertNull(server);\n\n    data.add(noneMatchInstance);\n    parent.cacheVersion(1);\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()), discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:7092\", server.getEndpoint().getEndpoint());\n\n    data.add(regionMatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:7091\", server.getEndpoint().getEndpoint());\n\n    data.add(allmatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:7090\", server.getEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testStatusFilterUsingMockedInvocationWorks() {\n    Invocation invocation = new NonSwaggerInvocation(\"testApp\", \"testMicroserviceName\");\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    Transport transport = Mockito.mock(Transport.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    Mockito.when(scbEngine.getEnvironment()).thenReturn(environment);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test-Region\");\n    myself.setAvailableZone(\"test-zone\");\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance allmatchInstance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test-Region\");\n    info.setAvailableZone(\"test-zone\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:7090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"allmatchInstance\");\n    Mockito.when(discoveryInstance.getStatus()).thenReturn(MicroserviceInstanceStatus.TESTING);\n\n    DiscoveryInstance regionMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance regionMatchInstance = new StatefulDiscoveryInstance(regionMatchDiscoveryInstance);\n    DataCenterInfo regionMatchInfo = new DataCenterInfo();\n    regionMatchInfo.setName(\"test\");\n    regionMatchInfo.setRegion(\"test-Region\");\n    regionMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> regionMatchEndpoint = new ArrayList<>();\n    regionMatchEndpoint.add(\"rest://localhost:7091\");\n    Mockito.when(regionMatchDiscoveryInstance.getEndpoints()).thenReturn(regionMatchEndpoint);\n    Mockito.when(regionMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(regionMatchInfo);\n    Mockito.when(regionMatchDiscoveryInstance.getInstanceId()).thenReturn(\"regionMatchInstance\");\n\n    DiscoveryInstance noneMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance noneMatchInstance = new StatefulDiscoveryInstance(noneMatchDiscoveryInstance);\n    DataCenterInfo noneMatchInfo = new DataCenterInfo();\n    noneMatchInfo.setName(\"test\");\n    noneMatchInfo.setRegion(\"test-Region2\");\n    noneMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> noMatchEndpoint = new ArrayList<>();\n    noMatchEndpoint.add(\"rest://localhost:7092\");\n    Mockito.when(noneMatchDiscoveryInstance.getEndpoints()).thenReturn(noMatchEndpoint);\n    Mockito.when(noneMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(noneMatchInfo);\n    Mockito.when(noneMatchDiscoveryInstance.getInstanceId()).thenReturn(\"noneMatchInstance\");\n\n    List<StatefulDiscoveryInstance> data = new ArrayList<>();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n\n    when(transportManager.findTransport(\"rest\")).thenReturn(transport);\n\n    LoadBalanceFilter handler;\n    LoadBalancer loadBalancer;\n    ServiceCombServer server;\n\n    DiscoveryManager discoveryManager = Mockito.mock(DiscoveryManager.class);\n    Mockito.when(discoveryManager.getOrCreateVersionedCache(\"testApp\", \"testMicroserviceName\"))\n        .thenReturn(parent);\n    DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager);\n    ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter();\n    zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties);\n    zoneAwareDiscoveryFilter.setDataCenterProperties(myself);\n    ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter();\n    serverDiscoveryFilter.setScbEngine(scbEngine);\n    discoveryTree.setDiscoveryFilters(Arrays.asList(zoneAwareDiscoveryFilter,\n        serverDiscoveryFilter));\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()), discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertNull(server);\n\n    data.add(noneMatchInstance);\n    parent.cacheVersion(1);\n    handler = new LoadBalanceFilter(new ExtensionsManager(new ArrayList<>()), discoveryTree, scbEngine);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:7092\", server.getEndpoint().getEndpoint());\n\n    data.add(regionMatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:7091\", server.getEndpoint().getEndpoint());\n\n    data.add(allmatchInstance);\n    parent.cacheVersion(parent.cacheVersion() + 1);\n    loadBalancer = handler.getOrCreateLoadBalancer(invocation);\n    server = loadBalancer.chooseServer(invocation);\n    Assertions.assertEquals(\"rest://localhost:7090\", server.getEndpoint().getEndpoint());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestLoadBalancer {\n  private final RuleExt rule = Mockito.mock(RuleExt.class);\n\n  @Test\n  public void testLoadBalancerFullOperationWithoutException() {\n    List<ServiceCombServer> newServers = new ArrayList<>();\n    ServiceCombServer server = Mockito.mock(ServiceCombServer.class);\n    Invocation invocation = Mockito.mock(Invocation.class);\n    StatefulDiscoveryInstance microserviceInstance = Mockito.mock(StatefulDiscoveryInstance.class);\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    newServers.add(server);\n    Mockito.when(invocation.getLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST)).thenReturn(newServers);\n    Mockito.when(server.getInstance()).thenReturn(microserviceInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"123456\");\n    LoadBalancer loadBalancer = new LoadBalancer(rule, \"test\");\n    loadBalancer.chooseServer(invocation);\n\n    Mockito.when(rule.choose(newServers, invocation)).thenReturn(server);\n\n    Assertions.assertEquals(server, loadBalancer.chooseServer(invocation));\n    Assertions.assertEquals(\"test\", loadBalancer.getMicroServiceName());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestRoundRobinRuleExt {\n  @Test\n  public void testRoundRobin() {\n    RoundRobinRuleExt rule = new RoundRobinRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    for (int i = 0; i < 2; i++) {\n      ServiceCombServer server = Mockito.mock(ServiceCombServer.class);\n      Mockito.when(server.toString()).thenReturn(\"server \" + i);\n      servers.add(server);\n    }\n\n    AtomicInteger server1 = new AtomicInteger(0);\n    AtomicInteger server2 = new AtomicInteger(0);\n    for (int i = 0; i < 2000; i++) {\n      if (rule.choose(servers, invocation).toString().equals(\"server 0\")) {\n        server1.incrementAndGet();\n      } else {\n        server2.incrementAndGet();\n      }\n    }\n    Assertions.assertEquals(server1.get(), server2.get());\n  }\n\n  @Test\n  public void testBenchmarkRobin() {\n    // less than 0.001ms\n    RoundRobinRuleExt rule = new RoundRobinRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    for (int i = 0; i < 100; i++) {\n      ServiceCombServer server = Mockito.mock(ServiceCombServer.class);\n      Mockito.when(server.toString()).thenReturn(\"server \" + i);\n      servers.add(server);\n    }\n    long begin = System.currentTimeMillis();\n    for (int i = 0; i < 10000; i++) {\n      rule.choose(servers, invocation);\n    }\n    long taken = System.currentTimeMillis() - begin;\n    System.out.println(\"taken \" + taken);\n    Assertions.assertTrue(taken < 10 * 5, \"actual token \" + taken);  // 5 * times make slow machine happy\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\n/**\n *\n *\n */\npublic class TestServiceCombServer {\n\n  private final Transport transport = Mockito.mock(Transport.class);\n\n  private ServiceCombServer cs;\n\n  @Before\n  public void setUp() {\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"123456\");\n    cs = new ServiceCombServer(null, new Endpoint(transport, \"abcd\", instance));\n  }\n\n  @Test\n  public void testCseServerObj() {\n    Assertions.assertNotNull(cs);\n  }\n\n  @Test\n  public void testGetEndpoint() {\n    cs.getEndpoint();\n    Assertions.assertNotNull(cs.getEndpoint());\n  }\n\n  @Test\n  public void testEqualsMethod() {\n    Assertions.assertNotEquals(cs, (Object) \"abcd\");\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance1 = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"1234\");\n    ServiceCombServer other = new ServiceCombServer(null, new Endpoint(transport, \"1234\", instance1));\n    Assertions.assertNotEquals(cs, other);\n\n    DiscoveryInstance discoveryInstance2 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance2 = new StatefulDiscoveryInstance(discoveryInstance2);\n    Mockito.when(discoveryInstance2.getInstanceId()).thenReturn(\"123456\");\n    other = new ServiceCombServer(null, new Endpoint(transport, \"abcd\", instance2));\n    Assertions.assertEquals(cs, other);\n  }\n\n  @Test\n  public void testToStringMethod() {\n    cs.toString();\n    Assertions.assertNotNull(cs.toString());\n  }\n\n  @Test\n  public void testGetHost() {\n    cs.getHost();\n    Assertions.assertNotNull(cs.getHost());\n  }\n\n  @Test\n  public void testHashCodeMethod() {\n    cs.hashCode();\n    Assertions.assertNotNull(cs.hashCode());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionStickinessRule.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\nimport mockit.Deencapsulation;\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class TestSessionStickinessRule {\n  @Test\n  public void testServerWithoutTimeoutAndWithThreshold() {\n\n    boolean status = true;\n\n    SessionStickinessRule ss = new SessionStickinessRule();\n\n    Invocation invocation = mock(Invocation.class);\n    ServiceCombServer server = mock(ServiceCombServer.class);\n    List<ServiceCombServer> servers = new ArrayList<>();\n    servers.add(server);\n\n    Deencapsulation.setField(ss, \"lastServer\", server);\n\n    ServerMetrics serverMetrics = new ServerMetrics();\n    Mockito.when(server.getServerMetrics()).thenReturn(serverMetrics);\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isTimeOut() {\n        return false;\n      }\n    };\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isErrorThresholdMet(ServiceCombServer server) {\n        return true;\n      }\n    };\n\n    try {\n      ss.choose(servers, invocation);\n    } catch (Exception e) {\n      e.printStackTrace();\n      status = false;\n    }\n    Assertions.assertTrue(status);\n  }\n\n  @Test\n  public void testServerWithTimeout() {\n\n    boolean status = true;\n\n    SessionStickinessRule ss = new SessionStickinessRule();\n\n    Invocation invocation = mock(Invocation.class);\n    ServiceCombServer server = mock(ServiceCombServer.class);\n    List<ServiceCombServer> servers = new ArrayList<>();\n    servers.add(server);\n\n    Deencapsulation.setField(ss, \"lastServer\", server);\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isTimeOut() {\n        return true;\n      }\n    };\n\n    try {\n      ss.choose(servers, invocation);\n    } catch (Exception e) {\n      status = false;\n    }\n\n    Assertions.assertTrue(status);\n  }\n\n  @Test\n  public void testServerWithoutTimeoutException() {\n\n    boolean status = true;\n\n    SessionStickinessRule ss = new SessionStickinessRule();\n\n    Invocation invocation = mock(Invocation.class);\n    ServiceCombServer server = mock(ServiceCombServer.class);\n    List<ServiceCombServer> servers = new ArrayList<>();\n    servers.add(server);\n\n    Deencapsulation.setField(ss, \"lastServer\", server);\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isTimeOut() {\n        return false;\n      }\n    };\n\n    try {\n      ss.choose(servers, invocation);\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertFalse(status);\n  }\n\n  @Test\n  public void testServerWithoutTimeoutAndThreshold() {\n\n    boolean status = true;\n\n    SessionStickinessRule ss = new SessionStickinessRule();\n\n    Invocation invocation = mock(Invocation.class);\n    ServiceCombServer server = mock(ServiceCombServer.class);\n    List<ServiceCombServer> servers = new ArrayList<>();\n    servers.add(server);\n\n    Deencapsulation.setField(ss, \"lastServer\", server);\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isTimeOut() {\n        return false;\n      }\n    };\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isErrorThresholdMet(ServiceCombServer server) {\n        return false;\n      }\n    };\n\n    new MockUp<SessionStickinessRule>() {\n\n      @Mock\n      private boolean isLastServerExists(ServiceCombServer server) {\n        return true;\n      }\n    };\n\n    try {\n      ss.choose(servers, invocation);\n    } catch (Exception e) {\n      status = false;\n    }\n    Assertions.assertTrue(status);\n  }\n\n  @Test\n  public void testLastServerNotExist() {\n    SessionStickinessRule rule = new SessionStickinessRule();\n\n    Transport transport = mock(Transport.class);\n    Invocation invocation = mock(Invocation.class);\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance1 = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"1234\");\n    ServiceCombServer mockedServer =\n        new ServiceCombServer(null, new Endpoint(transport, \"rest:127.0.0.1:8890\", instance1));\n    List<ServiceCombServer> allServers = Arrays.asList(mockedServer);\n    LoadBalancer lb = new LoadBalancer(rule, \"mockedServer\");\n    when(invocation.getLocalContext(LoadBalanceFilter.CONTEXT_KEY_SERVER_LIST)).thenReturn(allServers);\n    rule.setLoadBalancer(lb);\n    ServiceCombServer server = new ServiceCombServer(null,\n        new Endpoint(transport, \"rest:127.0.0.1:8890\", instance1));\n    Deencapsulation.setField(rule, \"lastServer\", server);\n\n    new MockUp<SessionStickinessRule>(rule) {\n      @Mock\n      private boolean isTimeOut() {\n        return false;\n      }\n\n      @Mock\n      private boolean isErrorThresholdMet(ServiceCombServer server) {\n        return false;\n      }\n    };\n    ServiceCombServer s = rule.choose(allServers, invocation);\n    Assertions.assertEquals(mockedServer, s);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.github.resilience4j.core.metrics.Metrics.Outcome;\n\npublic class TestWeightedResponseTimeRuleExt {\n  @Test\n  public void testRoundRobin() {\n    WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    for (int i = 0; i < 2; i++) {\n      ServiceCombServer server = Mockito.mock(ServiceCombServer.class);\n      ServerMetrics serverMetrics = new ServerMetrics();\n      Mockito.when(server.getServerMetrics()).thenReturn(serverMetrics);\n      Mockito.when(server.toString()).thenReturn(\"server \" + i);\n      servers.add(server);\n      serverMetrics.record(1, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n    }\n\n    AtomicInteger server1 = new AtomicInteger(0);\n    AtomicInteger server2 = new AtomicInteger(0);\n    for (int i = 0; i < 2000; i++) {\n      if (rule.choose(servers, invocation).toString().equals(\"server 0\")) {\n        server1.incrementAndGet();\n      } else {\n        server2.incrementAndGet();\n      }\n    }\n    Assertions.assertEquals(server1.get(), server2.get());\n  }\n\n  @Test\n  public void testWeighed() {\n    WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n\n    ServiceCombServer server1 = Mockito.mock(ServiceCombServer.class);\n    Mockito.when(server1.toString()).thenReturn(\"server \" + 0);\n    servers.add(server1);\n    ServerMetrics serverMetrics1 = new ServerMetrics();\n    Mockito.when(server1.getServerMetrics()).thenReturn(serverMetrics1);\n\n    ServiceCombServer server2 = Mockito.mock(ServiceCombServer.class);\n    Mockito.when(server2.toString()).thenReturn(\"server \" + 1);\n    servers.add(server2);\n    ServerMetrics serverMetrics2 = new ServerMetrics();\n    Mockito.when(server2.getServerMetrics()).thenReturn(serverMetrics2);\n\n    AtomicInteger serverCounter1 = new AtomicInteger(0);\n    AtomicInteger serverCounter2 = new AtomicInteger(0);\n    for (int i = 0; i < 100; i++) {\n      serverMetrics1.record(200, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n      serverMetrics2.record(400, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n    }\n    for (int i = 0; i < 2000; i++) {\n      if (rule.choose(servers, invocation).toString().equals(\"server 0\")) {\n        serverCounter1.incrementAndGet();\n      } else {\n        serverCounter2.incrementAndGet();\n      }\n    }\n    double percent = (double) serverCounter1.get() / (serverCounter2.get() + serverCounter1.get());\n    System.out.println(\"percent\" + percent);\n    Assertions.assertEquals(0.67d, percent, 0.1);\n    serverCounter1.set(0);\n    serverCounter2.set(0);\n\n    for (int i = 0; i < 100; i++) {\n      serverMetrics1.record(20, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n      serverMetrics2.record(20, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n    }\n    for (int i = 0; i < 2000; i++) {\n      if (rule.choose(servers, invocation).toString().equals(\"server 0\")) {\n        serverCounter1.incrementAndGet();\n      } else {\n        serverCounter2.incrementAndGet();\n      }\n    }\n    percent = (double) serverCounter1.get() / (serverCounter2.get() + serverCounter1.get());\n    System.out.println(\"percent\" + percent);\n    Assertions.assertEquals(0.50d, percent, 0.1);\n  }\n\n  @Test\n  public void testBenchmark() {\n    // 100 instances will taken less than 0.1ms. Because we use weighed rule when response time more than 10ms,\n    // This only taken 1/1000 time.\n    WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    for (int i = 0; i < 100; i++) {\n      ServiceCombServer server = Mockito.mock(ServiceCombServer.class);\n      ServerMetrics serverMetrics = new ServerMetrics();\n      Mockito.when(server.toString()).thenReturn(\"server \" + i);\n      Mockito.when(server.getServerMetrics()).thenReturn(serverMetrics);\n      servers.add(server);\n      serverMetrics.record(i, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n    }\n    long begin = System.currentTimeMillis();\n    for (int i = 0; i < 100000; i++) {\n      rule.choose(servers, invocation);\n    }\n    long taken = System.currentTimeMillis() - begin;\n    System.out.println(\"taken \" + taken);\n    Assertions.assertTrue(taken < 1000 * 5, \"actually taken: \" + taken); // 5 * times make slow machine happy\n  }\n\n  @Test\n  public void testBenchmarkRobin() {\n    // 100 instances will taken less than 0.02ms. Not as good as RoundRobinRule, which taken less than 0.001ms\n    WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();\n    List<ServiceCombServer> servers = new ArrayList<>();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    for (int i = 0; i < 100; i++) {\n      ServiceCombServer server = Mockito.mock(ServiceCombServer.class);\n      ServerMetrics serverMetrics = new ServerMetrics();\n      Mockito.when(server.toString()).thenReturn(\"server \" + i);\n      Mockito.when(server.getServerMetrics()).thenReturn(serverMetrics);\n      servers.add(server);\n      serverMetrics.record(2, TimeUnit.MILLISECONDS, Outcome.SUCCESS);\n    }\n    long begin = System.currentTimeMillis();\n    for (int i = 0; i < 100000; i++) {\n      rule.choose(servers, invocation);\n    }\n    long taken = System.currentTimeMillis() - begin;\n    System.out.println(\"taken \" + taken);\n    Assertions.assertTrue(taken < 200 * 5, \"actually taken: \" + taken); // 5 * times make slow machine happy\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/exception/TestLoadbalanceExceptionUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.exception;\n\nimport org.apache.servicecomb.core.exception.CseException;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestLoadbalanceExceptionUtils {\n\n  @Test\n  public void testLoadbalanceExceptionUtils() {\n\n    Assertions.assertEquals(\"servicecomb.handler.lb.wrong.rule\", LoadbalanceExceptionUtils.CSE_HANDLER_LB_WRONG_RULE);\n    CseException cseException = LoadbalanceExceptionUtils.createLoadbalanceException(\"servicecomb.handler.lb.wrong.rule\",\n        new Throwable(),\n        \"ARGS\");\n    Assertions.assertNotNull(cseException);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.MutablePropertySources;\n\nimport com.google.common.collect.Sets;\n\n/**\n * Test for PriorityInstancePropertyDiscoveryFilter\n */\npublic class PriorityInstancePropertyDiscoveryFilterTest {\n\n  public static final String PROPERTY_KEY = \"environment\";\n\n  private PriorityInstancePropertyDiscoveryFilter filter;\n\n  private List<StatefulDiscoveryInstance> instances;\n\n  StatefulDiscoveryInstance instance1;\n\n  ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\n\n  EnumerablePropertySource propertySource;\n\n  DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class);\n\n  @Before\n  public void setUp() {\n    propertySource = Mockito.mock(EnumerablePropertySource.class);\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.service.properties.\" + PROPERTY_KEY\n    });\n\n    filter = new PriorityInstancePropertyDiscoveryFilter();\n    filter.setEnvironment(environment);\n    filter.setDynamicProperties(dynamicProperties);\n    Mockito.when(dynamicProperties.getStringProperty(Mockito.eq(\"servicecomb.loadbalance.filter.priorityInstanceProperty.key\"),\n        Mockito.any(),\n        Mockito.eq(\"environment\"))).thenReturn(\"environment\");\n    instances = new ArrayList<>();\n    filter.setEnvironment(environment);\n    DiscoveryInstance discoveryInstance1 = Mockito.mock(DiscoveryInstance.class);\n    instance1 = new StatefulDiscoveryInstance(discoveryInstance1);\n    Mockito.when(discoveryInstance1.getInstanceId()).thenReturn(\"instance.empty\");\n\n    DiscoveryInstance discoveryInstance2 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance2 = new StatefulDiscoveryInstance(discoveryInstance2);\n    Mockito.when(discoveryInstance2.getInstanceId()).thenReturn(\"instance.local\");\n    Map<String, String> properties = new HashMap<>();\n    properties.put(PROPERTY_KEY, \"local\");\n    Mockito.when(discoveryInstance2.getProperties()).thenReturn(properties);\n\n    DiscoveryInstance discoveryInstance3 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance3 = new StatefulDiscoveryInstance(discoveryInstance3);\n    Mockito.when(discoveryInstance3.getInstanceId()).thenReturn(\"instance.local.feature1\");\n    Map<String, String> properties3 = new HashMap<>();\n    properties3.put(PROPERTY_KEY, \"local.feature1\");\n    Mockito.when(discoveryInstance3.getProperties()).thenReturn(properties3);\n\n    DiscoveryInstance discoveryInstance4 = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance4 = new StatefulDiscoveryInstance(discoveryInstance4);\n    Mockito.when(discoveryInstance4.getInstanceId()).thenReturn(\"instance.local.feature1.sprint1\");\n    Map<String, String> properties4 = new HashMap<>();\n    properties4.put(PROPERTY_KEY, \"local.feature1.sprint1\");\n    Mockito.when(discoveryInstance4.getProperties()).thenReturn(properties4);\n\n    instances.add(instance1);\n    instances.add(instance2);\n    instances.add(instance3);\n    instances.add(instance4);\n  }\n\n  @After\n  public void cleanup() {\n  }\n\n  @Test\n  public void testGetFilteredListOfServers() {\n\n    //complete match\n    executeTest(\"\", Sets.newHashSet(\"instance.empty\"));\n    executeTest(\"local\", Sets.newHashSet(\"instance.local\"));\n    executeTest(\"local.feature1\", Sets.newHashSet(\"instance.local.feature1\"));\n    executeTest(\"local.feature1.sprint1\", Sets.newHashSet(\"instance.local.feature1.sprint1\"));\n\n    //priority match\n    executeTest(\"test\", Sets.newHashSet(\"instance.empty\"));\n    executeTest(\"local.feature2\", Sets.newHashSet(\"instance.local\"));\n    executeTest(\"local.feature1.sprint2\", Sets.newHashSet(\"instance.local.feature1\"));\n    executeTest(\"local.feature2.sprint1\", Sets.newHashSet(\"instance.local\"));\n    executeTest(\"local.feature1.sprint2.temp\", Sets.newHashSet(\"instance.local.feature1\"));\n\n    //none match\n    instances.remove(instance1);\n    executeTest(\"\", Collections.emptySet());\n    executeTest(\"foo\", Collections.emptySet());\n    instances.add(instance1);\n  }\n\n\n  private void executeTest(String selfProperty, Set<String> expectedMatchedKeys) {\n    Mockito.when(environment.getProperty(\"servicecomb.service.properties.\" + PROPERTY_KEY)).thenReturn(selfProperty);\n\n    Invocation invocation = new Invocation();\n    DiscoveryContext discoveryContext = new DiscoveryContext();\n    discoveryContext.setInputParameters(invocation);\n\n    DiscoveryTreeNode parent = new DiscoveryTreeNode();\n    parent.name(\"parent\");\n    parent.data(instances);\n\n    DiscoveryTreeNode node = filter.discovery(discoveryContext, parent);\n    List<StatefulDiscoveryInstance> filterInstance = node.data();\n    assertThat(filterInstance.stream().map(instance -> instance.getInstanceId()).collect(\n        Collectors.toList())).containsAnyElementsOf(expectedMatchedKeys);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestInstancePropertyDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.MutablePropertySources;\n\npublic class TestInstancePropertyDiscoveryFilter {\n\n  private InstancePropertyDiscoveryFilter filter;\n\n  StatefulDiscoveryInstance instance;\n\n  ConfigurableEnvironment environment;\n\n  EnumerablePropertySource<?> propertySource;\n\n  @BeforeEach\n  public void setUp() {\n    environment = Mockito.mock(ConfigurableEnvironment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n    propertySource = Mockito.mock(EnumerablePropertySource.class);\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.loadbalance.test.flowsplitFilter.policy\",\n        \"servicecomb.loadbalance.test.flowsplitFilter.options.tag0\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.loadbalance.test.flowsplitFilter.policy\"))\n        .thenReturn(\"org.apache.servicecomb.loadbalance.filter.SimpleFlowsplitFilter\");\n    Mockito.when(environment.getProperty(\"servicecomb.loadbalance.test.flowsplitFilter.options.tag0\"))\n        .thenReturn(\"value0\");\n\n    filter = new InstancePropertyDiscoveryFilter();\n    Map<String, String> properties = new HashMap<>();\n    properties.put(\"tag0\", \"value0\");\n    properties.put(\"tag1\", \"value1\");\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    instance = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"instance111\");\n    Mockito.when(discoveryInstance.getProperties()).thenReturn(properties);\n  }\n\n  @Test\n  public void testAllowVisit() {\n    Map<String, String> filterOptions = new HashMap<>();\n    Assertions.assertTrue(filter.allowVisit(instance, filterOptions));\n\n    filterOptions.put(\"tag0\", \"value0\");\n    Assertions.assertTrue(filter.allowVisit(instance, filterOptions));\n\n    filterOptions.put(\"tag2\", \"value2\");\n    Assertions.assertFalse(filter.allowVisit(instance, filterOptions));\n\n    filterOptions.clear();\n    filterOptions.put(\"tag0\", \"value1\");\n    Assertions.assertFalse(filter.allowVisit(instance, filterOptions));\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void testGetFilteredListOfServers() {\n    DiscoveryContext context = new DiscoveryContext();\n    DiscoveryTreeNode parent = new DiscoveryTreeNode();\n\n    Invocation invocation = Mockito.mock(Invocation.class);\n    context.setInputParameters(invocation);\n\n    List<StatefulDiscoveryInstance> instances = new ArrayList<>();\n    instances.add(instance);\n    parent.data(instances);\n    parent.name(\"parent\");\n\n    DiscoveryTreeNode node = filter.discovery(context, parent);\n    Assertions.assertEquals(1, ((List<StatefulDiscoveryInstance>) node.data()).size());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport static org.mockito.ArgumentMatchers.any;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestServerDiscoveryFilter {\n  ServerDiscoveryFilter filter = new ServerDiscoveryFilter();\n\n  @Test\n  public void createEndpoint_TransportNotExist() {\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    Mockito.when(transportManager.findTransport(any(String.class))).thenReturn(null);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    filter.setScbEngine(scbEngine);\n    ServiceCombServer server = (ServiceCombServer) filter.createEndpoint(null, CoreConst.RESTFUL, null, null);\n    Assertions.assertNull(server);\n  }\n\n  @Test\n  public void createEndpointNormal() {\n    TransportManager transportManager = Mockito.mock(TransportManager.class);\n    SCBEngine scbEngine = Mockito.mock(SCBEngine.class);\n    Mockito.when(scbEngine.getTransportManager()).thenReturn(transportManager);\n    Transport transport = Mockito.mock(Transport.class);\n    Invocation invocation = Mockito.mock(Invocation.class);\n    Mockito.when(transportManager.findTransport(any(String.class))).thenReturn(transport);\n    Mockito.when(invocation.getConfigTransportName()).thenReturn(CoreConst.RESTFUL);\n    Mockito.when(invocation.getMicroserviceName()).thenReturn(\"test\");\n    DiscoveryContext context = new DiscoveryContext();\n    context.setInputParameters(invocation);\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance instance = new StatefulDiscoveryInstance(discoveryInstance);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"0000001\");\n    filter.setScbEngine(scbEngine);\n\n    ServiceCombServer server = (ServiceCombServer) filter\n        .createEndpoint(context, CoreConst.RESTFUL, \"rest://localhost:8080\", instance);\n    Assertions.assertSame(instance, server.getInstance());\n    Assertions.assertSame(transport, server.getEndpoint().getTransport());\n    Assertions.assertEquals(\"rest://localhost:8080\", server.getEndpoint().getEndpoint());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareDiscoveryFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.loadbalance.filter;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.DiscoveryContext;\nimport org.apache.servicecomb.registry.discovery.DiscoveryTreeNode;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestZoneAwareDiscoveryFilter {\n  DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class);\n\n  @BeforeEach\n  public void setUp() {\n\n    Mockito.when(dynamicProperties.getBooleanProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.enabled\"),\n            Mockito.any(),\n            Mockito.eq(true)))\n        .thenReturn(true);\n  }\n\n  @Test\n  public void test_not_enough_instance() {\n\n    Mockito.when(dynamicProperties.getIntProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.ratio\"),\n            Mockito.any(),\n            Mockito.eq(30)))\n        .thenReturn(50);\n    Mockito.when(dynamicProperties.getIntProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.ratioCeiling\"),\n            Mockito.any(),\n            Mockito.eq(50)))\n        .thenReturn(70);\n\n    ZoneAwareDiscoveryFilter filter = new ZoneAwareDiscoveryFilter();\n    filter.setDynamicProperties(dynamicProperties);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test-Region\");\n    myself.setAvailableZone(\"test-zone\");\n    filter.setDataCenterProperties(myself);\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance allmatchInstance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test-Region\");\n    info.setAvailableZone(\"test-zone\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:9090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"allmatchInstance\");\n\n    DiscoveryInstance regionMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance regionMatchInstance = new StatefulDiscoveryInstance(regionMatchDiscoveryInstance);\n    DataCenterInfo regionMatchInfo = new DataCenterInfo();\n    regionMatchInfo.setName(\"test\");\n    regionMatchInfo.setRegion(\"test-Region\");\n    regionMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> regionMatchEndpoint = new ArrayList<>();\n    regionMatchEndpoint.add(\"rest://localhost:9091\");\n    Mockito.when(regionMatchDiscoveryInstance.getEndpoints()).thenReturn(regionMatchEndpoint);\n    Mockito.when(regionMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(regionMatchInfo);\n    Mockito.when(regionMatchDiscoveryInstance.getInstanceId()).thenReturn(\"regionMatchInstance\");\n\n    DiscoveryInstance noneMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance noneMatchInstance = new StatefulDiscoveryInstance(noneMatchDiscoveryInstance);\n    DataCenterInfo noneMatchInfo = new DataCenterInfo();\n    noneMatchInfo.setName(\"test\");\n    noneMatchInfo.setRegion(\"test-Region2\");\n    noneMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> noMatchEndpoint = new ArrayList<>();\n    noMatchEndpoint.add(\"rest://localhost:9092\");\n    Mockito.when(noneMatchDiscoveryInstance.getEndpoints()).thenReturn(noMatchEndpoint);\n    Mockito.when(noneMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(noneMatchInfo);\n    Mockito.when(noneMatchDiscoveryInstance.getInstanceId()).thenReturn(\"noneMatchInstance\");\n\n    // run test\n    List<StatefulDiscoveryInstance> data = Arrays.asList(allmatchInstance, regionMatchInstance, noneMatchInstance);\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n    DiscoveryContext context = new DiscoveryContext();\n    DiscoveryTreeNode result = filter.discovery(context, parent);\n\n    // check result\n    Integer level = context.getContextParameter(filter.contextParameter());\n    Integer groups = parent.attribute(filter.groupsSizeParameter());\n    List<StatefulDiscoveryInstance> resultData = result.data();\n    Assertions.assertEquals(1, level);\n    Assertions.assertEquals(2, groups);\n    Assertions.assertEquals(2, resultData.size());\n    Assertions.assertEquals(\"regionMatchInstance\", resultData.get(0).getInstanceId());\n    Assertions.assertEquals(\"allmatchInstance\", resultData.get(1).getInstanceId());\n  }\n\n  @Test\n  public void test_not_enough_instance_both_ceiling_floor() {\n\n    Mockito.when(dynamicProperties.getIntProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.ratio\"),\n            Mockito.any(),\n            Mockito.eq(30)))\n        .thenReturn(40);\n    Mockito.when(dynamicProperties.getIntProperty(Mockito.eq(\"servicecomb.loadbalance.filter.zoneaware.ratioCeiling\"),\n            Mockito.any(),\n            Mockito.eq(60)))\n        .thenReturn(60);\n\n    ZoneAwareDiscoveryFilter filter = new ZoneAwareDiscoveryFilter();\n    filter.setDynamicProperties(dynamicProperties);\n\n    // set up data\n    DataCenterProperties myself = new DataCenterProperties();\n    myself.setName(\"test\");\n    myself.setRegion(\"test-Region\");\n    myself.setAvailableZone(\"test-zone\");\n    filter.setDataCenterProperties(myself);\n\n    DiscoveryInstance discoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance allmatchInstance = new StatefulDiscoveryInstance(discoveryInstance);\n    DataCenterInfo info = new DataCenterInfo();\n    info.setName(\"test\");\n    info.setRegion(\"test-Region\");\n    info.setAvailableZone(\"test-zone\");\n    List<String> allMatchEndpoint = new ArrayList<>();\n    allMatchEndpoint.add(\"rest://localhost:9090\");\n    Mockito.when(discoveryInstance.getEndpoints()).thenReturn(allMatchEndpoint);\n    Mockito.when(discoveryInstance.getDataCenterInfo()).thenReturn(info);\n    Mockito.when(discoveryInstance.getInstanceId()).thenReturn(\"allmatchInstance\");\n\n    DiscoveryInstance regionMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance regionMatchInstance = new StatefulDiscoveryInstance(regionMatchDiscoveryInstance);\n    DataCenterInfo regionMatchInfo = new DataCenterInfo();\n    regionMatchInfo.setName(\"test\");\n    regionMatchInfo.setRegion(\"test-Region\");\n    regionMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> regionMatchEndpoint = new ArrayList<>();\n    regionMatchEndpoint.add(\"rest://localhost:9091\");\n    Mockito.when(regionMatchDiscoveryInstance.getEndpoints()).thenReturn(regionMatchEndpoint);\n    Mockito.when(regionMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(regionMatchInfo);\n    Mockito.when(regionMatchDiscoveryInstance.getInstanceId()).thenReturn(\"regionMatchInstance\");\n\n    DiscoveryInstance noneMatchDiscoveryInstance = Mockito.mock(DiscoveryInstance.class);\n    StatefulDiscoveryInstance noneMatchInstance = new StatefulDiscoveryInstance(noneMatchDiscoveryInstance);\n    DataCenterInfo noneMatchInfo = new DataCenterInfo();\n    noneMatchInfo.setName(\"test\");\n    noneMatchInfo.setRegion(\"test-Region2\");\n    noneMatchInfo.setAvailableZone(\"test-zone2\");\n    List<String> noMatchEndpoint = new ArrayList<>();\n    noMatchEndpoint.add(\"rest://localhost:9092\");\n    Mockito.when(noneMatchDiscoveryInstance.getEndpoints()).thenReturn(noMatchEndpoint);\n    Mockito.when(noneMatchDiscoveryInstance.getDataCenterInfo()).thenReturn(noneMatchInfo);\n    Mockito.when(noneMatchDiscoveryInstance.getInstanceId()).thenReturn(\"noneMatchInstance\");\n\n    // run test\n    List<StatefulDiscoveryInstance> data = Arrays.asList(allmatchInstance, regionMatchInstance, noneMatchInstance);\n    DiscoveryTreeNode parent = new DiscoveryTreeNode().name(\"parent\").data(data);\n    DiscoveryContext context = new DiscoveryContext();\n    DiscoveryTreeNode result = filter.discovery(context, parent);\n\n    // check result\n    Integer level = context.getContextParameter(filter.contextParameter());\n    Integer groups = parent.attribute(filter.groupsSizeParameter());\n    List<StatefulDiscoveryInstance> resultData = result.data();\n    Assertions.assertEquals(null, level);\n    Assertions.assertEquals(1, groups);\n    Assertions.assertEquals(3, resultData.size());\n    Assertions.assertEquals(\"noneMatchInstance\", resultData.get(0).getInstanceId());\n    Assertions.assertEquals(\"regionMatchInstance\", resultData.get(1).getInstanceId());\n    Assertions.assertEquals(\"allmatchInstance\", resultData.get(2).getInstanceId());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-loadbalance/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  filter-chains:\n    consumer:\n      default: empty\n    producer:\n      default: empty\n"
  },
  {
    "path": "handlers/handler-publickey-auth/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>handlers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>handler-publickey-auth</artifactId>\n  <name>Java Chassis::Handlers::PublicKey Auth</name>\n\n  <properties>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/AuthenticationBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairEntry;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairUtils;\nimport org.apache.servicecomb.foundation.token.Keypair4Auth;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.springframework.beans.factory.annotation.Autowired;\n\n/**\n * initialize public and private key pair when system boot before registry instance to service center\n */\npublic class AuthenticationBootListener implements BootListener {\n  private RegistrationManager registrationManager;\n\n  @Autowired\n  public void setRegistrationManager(RegistrationManager registrationManager) {\n    this.registrationManager = registrationManager;\n  }\n\n  @Override\n  public void onBootEvent(BootEvent event) {\n    if (!EventType.BEFORE_REGISTRY.equals(event.getEventType())) {\n      return;\n    }\n    KeyPairEntry rsaKeyPairEntry = KeyPairUtils.generateALGKeyPair();\n    Keypair4Auth.INSTANCE.setPrivateKey(rsaKeyPairEntry.getPrivateKey());\n    Keypair4Auth.INSTANCE.setPublicKey(rsaKeyPairEntry.getPublicKey());\n    Keypair4Auth.INSTANCE.setPublicKeyEncoded(rsaKeyPairEntry.getPublicKeyEncoded());\n    this.registrationManager.addProperty(DefinitionConst.INSTANCE_PUBKEY_PRO,\n        rsaKeyPairEntry.getPublicKeyEncoded());\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/AuthenticationConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication;\n\nimport org.apache.servicecomb.authentication.consumer.ConsumerAuthFilter;\nimport org.apache.servicecomb.authentication.consumer.ConsumerTokenManager;\nimport org.apache.servicecomb.authentication.provider.AccessController;\nimport org.apache.servicecomb.authentication.provider.ProviderAuthFilter;\nimport org.apache.servicecomb.authentication.provider.ProviderTokenManager;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\n@ConditionalOnProperty(value = AuthenticationConfiguration.ACCESS_CONTROL_ENABLED,\n    havingValue = \"true\")\npublic class AuthenticationConfiguration {\n  public static final String ACCESS_CONTROL_PREFIX = \"servicecomb.publicKey.accessControl\";\n\n  public static final String ACCESS_CONTROL_ENABLED = ACCESS_CONTROL_PREFIX + \".enabled\";\n\n  @Bean\n  public ConsumerAuthFilter scbConsumerAuthFilter() {\n    return new ConsumerAuthFilter();\n  }\n\n  @Bean\n  public ProviderAuthFilter scbProviderAuthFilter() {\n    return new ProviderAuthFilter();\n  }\n\n  @Bean\n  public AuthenticationBootListener scbAuthenticationBootListener() {\n    return new AuthenticationBootListener();\n  }\n\n  @Bean\n  public ConsumerTokenManager scbConsumerTokenManager() {\n    return new ConsumerTokenManager();\n  }\n\n  @Bean\n  public ProviderTokenManager scbProviderTokenManager() {\n    return new ProviderTokenManager();\n  }\n\n  @Bean\n  public AccessController scbAccessController(Environment environment) {\n    return new AccessController(environment);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/RSAAuthenticationToken.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication;\n\n\n/**\n * token 组成部分：\n * token: instanceId@@generateTime@randomCode@sign(instanceId@@generateTime@randomCode)\n *\n */\npublic class RSAAuthenticationToken {\n\n  public static final long TOKEN_ACTIVE_TIME = 24 * 60 * 60 * 1000;\n\n  private final String instanceId;\n\n  private final String serviceId;\n\n  private final long generateTime;\n\n  private final String randomCode;\n\n  private final String sign;\n\n  private final String tokenFormat;\n\n  private final String plainToken;\n\n  public RSAAuthenticationToken(String instanceId, String serviceId, long generateTime,\n      String randomCode, String sign) {\n    this.instanceId = instanceId;\n    this.generateTime = generateTime;\n    this.randomCode = randomCode;\n    this.serviceId = serviceId;\n    this.sign = sign;\n    this.tokenFormat = String.format(\"%s@%s@%s@%s@%s\",\n        instanceId,\n        serviceId,\n        generateTime,\n        randomCode,\n        sign);\n    this.plainToken = String.format(\"%s@%s@%s@%s\", this.instanceId, this.serviceId, this.generateTime, this.randomCode);\n  }\n\n  public String plainToken() {\n    return this.plainToken;\n  }\n\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n\n  public long getGenerateTime() {\n    return generateTime;\n  }\n\n\n  public String getSign() {\n    return sign;\n  }\n\n\n  public String format() {\n    return tokenFormat;\n  }\n\n  public static RSAAuthenticationToken fromStr(String token) {\n    String[] tokenArr = token.split(\"@\");\n    if (tokenArr.length != 5) {\n      return null;\n    }\n    return new RSAAuthenticationToken(tokenArr[0], tokenArr[1],\n        Long.parseLong(tokenArr[2]), tokenArr[3], tokenArr[4]);\n  }\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  @Override\n  public boolean equals(Object obj) {\n    if (!(obj instanceof RSAAuthenticationToken)) {\n      return false;\n    }\n    RSAAuthenticationToken token = (RSAAuthenticationToken) obj;\n    if (!token.plainToken().equals(this.plainToken())) {\n      return false;\n    }\n    return token.getSign().equals(this.sign);\n  }\n\n  public int hashCode() {\n    return this.plainToken().hashCode() + this.sign.hashCode();\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/consumer/ConsumerAuthFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.consumer;\n\nimport java.util.Optional;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ConsumerAuthFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private ConsumerTokenManager authenticationTokenManager;\n\n  @Autowired\n  public void setConsumerTokenManager(ConsumerTokenManager consumerTokenManager) {\n    this.authenticationTokenManager = consumerTokenManager;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1010;\n  }\n\n  @Override\n  public String getName() {\n    return \"consumer-public-key\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    Optional<String> token = Optional.ofNullable(authenticationTokenManager.getToken());\n    if (!token.isPresent()) {\n      return CompletableFuture.failedFuture(\n          new InvocationException(Status.SERVICE_UNAVAILABLE, \"auth token is not properly configured yet.\"));\n    }\n    invocation.addContext(CoreConst.AUTH_TOKEN, token.get());\n    return nextNode.onFilter(invocation);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/consumer/ConsumerTokenManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.consumer;\n\nimport java.security.PrivateKey;\n\nimport org.apache.servicecomb.authentication.RSAAuthenticationToken;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairUtils;\nimport org.apache.servicecomb.foundation.token.Keypair4Auth;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class ConsumerTokenManager {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerTokenManager.class);\n\n  private final Object lock = new Object();\n\n  private RSAAuthenticationToken token;\n\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  public String getToken() {\n\n    if (isExpired(token)) {\n      synchronized (lock) {\n        if (isExpired(token)) {\n          return createToken();\n        }\n      }\n    }\n    return token.format();\n  }\n\n  public String createToken() {\n    PrivateKey privateKey = Keypair4Auth.INSTANCE.getPrivateKey();\n    String instanceId = BootStrapProperties.readServiceName(environment);\n    String serviceId = BootStrapProperties.readApplication(environment);\n\n    if (instanceId == null || serviceId == null) {\n      LOGGER.error(\"service not ready when create token.\");\n      return null;\n    }\n\n    @SuppressWarnings(\"deprecation\")\n    String randomCode = org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric(128);\n    long generateTime = System.currentTimeMillis();\n    try {\n      String plain = String.format(\"%s@%s@%s@%s\", instanceId, serviceId, generateTime, randomCode);\n      String sign = KeyPairUtils.sign(plain, privateKey);\n      token = RSAAuthenticationToken.fromStr(String.format(\"%s@%s\", plain, sign));\n    } catch (Exception e) {\n      LOGGER.error(\"create token error\", e);\n      return null;\n    }\n    return token.format();\n  }\n\n  /**\n   * the TTL of Token is  24 hours\n   * client token will expired 15 minutes early\n   */\n  public boolean isExpired(RSAAuthenticationToken token) {\n    if (null == token) {\n      return true;\n    }\n    long generateTime = token.getGenerateTime();\n    long expiredDate = generateTime + RSAAuthenticationToken.TOKEN_ACTIVE_TIME - 15 * 60 * 1000;\n    long now = System.currentTimeMillis();\n    return now > expiredDate;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/AccessController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.provider;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.Subscribe;\n\n/**\n * Add black / white list control to service access\n */\npublic class AccessController {\n  static class ConfigurationItem {\n    static final String CATEGORY_PROPERTY = \"property\";\n\n    String category;\n\n    String propertyName;\n\n    String rule;\n  }\n\n  private static final Logger LOG = LoggerFactory.getLogger(AccessController.class);\n\n  private static final String KEY_WHITE_LIST_PREFIX = \"servicecomb.publicKey.accessControl.white\";\n\n  private static final String KEY_BLACK_LIST_PREFIX = \"servicecomb.publicKey.accessControl.black\";\n\n  private static final String KEY_PROPERTY_NAME = \"%s.%s.propertyName\";\n\n  private static final String KEY_CATEGORY = \"%s.%s.category\";\n\n  private static final String KEY_RULE_POSTFIX = \".rule\";\n\n  private final Environment environment;\n\n  private Map<String, ConfigurationItem> whiteList = new HashMap<>();\n\n  private Map<String, ConfigurationItem> blackList = new HashMap<>();\n\n  public AccessController(Environment environment) {\n    this.environment = environment;\n    loadConfigurations(KEY_BLACK_LIST_PREFIX);\n    loadConfigurations(KEY_WHITE_LIST_PREFIX);\n    EventManager.register(this);\n  }\n\n  public boolean isAllowed(DiscoveryInstance microservice) {\n    return whiteAllowed(microservice) && !blackDenied(microservice);\n  }\n\n  private boolean whiteAllowed(DiscoveryInstance microservice) {\n    if (whiteList.isEmpty()) {\n      return true;\n    }\n    return matchFound(microservice, whiteList);\n  }\n\n  private boolean blackDenied(DiscoveryInstance microservice) {\n    if (blackList.isEmpty()) {\n      return false;\n    }\n    return matchFound(microservice, blackList);\n  }\n\n  private boolean matchFound(DiscoveryInstance microservice, Map<String, ConfigurationItem> ruleList) {\n    boolean matched = false;\n    for (ConfigurationItem item : ruleList.values()) {\n      if (ConfigurationItem.CATEGORY_PROPERTY.equals(item.category)) {\n        // we support to configure properties, e.g. serviceName, appId, environment, alias, version and so on, also support key in properties.\n        if (matchMicroserviceField(microservice, item) || matchMicroserviceProperties(microservice, item)) {\n          return true;\n        }\n      }\n    }\n    return matched;\n  }\n\n  private boolean matchMicroserviceProperties(DiscoveryInstance microservice, ConfigurationItem item) {\n    Map<String, String> properties = microservice.getProperties();\n    for (Entry<String, String> entry : properties.entrySet()) {\n      if (!entry.getKey().equals(item.propertyName)) {\n        continue;\n      }\n      return isPatternMatch(entry.getValue(), item.rule);\n    }\n    return false;\n  }\n\n  private boolean matchMicroserviceField(DiscoveryInstance microservice, ConfigurationItem item) {\n    String fieldValue;\n    if (\"version\".equals(item.propertyName)) {\n      fieldValue = microservice.getVersion();\n    } else if (\"serviceName\".equals(item.propertyName)) {\n      fieldValue = microservice.getServiceName();\n    } else {\n      fieldValue = microservice.getProperties().get(item.propertyName);\n    }\n    return isPatternMatch(fieldValue, item.rule);\n  }\n\n  private boolean isPatternMatch(String value, String pattern) {\n    if (pattern.startsWith(\"*\")) {\n      return value.endsWith(pattern.substring(1));\n    }\n    if (pattern.endsWith(\"*\")) {\n      return value.startsWith(pattern.substring(0, pattern.length() - 1));\n    }\n    return value.equals(pattern);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(KEY_WHITE_LIST_PREFIX)) {\n        loadConfigurations(KEY_WHITE_LIST_PREFIX);\n        break;\n      }\n    }\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(KEY_BLACK_LIST_PREFIX)) {\n        loadConfigurations(KEY_BLACK_LIST_PREFIX);\n        break;\n      }\n    }\n  }\n\n  private void loadConfigurations(String prefix) {\n    Map<String, ConfigurationItem> configurations = new HashMap<>();\n    Set<String> configsItems = ConfigUtil.propertiesWithPrefix((ConfigurableEnvironment) environment, prefix);\n    for (String pathKey : configsItems) {\n      if (pathKey.endsWith(KEY_RULE_POSTFIX)) {\n        ConfigurationItem configurationItem = new ConfigurationItem();\n        String rule = environment.getProperty(pathKey);\n        if (StringUtils.isEmpty(rule)) {\n          continue;\n        }\n        configurationItem.rule = rule;\n        String pathKeyItem = pathKey\n            .substring(prefix.length() + 1, pathKey.length() - KEY_RULE_POSTFIX.length());\n        configurationItem.propertyName = environment.getProperty(String.format(KEY_PROPERTY_NAME, prefix, pathKeyItem));\n        if (StringUtils.isEmpty(configurationItem.propertyName)) {\n          continue;\n        }\n        configurationItem.category = environment.getProperty(String.format(KEY_CATEGORY, prefix, pathKeyItem));\n        if (StringUtils.isEmpty(configurationItem.category)) {\n          continue;\n        }\n        configurations.put(pathKeyItem, configurationItem);\n      }\n    }\n\n    if (KEY_WHITE_LIST_PREFIX.equals(prefix)) {\n      this.whiteList = configurations;\n      logConfigurations(configurations, true);\n    } else {\n      this.blackList = configurations;\n      logConfigurations(configurations, false);\n    }\n  }\n\n  private void logConfigurations(Map<String, ConfigurationItem> configurations, boolean isWhite) {\n    configurations.forEach((key, item) -> LOG.info((isWhite ? \"White list \" : \"Black list \") + \"config item: key=\" + key\n        + \";category=\" + item.category\n        + \";propertyName=\" + item.propertyName\n        + \";rule=\" + item.rule));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/PathCheckUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.authentication.provider;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.springframework.core.env.Environment;\n\npublic class PathCheckUtils {\n  private static final String KEY_INCLUDE_PATH = \"servicecomb.publicKey.accessControl.includePathPatterns\";\n\n  private static final String KEY_EXCLUDE_PATH = \"servicecomb.publicKey.accessControl.excludePathPatterns\";\n\n  /**\n   * first determine configured non-authentication path is matched requestPath, if match not needed auth.\n   * second determine whether of configured authentication path, if not configured, default all path need auth;\n   * if configured, then check whether of matched requestPath, if match needed auth, otherwise not needed auth.\n   *\n   * @param requestPath path\n   * @param env environment\n   * @return notRequiredAuth\n   */\n  public static boolean isNotRequiredAuth(String requestPath, Environment env) {\n    if (excludePathMatchPath(requestPath, env)) {\n      return true;\n    }\n    return includePathMatchPath(requestPath, env);\n  }\n\n  private static boolean excludePathMatchPath(String requestPath, Environment env) {\n    String excludePathPattern = env.getProperty(KEY_EXCLUDE_PATH, \"\");\n    if (StringUtils.isEmpty(excludePathPattern)) {\n      return false;\n    }\n    return isPathMather(requestPath, excludePathPattern);\n  }\n\n  private static boolean includePathMatchPath(String requestPath, Environment env) {\n    String includePathPattern = env.getProperty(KEY_INCLUDE_PATH, \"\");\n    if (StringUtils.isEmpty(includePathPattern)) {\n      return false;\n    }\n    return !isPathMather(requestPath, includePathPattern);\n  }\n\n  private static boolean isPathMather(String requestPath, String pathPattern) {\n    for (String pattern : pathPattern.split(\",\")) {\n      if (!pattern.isEmpty() && isPatternMatch(requestPath, pattern)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  public static boolean isPatternMatch(String value, String pattern) {\n    if (pattern.startsWith(\"*\") || pattern.startsWith(\"/*\")) {\n      int index = 0;\n      for (int i = 0; i < pattern.length(); i++) {\n        if (pattern.charAt(i) != '*' && pattern.charAt(i) != '/') {\n          break;\n        }\n        index++;\n      }\n      return value.endsWith(pattern.substring(index));\n    }\n    if (pattern.endsWith(\"*\")) {\n      int index = pattern.length() - 1;\n      for (int i = pattern.length() - 1; i >= 0; i--) {\n        if (pattern.charAt(i) != '*' && pattern.charAt(i) != '/') {\n          break;\n        }\n        index--;\n      }\n      return value.startsWith(pattern.substring(0, index + 1));\n    }\n    return value.equals(pattern);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.provider;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class ProviderAuthFilter extends AbstractFilter implements ProviderFilter {\n  private ProviderTokenManager authenticationTokenManager;\n\n  private Environment env;\n\n  @Autowired\n  public void setProviderTokenManager(ProviderTokenManager providerTokenManager, Environment env) {\n    this.authenticationTokenManager = providerTokenManager;\n    this.env = env;\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER + 1010;\n  }\n\n  @Override\n  public String getName() {\n    return \"provider-public-key\";\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    String requestFullPath = SwaggerUtils.concatAbsolutePath(invocation.getSchemaMeta().getSwagger(),\n            invocation.getOperationMeta().getOperationPath());\n    if (PathCheckUtils.isNotRequiredAuth(requestFullPath, env)) {\n      return nextNode.onFilter(invocation);\n    }\n    String token = invocation.getContext(CoreConst.AUTH_TOKEN);\n    if (null != token && authenticationTokenManager.valid(token)) {\n      return nextNode.onFilter(invocation);\n    }\n    return CompletableFuture.failedFuture(\n        new InvocationException(Status.UNAUTHORIZED, \"public key authorization failed.\"));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderTokenManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.provider;\n\nimport java.security.InvalidKeyException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.SignatureException;\nimport java.security.spec.InvalidKeySpecException;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.authentication.RSAAuthenticationToken;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairUtils;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.apache.servicecomb.registry.discovery.MicroserviceInstanceCache;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.google.common.cache.Cache;\nimport com.google.common.cache.CacheBuilder;\n\npublic class ProviderTokenManager {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ProviderTokenManager.class);\n\n  private final Cache<RSAAuthenticationToken, Boolean> validatedToken = CacheBuilder.newBuilder()\n      .expireAfterAccess(getExpiredTime(), TimeUnit.MILLISECONDS)\n      .build();\n\n  private AccessController accessController;\n\n  private MicroserviceInstanceCache microserviceInstanceCache;\n\n  @Autowired\n  public void setMicroserviceInstanceCache(MicroserviceInstanceCache microserviceInstanceCache) {\n    this.microserviceInstanceCache = microserviceInstanceCache;\n  }\n\n  @Autowired\n  public void setAccessController(AccessController accessController) {\n    this.accessController = accessController;\n  }\n\n  public boolean valid(String token) {\n    try {\n      RSAAuthenticationToken rsaToken = RSAAuthenticationToken.fromStr(token);\n      if (null == rsaToken) {\n        LOGGER.error(\"token format is error, perhaps you need to set auth handler at consumer\");\n        return false;\n      }\n      if (tokenExpired(rsaToken)) {\n        LOGGER.error(\"token is expired\");\n        return false;\n      }\n\n      if (validatedToken.asMap().containsKey(rsaToken)) {\n        return accessController.isAllowed(microserviceInstanceCache.getOrCreate(\n            rsaToken.getServiceId(), rsaToken.getInstanceId()));\n      }\n\n      if (isValidToken(rsaToken) && !tokenExpired(rsaToken)) {\n        validatedToken.put(rsaToken, true);\n        return accessController.isAllowed(microserviceInstanceCache.getOrCreate(\n            rsaToken.getServiceId(), rsaToken.getInstanceId()));\n      }\n      return false;\n    } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | SignatureException e) {\n      LOGGER.error(\"verify error\", e);\n      return false;\n    }\n  }\n\n  public boolean isValidToken(RSAAuthenticationToken rsaToken)\n      throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {\n    String sign = rsaToken.getSign();\n    String content = rsaToken.plainToken();\n    String publicKey = getPublicKeyFromInstance(rsaToken.getInstanceId(), rsaToken.getServiceId());\n    return KeyPairUtils.verify(publicKey, sign, content);\n  }\n\n  protected int getExpiredTime() {\n    return 60 * 60 * 1000;\n  }\n\n  private boolean tokenExpired(RSAAuthenticationToken rsaToken) {\n    long generateTime = rsaToken.getGenerateTime();\n    long expired = generateTime + RSAAuthenticationToken.TOKEN_ACTIVE_TIME + 15 * 60 * 1000;\n    long now = System.currentTimeMillis();\n    return now > expired;\n  }\n\n  private String getPublicKeyFromInstance(String instanceId, String serviceId) {\n    DiscoveryInstance instances = microserviceInstanceCache.getOrCreate(serviceId, instanceId);\n    if (instances != null) {\n      return instances.getProperties().get(DefinitionConst.INSTANCE_PUBKEY_PRO);\n    } else {\n      LOGGER.error(\"not instance found {}-{}, maybe attack\", instanceId, serviceId);\n      return \"\";\n    }\n  }\n\n  @VisibleForTesting\n  Cache<RSAAuthenticationToken, Boolean> getValidatedToken() {\n    return validatedToken;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.authentication.AuthenticationConfiguration\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestAccessController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.authentication.provider.AccessController;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.MutablePropertySources;\n\npublic class TestAccessController {\n  ConfigurableEnvironment environment;\n\n  EnumerablePropertySource<?> propertySource;\n\n  @BeforeEach\n  public void tearDown() {\n    environment = Mockito.mock(ConfigurableEnvironment.class);\n    propertySource = Mockito.mock(EnumerablePropertySource.class);\n  }\n\n  @Test\n  public void testIsValidOfWhiteByServiceName() {\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.publicKey.accessControl.white.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.white.list1.category\",\n        \"servicecomb.publicKey.accessControl.white.list1.rule\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.propertyName\"))\n        .thenReturn(\"serviceName\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.rule\"))\n        .thenReturn(\"trust*\");\n\n    AccessController controller = new AccessController(environment);\n    DiscoveryInstance service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trustCustomer\");\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"nottrustCustomer\");\n    Assertions.assertFalse(controller.isAllowed(service));\n\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.rule\"))\n        .thenReturn(\"*trust\");\n    Map<String, Object> latest = new HashMap<>();\n    latest.put(\"servicecomb.publicKey.accessControl.white.list1.rule\", \"*trust\");\n    controller.onConfigurationChangedEvent(ConfigurationChangedEvent.createIncremental(latest, new HashMap<>()));\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"Customer_trust\");\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"Customer_trust_not\");\n    Assertions.assertFalse(controller.isAllowed(service));\n\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.rule\"))\n        .thenReturn(\"trust\");\n    latest.put(\"servicecomb.publicKey.accessControl.white.list1.rule\", \"trust\");\n    controller.onConfigurationChangedEvent(ConfigurationChangedEvent.createIncremental(latest, new HashMap<>()));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trust\");\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"Customer_trust\");\n    Assertions.assertFalse(controller.isAllowed(service));\n  }\n\n  @Test\n  public void testIsValidOfBlackByServiceName() {\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.publicKey.accessControl.black.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.black.list1.category\",\n        \"servicecomb.publicKey.accessControl.black.list1.rule\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.propertyName\"))\n        .thenReturn(\"serviceName\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.rule\"))\n        .thenReturn(\"trust*\");\n\n    AccessController controller = new AccessController(environment);\n\n    DiscoveryInstance service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trustCustomer\");\n    Assertions.assertFalse(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"nottrustCustomer\");\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.rule\"))\n        .thenReturn(\"*trust\");\n    Map<String, Object> latest = new HashMap<>();\n    latest.put(\"servicecomb.publicKey.accessControl.black.list1.rule\", \"*trust\");\n    controller.onConfigurationChangedEvent(ConfigurationChangedEvent.createIncremental(latest, new HashMap<>()));\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"Customer_trust\");\n    Assertions.assertFalse(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"Customer_trust_not\");\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.rule\"))\n        .thenReturn(\"trust\");\n    latest = new HashMap<>();\n    latest.put(\"servicecomb.publicKey.accessControl.black.list1.rule\", \"trust\");\n    controller.onConfigurationChangedEvent(ConfigurationChangedEvent.createIncremental(latest, new HashMap<>()));\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trust\");\n    Assertions.assertFalse(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"Customer_trust\");\n    Assertions.assertTrue(controller.isAllowed(service));\n  }\n\n  @Test\n  public void testIsValidOfBlackAndWhiteByServiceName() {\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.publicKey.accessControl.black.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.black.list1.category\",\n        \"servicecomb.publicKey.accessControl.black.list1.rule\",\n        \"servicecomb.publicKey.accessControl.white.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.white.list1.category\",\n        \"servicecomb.publicKey.accessControl.white.list1.rule\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.propertyName\"))\n        .thenReturn(\"serviceName\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.rule\"))\n        .thenReturn(\"trust*\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.propertyName\"))\n        .thenReturn(\"serviceName\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.rule\"))\n        .thenReturn(\"*hacker\");\n\n    AccessController controller = new AccessController(environment);\n    DiscoveryInstance service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trustCustomer\");\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trustCustomerhacker\");\n    Assertions.assertFalse(controller.isAllowed(service));\n  }\n\n  @Test\n  public void testIsValidOfBlackByProperties() {\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.publicKey.accessControl.black.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.black.list1.category\",\n        \"servicecomb.publicKey.accessControl.black.list1.rule\",\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.propertyName\"))\n        .thenReturn(\"tag\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.rule\"))\n        .thenReturn(\"test\");\n\n    AccessController controller = new AccessController(environment);\n    DiscoveryInstance service = Mockito.mock(DiscoveryInstance.class);\n    Map<String, String> map = new HashMap<>();\n    map.put(\"tag\", \"test\");\n    Mockito.when(service.getProperties()).thenReturn(map);\n\n    Assertions.assertFalse(controller.isAllowed(service));\n\n    map.put(\"tag\", \"testa\");\n    Mockito.when(service.getProperties()).thenReturn(map);\n    Assertions.assertTrue(controller.isAllowed(service));\n  }\n\n  @Test\n  public void testIsValidOfWhiteByProperties() {\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.publicKey.accessControl.white.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.white.list1.category\",\n        \"servicecomb.publicKey.accessControl.white.list1.rule\",\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.propertyName\"))\n        .thenReturn(\"tag\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.rule\"))\n        .thenReturn(\"test\");\n\n    AccessController controller = new AccessController(environment);\n    DiscoveryInstance service = Mockito.mock(DiscoveryInstance.class);\n    Map<String, String> map = new HashMap<>();\n    map.put(\"tag\", \"test\");\n    Mockito.when(service.getProperties()).thenReturn(map);\n    Assertions.assertTrue(controller.isAllowed(service));\n\n    map.put(\"tag\", \"testa\");\n    Mockito.when(service.getProperties()).thenReturn(map);\n    Assertions.assertFalse(controller.isAllowed(service));\n  }\n\n  @Test\n  public void testIsValidOfBlackAndWhiteByServiceNameAndVersion() {\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {\n        \"servicecomb.publicKey.accessControl.black.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.black.list1.category\",\n        \"servicecomb.publicKey.accessControl.black.list1.rule\",\n        \"servicecomb.publicKey.accessControl.white.list1.propertyName\",\n        \"servicecomb.publicKey.accessControl.white.list1.category\",\n        \"servicecomb.publicKey.accessControl.white.list1.rule\"\n    });\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.propertyName\"))\n        .thenReturn(\"serviceName\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.white.list1.rule\"))\n        .thenReturn(\"trust*\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.propertyName\"))\n        .thenReturn(\"version\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.category\"))\n        .thenReturn(\"property\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.black.list1.rule\"))\n        .thenReturn(\"0.0.1\");\n\n    AccessController controller = new AccessController(environment);\n    DiscoveryInstance service = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(service.getServiceName()).thenReturn(\"trustCustomer\");\n    Mockito.when(service.getVersion()).thenReturn(\"0.0.1\");\n\n    Assertions.assertFalse(controller.isAllowed(service));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestAuthenticationBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.mockito.ArgumentMatchers.any;\nimport static org.mockito.ArgumentMatchers.eq;\nimport static org.mockito.Mockito.times;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.core.BootListener.BootEvent;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.token.Keypair4Auth;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestAuthenticationBootListener {\n  private SCBEngine engine;\n\n  private Environment environment;\n\n  @BeforeEach\n  public void setUp() {\n    environment = Mockito.mock(Environment.class);\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keyGeneratorAlgorithm\", \"RSA\"))\n        .thenReturn(\"RSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.signAlgorithm\", \"SHA256withRSA\"))\n        .thenReturn(\"SHA256withRSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keySize\", int.class, 2048))\n        .thenReturn(2048);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION))\n        .thenReturn(BootStrapProperties.DEFAULT_APPLICATION);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_NAME);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_ENVIRONMENT))\n        .thenReturn(BootStrapProperties.DEFAULT_MICROSERVICE_ENVIRONMENT);\n\n    engine = SCBBootstrap.createSCBEngineForTest(environment);\n    engine.run();\n  }\n\n  @AfterEach\n  public void teardown() {\n    engine.destroy();\n  }\n\n  @Test\n  public void testGenerateRSAKey() {\n    RegistrationManager registrationManager = Mockito.mock(RegistrationManager.class);\n    AuthenticationBootListener authenticationBootListener = new AuthenticationBootListener();\n    authenticationBootListener.setRegistrationManager(registrationManager);\n    BootEvent bootEvent = new BootEvent();\n    bootEvent.setEventType(BootListener.EventType.BEFORE_REGISTRY);\n    authenticationBootListener.onBootEvent(bootEvent);\n    Assertions.assertNotNull(Keypair4Auth.INSTANCE.getPrivateKey());\n    Assertions.assertNotNull(Keypair4Auth.INSTANCE.getPublicKey());\n  }\n\n  @Test\n  public void testMicroserviceInstancePublicKey() {\n    RegistrationManager registrationManager = Mockito.mock(RegistrationManager.class);\n    AuthenticationBootListener authenticationBootListener = new AuthenticationBootListener();\n    authenticationBootListener.setRegistrationManager(registrationManager);\n    BootEvent bootEvent = new BootEvent();\n    bootEvent.setEventType(BootListener.EventType.BEFORE_REGISTRY);\n\n    authenticationBootListener.onBootEvent(bootEvent);\n\n    Mockito.verify(registrationManager, times(1))\n        .addProperty(eq(DefinitionConst.INSTANCE_PUBKEY_PRO), any(String.class));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/TestRSAAuthenticationToken.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\n\nimport java.security.InvalidKeyException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.SignatureException;\nimport java.security.spec.InvalidKeySpecException;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\n\npublic class TestRSAAuthenticationToken {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void setUpClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keyGeneratorAlgorithm\", \"RSA\"))\n        .thenReturn(\"RSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.signAlgorithm\", \"SHA256withRSA\"))\n        .thenReturn(\"SHA256withRSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keySize\", int.class, 2048))\n        .thenReturn(2048);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n  }\n\n  @Test\n  public void testRSAAuthenticationToken()\n      throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException {\n    String tokenstr =\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\";\n    RSAAuthenticationToken token = RSAAuthenticationToken.fromStr(tokenstr);\n    String contents = token.plainToken();\n    Assertions.assertEquals(\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ\",\n        contents);\n    String sign = token.getSign();\n    Assertions.assertEquals(\n        \"WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\",\n        sign);\n    String pubKey =\n        \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxKl5TNUTec7fL2degQcCk6vKf3c0wsfNK5V6elKzjWxm0MwbRj/UeR20VSnicBmVIOWrBS9LiERPPvjmmWUOSS2vxwr5XfhBhZ07gCAUNxBOTzgMo5nE45DhhZu5Jzt5qSV6o10Kq7+fCCBlDZ1UoWxZceHkUt5AxcrhEDulFjQIDAQAB\";\n    Assertions.assertTrue(KeyPairUtils.verify(pubKey, sign, contents));\n  }\n\n\n  @Test\n  public void testRSAAuthenticationTokenError() {\n    String tokenstr =\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\";\n    RSAAuthenticationToken token = RSAAuthenticationToken.fromStr(tokenstr);\n    Assertions.assertNull(token);\n  }\n\n\n  @Test\n  public void testEqual() {\n    String tokenstr =\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\";\n    RSAAuthenticationToken token = RSAAuthenticationToken.fromStr(tokenstr);\n    Assertions.assertNotEquals(token, null);\n    RSAAuthenticationToken token2 = RSAAuthenticationToken.fromStr(\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk\");\n    Assertions.assertNotEquals(token2, token);\n\n    RSAAuthenticationToken token3 = RSAAuthenticationToken.fromStr(\n        \"e8a0a4b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk\");\n    Assertions.assertNotEquals(token3, token);\n\n    RSAAuthenticationToken token4 = RSAAuthenticationToken.fromStr(\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\");\n    Assertions.assertEquals(token4, token);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/provider/TestPathCheckUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.provider;\n\nimport static org.junit.jupiter.api.Assertions.assertTrue;\nimport static org.junit.jupiter.api.Assertions.assertFalse;\nimport static org.mockito.Mockito.when;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.servers.Server;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class TestPathCheckUtils {\n  private static final String KEY_INCLUDE_PATH = \"servicecomb.publicKey.accessControl.includePathPatterns\";\n\n  private static final String KEY_EXCLUDE_PATH = \"servicecomb.publicKey.accessControl.excludePathPatterns\";\n\n  private static final String BASE_PATH = \"/api/v1\";\n\n  private Environment environment;\n\n  private OpenAPI swagger;\n\n  @BeforeEach\n  public void setUp() {\n    environment = Mockito.mock(Environment.class);\n    swagger = new OpenAPI();\n    swagger.setServers(new ArrayList<>());\n    swagger.getServers().add(new Server().url(BASE_PATH));\n  }\n\n  @Test\n  public void testExcludePathWithBasePathAndExactMatch() {\n    String operationPath = \"/public\";\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(BASE_PATH + operationPath);\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, operationPath);\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for excluded path with exact match\");\n  }\n\n  @Test\n  public void testExcludePathWithBasePathAndWildcard() {\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(BASE_PATH + \"/public/*\");\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/public/test\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for excluded path with wildcard\");\n\n    fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/public/nested/path\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for excluded nested path with wildcard\");\n  }\n\n  @Test\n  public void testIncludePathWithBasePath() {\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(\"\");\n    when(environment.getProperty(KEY_INCLUDE_PATH, \"\")).thenReturn(BASE_PATH + \"/private/*\");\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/private/resource\");\n    assertFalse(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should require auth for included path\");\n\n    fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/public/resource\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for non-included path\");\n  }\n\n  @Test\n  public void testExcludeOverrideIncludePath() {\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(BASE_PATH + \"/resource\");\n    when(environment.getProperty(KEY_INCLUDE_PATH, \"\")).thenReturn(BASE_PATH + \"/*\");\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/resource\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Exclude patterns should override include patterns\");\n  }\n\n  @Test\n  public void testMultipleExcludePaths() {\n    List<String> operationPaths = List.of(\"/public\", \"/health\", \"/metrics/*\");\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(concatPath(BASE_PATH, operationPaths));\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/public\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for first exclude path\");\n\n    fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/health\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for second exclude path\");\n\n    fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/metrics/jvm\");\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth for wildcard exclude path\");\n  }\n\n  @Test\n  public void testDifferentBasePath() {\n    String basePath = \"/different/base\";\n    String publicOperationPath = \"/public\";\n    String privateOperationPath = \"/private\";\n    swagger.getServers().clear();\n    swagger.getServers().add(new Server().url(basePath));\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(basePath + publicOperationPath);\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, publicOperationPath);\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth with different base path\");\n\n    fullPath = SwaggerUtils.concatAbsolutePath(swagger, privateOperationPath);\n    assertFalse(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should require auth for non-excluded path with different base path\");\n  }\n\n  @Test\n  public void testNoBasePath() {\n    String operationPath = \"/public\";\n    swagger.setServers(null);\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(operationPath);\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, operationPath);\n    assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should not require auth when no base path is set\");\n  }\n\n  @Test\n  public void testEmptyConfiguration() {\n    when(environment.getProperty(KEY_EXCLUDE_PATH, \"\")).thenReturn(\"\");\n    when(environment.getProperty(KEY_INCLUDE_PATH, \"\")).thenReturn(\"\");\n\n    String fullPath = SwaggerUtils.concatAbsolutePath(swagger, \"/any/path\");\n    assertFalse(PathCheckUtils.isNotRequiredAuth(fullPath, environment),\n        \"Should require auth by default when no patterns are configured\");\n  }\n\n  private String concatPath(String basePath, List<String> paths) {\n    return paths.stream().map(path -> basePath + path).collect(Collectors.joining(\",\"));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/provider/TestProviderTokenManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.authentication.provider;\n\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.mockito.ArgumentMatchers.any;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.authentication.RSAAuthenticationToken;\nimport org.apache.servicecomb.authentication.consumer.ConsumerTokenManager;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairEntry;\nimport org.apache.servicecomb.foundation.common.utils.KeyPairUtils;\nimport org.apache.servicecomb.foundation.token.Keypair4Auth;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.apache.servicecomb.registry.discovery.MicroserviceInstanceCache;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.Environment;\nimport org.springframework.core.env.MutablePropertySources;\n\nimport com.google.common.cache.Cache;\n\npublic class TestProviderTokenManager {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void setUpClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keyGeneratorAlgorithm\", \"RSA\"))\n        .thenReturn(\"RSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.signAlgorithm\", \"SHA256withRSA\"))\n        .thenReturn(\"SHA256withRSA\");\n    Mockito.when(environment.getProperty(\"servicecomb.publicKey.accessControl.keySize\", int.class, 2048))\n        .thenReturn(2048);\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n  }\n\n  @BeforeEach\n  public void setUp() {\n  }\n\n  @AfterEach\n  public void teardown() {\n  }\n\n  @Test\n  public void testTokenExpired() {\n    String tokenStr =\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\";\n    ProviderTokenManager tokenManager = new ProviderTokenManager();\n    DiscoveryInstance microserviceInstance = Mockito.mock(DiscoveryInstance.class);\n    Map<String, String> properties = new HashMap<>();\n    Mockito.when(microserviceInstance.getProperties()).thenReturn(properties);\n    properties.put(DefinitionConst.INSTANCE_PUBKEY_PRO,\n        \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxKl5TNUTec7fL2degQcCk6vKf3c0wsfNK5V6elKzjWxm0MwbRj/UeR20VSnicBmVIOWrBS9LiERPPvjmmWUOSS2vxwr5XfhBhZ07gCAUNxBOTzgMo5nE45DhhZu5Jzt5qSV6o10Kq7+fCCBlDZ1UoWxZceHkUt5AxcrhEDulFjQIDAQAB\");\n    Assertions.assertFalse(tokenManager.valid(tokenStr));\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void testTokenExpiredRemoveInstance() throws Exception {\n\n    String tokenStr =\n        \"e8a04b54cf2711e7b701286ed488fc20@c8636e5acf1f11e7b701286ed488fc20@1511315597475@9t0tp8ce80SUM5ts6iRGjFJMvCdQ7uvhpyh0RM7smKm3p4wYOrojr4oT1Pnwx7xwgcgEFbQdwPJxIMfivpQ1rHGqiLp67cjACvJ3Ke39pmeAVhybsLADfid6oSjscFaJ@WBYouF6hXYrXzBA31HC3VX8Bw9PNgJUtVqOPAaeW9ye3q/D7WWb0M+XMouBIWxWY6v9Un1dGu5Rkjlx6gZbnlHkb2VO8qFR3Y6lppooWCirzpvEBRjlJQu8LPBur0BCfYGq8XYrEZA2NU6sg2zXieqCSiX6BnMnBHNn4cR9iZpk=\";\n    RSAAuthenticationToken token = Mockito.spy(RSAAuthenticationToken.fromStr(tokenStr));\n    ProviderTokenManager tokenManager = Mockito.spy(new ProviderTokenManager() {\n      @Override\n      protected int getExpiredTime() {\n        return 500;\n      }\n    });\n    ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    tokenManager.setAccessController(new AccessController(environment));\n    MicroserviceInstanceCache microserviceInstanceCache = Mockito.mock(MicroserviceInstanceCache.class);\n    DiscoveryInstance microserviceInstance = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(microserviceInstance.getInstanceId()).thenReturn(\"\");\n    Map<String, String> properties = new HashMap<>();\n    Mockito.when(microserviceInstance.getProperties()).thenReturn(properties);\n    Mockito.when(microserviceInstanceCache.getOrCreate(any(String.class), any(String.class)))\n        .thenReturn(microserviceInstance);\n    tokenManager.setMicroserviceInstanceCache(microserviceInstanceCache);\n    try (MockedStatic<RSAAuthenticationToken> rsaAuthenticationTokenMockedStatic = Mockito.mockStatic(\n        RSAAuthenticationToken.class)) {\n      rsaAuthenticationTokenMockedStatic.when(() -> RSAAuthenticationToken.fromStr(tokenStr)).thenReturn(token);\n      Mockito.when(token.getGenerateTime()).thenReturn(System.currentTimeMillis());\n      Mockito.doReturn(true).when(tokenManager).isValidToken(token);\n      Assertions.assertTrue(tokenManager.valid(tokenStr));\n\n      Cache<RSAAuthenticationToken, Boolean> cache = tokenManager\n          .getValidatedToken();\n      Assertions.assertTrue(cache.asMap().containsKey(token));\n\n      Thread.sleep(1000);\n      Assertions.assertFalse(cache.asMap().containsKey(token));\n    }\n  }\n\n  @Test\n  public void testTokenFromValidatePool() {\n    KeyPairEntry keyPairEntry = KeyPairUtils.generateALGKeyPair();\n    Keypair4Auth.INSTANCE.setPrivateKey(keyPairEntry.getPrivateKey());\n    Keypair4Auth.INSTANCE.setPublicKey(keyPairEntry.getPublicKey());\n    Keypair4Auth.INSTANCE.setPublicKeyEncoded(keyPairEntry.getPublicKeyEncoded());\n    String serviceId = \"test\";\n    String instanceId = \"test\";\n    ConsumerTokenManager consumerTokenManager = new ConsumerTokenManager();\n\n    ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_NAME)).thenReturn(\"test\");\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION)).thenReturn(\"test\");\n    consumerTokenManager.setEnvironment(environment);\n    DiscoveryInstance microserviceInstance = Mockito.mock(DiscoveryInstance.class);\n    Mockito.when(microserviceInstance.getInstanceId()).thenReturn(instanceId);\n    Map<String, String> properties = new HashMap<>();\n    Mockito.when(microserviceInstance.getProperties()).thenReturn(properties);\n    properties.put(DefinitionConst.INSTANCE_PUBKEY_PRO, keyPairEntry.getPublicKeyEncoded());\n    MicroserviceInstanceCache microserviceInstanceCache = Mockito.mock(MicroserviceInstanceCache.class);\n    Mockito.when(microserviceInstanceCache.getOrCreate(serviceId, instanceId)).thenReturn(microserviceInstance);\n    //Test Consumer first create token\n    String token = consumerTokenManager.getToken();\n    Assertions.assertNotNull(token);\n    // use cache token\n    Assertions.assertEquals(token, consumerTokenManager.getToken());\n    ProviderTokenManager rsaProviderTokenManager = new ProviderTokenManager();\n\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    rsaProviderTokenManager.setAccessController(new AccessController(environment));\n\n    rsaProviderTokenManager.setMicroserviceInstanceCache(microserviceInstanceCache);\n    //first validate need to verify use RSA\n    Assertions.assertTrue(rsaProviderTokenManager.valid(token));\n    // second validate use validated pool\n    Assertions.assertTrue(rsaProviderTokenManager.valid(token));\n  }\n}\n"
  },
  {
    "path": "handlers/handler-publickey-auth/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  filter-chains:\n    consumer:\n      default: empty\n    producer:\n      default: empty\n"
  },
  {
    "path": "handlers/handler-router/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>handlers</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>handler-router</artifactId>\n  <name>Java Chassis::Handlers::Router</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-beans</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.guava</groupId>\n      <artifactId>guava</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.yaml</groupId>\n      <artifactId>snakeyaml</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>servicecomb-governance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "handlers/handler-router/src/main/java/org/apache/servicecomb/router/custom/RouterServerListFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.custom;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.governance.MatchType;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.loadbalance.ServerListFilterExt;\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\nimport org.apache.servicecomb.router.RouterFilter;\nimport org.apache.servicecomb.router.distribute.RouterDistributor;\n\npublic class RouterServerListFilter implements ServerListFilterExt {\n\n  private static final String ENABLE = \"servicecomb.router.type\";\n\n  private static final String TYPE_ROUTER = \"router\";\n\n  @SuppressWarnings(\"unchecked\")\n  private final RouterDistributor<ServiceCombServer> routerDistributor = BeanUtils\n      .getBean(RouterDistributor.class);\n\n  private final RouterFilter routerFilter = BeanUtils.getBean(RouterFilter.class);\n\n  @Override\n  public boolean enabled() {\n    return LegacyPropertyFactory.getStringProperty(ENABLE, \"\")\n        .equals(TYPE_ROUTER);\n  }\n\n  @Override\n  public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> list,\n      Invocation invocation) {\n    String targetServiceName = invocation.getMicroserviceName();\n    return routerFilter.getFilteredListOfServers(list, targetServiceName,\n        MatchType.createGovHttpRequest(invocation), routerDistributor);\n  }\n}\n"
  },
  {
    "path": "handlers/handler-router/src/main/java/org/apache/servicecomb/router/custom/ServiceCombRouterConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.custom;\n\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@ConditionalOnProperty(value = ServiceCombRouterConfiguration.ROUTER_ENABLED,\n    havingValue = \"true\", matchIfMissing = true)\npublic class ServiceCombRouterConfiguration {\n  public static final String ROUTER_PREFIX = \"servicecomb.router\";\n\n  public static final String ROUTER_ENABLED = ROUTER_PREFIX + \".enabled\";\n\n  @Bean\n  public ServiceCombRouterDistributor scbServiceCombRouterDistributor() {\n    return new ServiceCombRouterDistributor();\n  }\n}\n"
  },
  {
    "path": "handlers/handler-router/src/main/java/org/apache/servicecomb/router/custom/ServiceCombRouterDistributor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.router.custom;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\nimport org.apache.servicecomb.router.distribute.AbstractRouterDistributor;\n\npublic class ServiceCombRouterDistributor extends\n    AbstractRouterDistributor<ServiceCombServer> {\n\n  public ServiceCombRouterDistributor() {\n    init(\n        instance -> instance.getInstance().getVersion(),\n        instance -> instance.getInstance().getServiceName(),\n        instance -> {\n          Map<String, String> properties = new HashMap<>();\n          properties.putAll(instance.getInstance().getProperties());\n          return properties;\n        });\n  }\n}\n"
  },
  {
    "path": "handlers/handler-router/src/main/resources/META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.router.custom.RouterServerListFilter\n"
  },
  {
    "path": "handlers/handler-router/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.router.custom.ServiceCombRouterConfiguration\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>handlers</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>handler-tracing-zipkin</artifactId>\n  <name>Java Chassis::Handlers::Tracing Zipkin</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave-spring-beans</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave-context-slf4j</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.zipkin2</groupId>\n      <artifactId>zipkin</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.reporter2</groupId>\n      <artifactId>zipkin-sender-okhttp3</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.reporter2</groupId>\n      <artifactId>zipkin-reporter-brave</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpRequestParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\n\nimport brave.SpanCustomizer;\nimport brave.http.HttpRequest;\nimport brave.http.HttpRequestParser;\nimport brave.http.HttpTags;\nimport brave.propagation.TraceContext;\n\npublic record CustomHttpRequestParser() implements HttpRequestParser {\n  @Override\n  public void parse(HttpRequest req, TraceContext context, SpanCustomizer span) {\n    Invocation invocation = ((InvocationAware) req).getInvocation();\n    span.name(invocation.getInvocationQualifiedName());\n    HttpTags.METHOD.tag(req, context, span);\n    HttpTags.PATH.tag(req, context, span);\n    if (!invocation.isConsumer()) { // server or edge\n      HttpTags.ROUTE.tag(req, context, span);\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpResponseParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\n\nimport brave.SpanCustomizer;\nimport brave.Tags;\nimport brave.http.HttpResponse;\nimport brave.http.HttpResponseParser;\nimport brave.http.HttpTags;\nimport brave.propagation.TraceContext;\n\npublic record CustomHttpResponseParser() implements HttpResponseParser {\n  @Override\n  public void parse(HttpResponse response, TraceContext context, SpanCustomizer span) {\n    Invocation invocation = ((InvocationAware) response).getInvocation();\n    HttpTags.STATUS_CODE.tag(response, context, span);\n    if (response.error() != null) {\n      span.tag(Tags.ERROR.key(), response.error().getMessage());\n    }\n    if (!invocation.isProducer()) { // client or edge\n      span.tag(HttpTags.ROUTE.key(), response.route());\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientRequestWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\n\nimport brave.http.HttpClientRequest;\n\nclass HttpClientRequestWrapper extends HttpClientRequest implements InvocationAware {\n  private final Invocation invocation;\n\n  HttpClientRequestWrapper(Invocation invocation) {\n    this.invocation = invocation;\n  }\n\n  @Override\n  public void header(String name, String value) {\n    invocation.addContext(name, value);\n  }\n\n  @Override\n  public String method() {\n    return invocation.getOperationMeta().getHttpMethod();\n  }\n\n  @Override\n  public String route() {\n    return invocation.getEndpoint().getEndpoint();\n  }\n\n  @Override\n  public String path() {\n    return TracingConfiguration.createRequestPath(invocation);\n  }\n\n  @Override\n  public String url() {\n    return invocation.getInvocationQualifiedName();\n  }\n\n  @Override\n  public String header(String name) {\n    return invocation.getContext(name);\n  }\n\n  @Override\n  public Object unwrap() {\n    return invocation;\n  }\n\n  @Override\n  public Invocation getInvocation() {\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientResponseWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\nimport brave.http.HttpClientRequest;\nimport brave.http.HttpClientResponse;\n\nclass HttpClientResponseWrapper extends HttpClientResponse implements InvocationAware {\n  final HttpClientRequest request;\n\n  final Response response;\n\n  final Invocation invocation;\n\n  HttpClientResponseWrapper(Invocation invocation, Response response, HttpClientRequestWrapper request) {\n    this.response = response;\n    this.request = request;\n    this.invocation = invocation;\n  }\n\n  @Override\n  public int statusCode() {\n    return response.getStatusCode();\n  }\n\n  @Override\n  public Object unwrap() {\n    return response;\n  }\n\n  @Override\n  public HttpClientRequest request() {\n    return request;\n  }\n\n  @Override\n  public Throwable error() {\n    return response.isFailed() ? response.getResult() : null;\n  }\n\n  @Override\n  public Invocation getInvocation() {\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpServeRequestWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.Invocation;\n\nimport brave.http.HttpServerRequest;\n\nclass HttpServeRequestWrapper extends HttpServerRequest implements InvocationAware {\n  private final Invocation invocation;\n\n  HttpServeRequestWrapper(Invocation invocation) {\n    this.invocation = invocation;\n  }\n\n  @Override\n  public String method() {\n    return invocation.getOperationMeta().getHttpMethod();\n  }\n\n  @Override\n  public String path() {\n    return TracingConfiguration.createRequestPath(invocation);\n  }\n\n  @Override\n  public String url() {\n    return invocation.getInvocationQualifiedName();\n  }\n\n  @Override\n  public String route() {\n    return invocation.getRequestEx() != null ? invocation.getRequestEx().getRemoteAddr() : null;\n  }\n\n  @Override\n  public String header(String name) {\n    String result = invocation.getContext(name);\n    if (StringUtils.isEmpty(result) && invocation.getRequestEx() != null) {\n      result = invocation.getRequestEx().getHeader(name);\n    }\n    return result;\n  }\n\n  @Override\n  public Object unwrap() {\n    return invocation;\n  }\n\n  @Override\n  public Invocation getInvocation() {\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpServerResponseWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\nimport brave.http.HttpServerRequest;\nimport brave.http.HttpServerResponse;\n\nclass HttpServerResponseWrapper extends HttpServerResponse implements InvocationAware {\n  private final Response response;\n\n  private final HttpServerRequest request;\n\n  private final Invocation invocation;\n\n  HttpServerResponseWrapper(Invocation invocation, Response response, HttpServeRequestWrapper request) {\n    this.response = response;\n    this.request = request;\n    this.invocation = invocation;\n  }\n\n  @Override\n  public int statusCode() {\n    return response.getStatusCode();\n  }\n\n  @Override\n  public Object unwrap() {\n    return response;\n  }\n\n  @Override\n  public HttpServerRequest request() {\n    return request;\n  }\n\n  @Override\n  public Throwable error() {\n    return response.isFailed() ? response.getResult() : null;\n  }\n\n  @Override\n  public Invocation getInvocation() {\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/InvocationAware.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\n\npublic interface InvocationAware {\n  Invocation getInvocation();\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/LogSpanHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.tracing.zipkin;\n\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport brave.handler.MutableSpan;\nimport brave.handler.SpanHandler;\nimport brave.propagation.TraceContext;\n\npublic class LogSpanHandler extends SpanHandler {\n  private static final Logger LOGGER = LoggerFactory.getLogger(\"scb-trace\");\n\n  public boolean end(TraceContext context, MutableSpan span, Cause cause) {\n    if (!LOGGER.isInfoEnabled()) {\n      return false;\n    } else {\n      LOGGER.info(span.toString());\n      return true;\n    }\n  }\n\n  public String toString() {\n    return \"LogSpanHandler{name=scb-trace}\";\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/TracingConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_TRACING_COLLECTOR_ADDRESS;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_TRACING_COLLECTOR_API_V1;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_TRACING_COLLECTOR_API_V2;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_TRACING_COLLECTOR_API_VERSION;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_TRACING_COLLECTOR_PATH;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.DEFAULT_TRACING_COLLECTOR_ADDRESS;\n\nimport java.text.MessageFormat;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport brave.Tracing;\nimport brave.context.slf4j.MDCScopeDecorator;\nimport brave.http.HttpTracing;\nimport brave.propagation.CurrentTraceContext;\nimport brave.propagation.ThreadLocalCurrentTraceContext;\nimport zipkin2.Span;\nimport zipkin2.reporter.AsyncReporter;\nimport zipkin2.reporter.BytesMessageSender;\nimport zipkin2.reporter.Reporter;\nimport zipkin2.reporter.Sender;\nimport zipkin2.reporter.SpanBytesEncoder;\nimport zipkin2.reporter.brave.AsyncZipkinSpanHandler;\nimport zipkin2.reporter.okhttp3.OkHttpSender;\n\n@Configuration\n@ConditionalOnProperty(value = TracingConfiguration.TRACING_ENABLED,\n    havingValue = \"true\", matchIfMissing = true)\npublic class TracingConfiguration {\n  public static final String TRACING_PREFIX = \"servicecomb.tracing\";\n\n  public static final String TRACING_ENABLED = TRACING_PREFIX + \".enabled\";\n\n  public static final String TRACING_REPORTER_LOG_ENABLED = TRACING_PREFIX + \".reporter.log.enabled\";\n\n  public static final String TRACING_REPORTER_ZIPKIN_ENABLED = TRACING_PREFIX + \".reporter.zipkin.enabled\";\n\n  @Configuration\n  @ConditionalOnProperty(value = TracingConfiguration.TRACING_REPORTER_ZIPKIN_ENABLED,\n      havingValue = \"true\")\n  static class ZipkinReporterConfiguration {\n    @Bean\n    BytesMessageSender scbOkHttpSender(DynamicProperties dynamicProperties) {\n      String apiVersion = dynamicProperties.getStringProperty(CONFIG_TRACING_COLLECTOR_API_VERSION,\n          CONFIG_TRACING_COLLECTOR_API_V2).toLowerCase();\n      // use default value if the user set value is invalid\n      if (apiVersion.compareTo(CONFIG_TRACING_COLLECTOR_API_V1) != 0) {\n        apiVersion = CONFIG_TRACING_COLLECTOR_API_V2;\n      }\n\n      String path = MessageFormat.format(CONFIG_TRACING_COLLECTOR_PATH, apiVersion);\n      return OkHttpSender.create(\n          dynamicProperties.getStringProperty(\n                  CONFIG_TRACING_COLLECTOR_ADDRESS,\n                  DEFAULT_TRACING_COLLECTOR_ADDRESS)\n              .trim()\n              .replaceAll(\"/+$\", \"\")\n              .concat(path));\n    }\n\n    @Bean\n    Reporter<Span> scbZipkinReporter(DynamicProperties dynamicProperties, BytesMessageSender sender) {\n      String apiVersion = dynamicProperties.getStringProperty(CONFIG_TRACING_COLLECTOR_API_VERSION,\n          CONFIG_TRACING_COLLECTOR_API_V2).toLowerCase();\n      if (apiVersion.compareTo(CONFIG_TRACING_COLLECTOR_API_V1) == 0) {\n        return AsyncReporter.builder(sender).build(SpanBytesEncoder.JSON_V1);\n      }\n\n      return AsyncReporter.builder(sender).build();\n    }\n  }\n\n  @Bean\n  CurrentTraceContext scbCurrentTraceContext() {\n    return ThreadLocalCurrentTraceContext.newBuilder()\n        .addScopeDecorator(MDCScopeDecorator.newBuilder().build())\n        .build();\n  }\n\n  @Bean\n  Tracing scbTracing(@Autowired(required = false) Sender sender,\n      CurrentTraceContext currentTraceContext, Environment environment, DynamicProperties dynamicProperties) {\n    Tracing.Builder builder = Tracing.newBuilder()\n        .localServiceName(BootStrapProperties.readServiceName(environment))\n        .currentTraceContext(currentTraceContext); // puts trace IDs into logs\n    if (dynamicProperties.getBooleanProperty(TRACING_REPORTER_LOG_ENABLED, true)) {\n      builder.addSpanHandler(new LogSpanHandler());\n    }\n    if (dynamicProperties.getBooleanProperty(TRACING_REPORTER_ZIPKIN_ENABLED, false)) {\n      builder.addSpanHandler(AsyncZipkinSpanHandler.create(sender));\n    }\n    return builder.build();\n  }\n\n  @Bean\n  HttpTracing scbHttpTracing(Tracing tracing) {\n    return HttpTracing.newBuilder(tracing)\n        .clientRequestParser(new CustomHttpRequestParser())\n        .clientResponseParser(new CustomHttpResponseParser())\n        .serverRequestParser(new CustomHttpRequestParser())\n        .serverResponseParser(new CustomHttpResponseParser()).build();\n  }\n\n  @Bean\n  ZipkinTracingFilter scbZipkinTracingFilter() {\n    return new ZipkinTracingFilter();\n  }\n\n  public static String createRequestPath(Invocation invocation) {\n    URIEndpointObject address = (URIEndpointObject) invocation.getEndpoint().getAddress();\n    String urlPrefix = address.getFirst(DefinitionConst.URL_PREFIX);\n    RestOperationMeta swaggerRestOperation = invocation.getOperationMeta().getExtData(RestConst.SWAGGER_REST_OPERATION);\n    String path = (String) invocation.getHandlerContext().get(RestConst.REST_CLIENT_REQUEST_PATH);\n    if (path == null) {\n      try {\n        path = swaggerRestOperation.getPathBuilder().createRequestPath(invocation.getSwaggerArguments());\n      } catch (Exception e) {\n        path = invocation.getOperationMeta().getOperationPath();\n      }\n    }\n\n    if (StringUtils.isEmpty(urlPrefix) || path.startsWith(urlPrefix)) {\n      return path;\n    }\n\n    return urlPrefix + path;\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.eventbus.Subscribe;\n\nimport brave.Span;\nimport brave.http.HttpClientHandler;\nimport brave.http.HttpClientRequest;\nimport brave.http.HttpClientResponse;\nimport brave.http.HttpServerHandler;\nimport brave.http.HttpServerRequest;\nimport brave.http.HttpServerResponse;\nimport brave.http.HttpTracing;\n\npublic class ZipkinTracingFilter {\n  public static final String CONTEXT_TRACE_REQUEST = \"x-trace-request\";\n\n  public static final String CONTEXT_TRACE_HANDLER = \"x-trace-handler\";\n\n  public static final String CONTEXT_TRACE_SPAN = \"x-trace-span\";\n\n  public static final String CONTEXT_TRACE_EDGE_REQUEST = \"x-trace-edge-request\";\n\n  public static final String CONTEXT_TRACE_EDGE_HANDLER = \"x-trace-edge-handler\";\n\n  public static final String CONTEXT_TRACE_EDGE_SPAN = \"x-trace-edge-span\";\n\n  private HttpTracing httpTracing;\n\n  public ZipkinTracingFilter() {\n    EventManager.register(this);\n  }\n\n  @Autowired\n  public void setHttpTracing(HttpTracing httpTracing) {\n    this.httpTracing = httpTracing;\n  }\n\n  @Subscribe\n  public void onInvocationStartEvent(InvocationStartEvent event) {\n    Invocation invocation = event.getInvocation();\n\n    if (invocation.isProducer()) {\n      HttpServerHandler<HttpServerRequest, HttpServerResponse> handler = HttpServerHandler.create(httpTracing);\n      HttpServeRequestWrapper request = new HttpServeRequestWrapper(invocation);\n      Span span = handler.handleReceive(request);\n      invocation.addLocalContext(CONTEXT_TRACE_SPAN, span);\n      invocation.addLocalContext(CONTEXT_TRACE_HANDLER, handler);\n      invocation.addLocalContext(CONTEXT_TRACE_REQUEST, request);\n    } else if (invocation.isConsumer()) {\n      Span parentSpan = invocation.getLocalContext(CONTEXT_TRACE_SPAN);\n      HttpClientHandler<HttpClientRequest, HttpClientResponse> handler = HttpClientHandler.create(httpTracing);\n      HttpClientRequestWrapper request = new HttpClientRequestWrapper(invocation);\n      Span span = handler.handleSendWithParent(request, parentSpan == null ? null : parentSpan.context());\n      invocation.addLocalContext(CONTEXT_TRACE_HANDLER, handler);\n      invocation.addLocalContext(CONTEXT_TRACE_REQUEST, request);\n      invocation.addLocalContext(CONTEXT_TRACE_SPAN, span);\n    } else {\n      // edge as server\n      HttpServerHandler<HttpServerRequest, HttpServerResponse> serverHandler = HttpServerHandler.create(httpTracing);\n      HttpServeRequestWrapper serverRequest = new HttpServeRequestWrapper(invocation);\n      Span serverSpan = serverHandler.handleReceive(serverRequest);\n      invocation.addLocalContext(CONTEXT_TRACE_EDGE_SPAN, serverSpan);\n      invocation.addLocalContext(CONTEXT_TRACE_EDGE_HANDLER, serverHandler);\n      invocation.addLocalContext(CONTEXT_TRACE_EDGE_REQUEST, serverRequest);\n\n      // edge as client\n      HttpClientHandler<HttpClientRequest, HttpClientResponse> clientHandler = HttpClientHandler.create(httpTracing);\n      HttpClientRequestWrapper clientRequest = new HttpClientRequestWrapper(invocation);\n      Span clientSpan = clientHandler.handleSendWithParent(clientRequest, serverSpan.context());\n      invocation.addLocalContext(CONTEXT_TRACE_HANDLER, clientHandler);\n      invocation.addLocalContext(CONTEXT_TRACE_REQUEST, clientRequest);\n      invocation.addLocalContext(CONTEXT_TRACE_SPAN, clientSpan);\n    }\n  }\n\n  @Subscribe\n  public void onInvocationFinishEvent(InvocationFinishEvent event) {\n    Invocation invocation = event.getInvocation();\n    if (invocation.isProducer()) {\n      HttpServerHandler<HttpServerRequest, HttpServerResponse> handler\n          = invocation.getLocalContext(CONTEXT_TRACE_HANDLER);\n      Span span = invocation.getLocalContext(CONTEXT_TRACE_SPAN);\n      handler.handleSend(new HttpServerResponseWrapper(invocation, event.getResponse(),\n          invocation.getLocalContext(CONTEXT_TRACE_REQUEST)), span);\n    } else if (invocation.isConsumer()) {\n      HttpClientHandler<HttpClientRequest, HttpClientResponse> handler\n          = invocation.getLocalContext(CONTEXT_TRACE_HANDLER);\n      Span span = invocation.getLocalContext(CONTEXT_TRACE_SPAN);\n      handler.handleReceive(new HttpClientResponseWrapper(invocation, event.getResponse(),\n          invocation.getLocalContext(CONTEXT_TRACE_REQUEST)), span);\n    } else {\n      // edge as client\n      HttpClientHandler<HttpClientRequest, HttpClientResponse> clientHandler\n          = invocation.getLocalContext(CONTEXT_TRACE_HANDLER);\n      Span clientSpan = invocation.getLocalContext(CONTEXT_TRACE_SPAN);\n      clientHandler.handleReceive(new HttpClientResponseWrapper(invocation, event.getResponse(),\n          invocation.getLocalContext(CONTEXT_TRACE_REQUEST)), clientSpan);\n      // edge as server\n      HttpServerHandler<HttpServerRequest, HttpServerResponse> serverHandler\n          = invocation.getLocalContext(CONTEXT_TRACE_EDGE_HANDLER);\n      Span serverSpan = invocation.getLocalContext(CONTEXT_TRACE_EDGE_SPAN);\n      serverHandler.handleSend(new HttpServerResponseWrapper(invocation, event.getResponse(),\n          invocation.getLocalContext(CONTEXT_TRACE_EDGE_REQUEST)), serverSpan);\n    }\n  }\n}\n"
  },
  {
    "path": "handlers/handler-tracing-zipkin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.tracing.zipkin.TracingConfiguration\n"
  },
  {
    "path": "handlers/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>handlers</artifactId>\n  <name>Java Chassis::Handlers</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>handler-tracing-zipkin</module>\n    <module>handler-flowcontrol-qps</module>\n    <module>handler-loadbalance</module>\n    <module>handler-fault-injection</module>\n    <module>handler-publickey-auth</module>\n    <module>handler-router</module>\n    <module>handler-governance</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "huawei-cloud/darklaunch/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>huawei-cloud</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>darklaunch</artifactId>\n  <name>Java Chassis::darklaunch</name>\n\n<dependencies>\n  <dependency>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>foundation-registry</artifactId>\n  </dependency>\n  <dependency>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>registry-service-center</artifactId>\n  </dependency>\n  <dependency>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>handler-loadbalance</artifactId>\n  </dependency>\n</dependencies>\n</project>\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/DarklaunchRule.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch;\n\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.darklaunch.oper.ConditionFactory;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class DarklaunchRule {\n  private static final Logger LOG = LoggerFactory.getLogger(DarklaunchRule.class);\n\n  public static final String PROP_VERSION = \"version\";\n\n  public static final String PROP_TAG = \"tag\";\n\n  public static final String PROP_PERCENT = \"rate\";\n\n  private PolicyType policyType;\n\n  private final List<DarklaunchRuleItem> ruleItems = new ArrayList<>();\n\n  public static DarklaunchRule parse(String ruleStr) {\n    if (StringUtils.isEmpty(ruleStr)) {\n      return null;\n    }\n\n    try {\n      DarklaunchRuleJson ruleJson = JsonUtils\n          .readValue(ruleStr.getBytes(StandardCharsets.UTF_8), DarklaunchRuleJson.class);\n      DarklaunchRule rule = new DarklaunchRule(ruleJson.getPolicyType());\n      for (DarklaunchRuleItemJson itemJson : ruleJson.getRuleItems()) {\n        DarklaunchRuleItem item = new DarklaunchRuleItem(itemJson.getGroupName());\n        item.setGroupCondition(\n            ConditionFactory.buildCondition(itemJson.getGroupCondition(), itemJson.isCaseInsensitive())\n        );\n        if (rule.getPolicyType().equals(PolicyType.RULE)) {\n          item.setPolicyCondition(\n              ConditionFactory.buildCondition(itemJson.getPolicyCondition(), itemJson.isCaseInsensitive()));\n        } else {\n          item.setPolicyCondition(ConditionFactory.buildRateCondition(itemJson.getPolicyCondition()));\n        }\n        rule.addRuleItem(item);\n      }\n      return rule;\n    } catch (Exception e) {\n      LOG.warn(\"Invalid configuration: rule={},message={}\", ruleStr, e.getMessage());\n    }\n    return null;\n  }\n\n  public DarklaunchRule(PolicyType policyType) {\n    this.policyType = policyType;\n  }\n\n  public PolicyType getPolicyType() {\n    return policyType;\n  }\n\n  public void setPolicyType(PolicyType policyType) {\n    this.policyType = policyType;\n  }\n\n  public List<DarklaunchRuleItem> getRuleItems() {\n    return ruleItems;\n  }\n\n  public void addRuleItem(DarklaunchRuleItem ruleItem) {\n    this.ruleItems.add(ruleItem);\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/DarklaunchRuleItem.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.darklaunch.oper.Condition;\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\n\npublic class DarklaunchRuleItem {\n  private String groupName;\n\n  private Condition groupCondition;\n\n  private Condition policyCondition;\n\n  private final List<ServiceCombServer> servers = new ArrayList<>();\n\n  public DarklaunchRuleItem(String groupName) {\n    this.groupName = groupName;\n  }\n\n  public String getGroupName() {\n    return groupName;\n  }\n\n  public void setGroupName(String groupName) {\n    this.groupName = groupName;\n  }\n\n  public Condition getGroupCondition() {\n    return groupCondition;\n  }\n\n  public void setGroupCondition(Condition groupCondition) {\n    this.groupCondition = groupCondition;\n  }\n\n  public Condition getPolicyCondition() {\n    return policyCondition;\n  }\n\n  public void setPolicyCondition(Condition policyCondition) {\n    this.policyCondition = policyCondition;\n  }\n\n  public List<ServiceCombServer> getServers() {\n    return this.servers;\n  }\n\n  public void addServer(ServiceCombServer server) {\n    this.servers.add(server);\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/DarklaunchRuleItemJson.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class DarklaunchRuleItemJson {\n  private String groupName;\n\n  private String groupCondition;\n\n  private String policyCondition;\n\n  private boolean caseInsensitive;\n\n  public String getGroupName() {\n    return groupName;\n  }\n\n  public void setGroupName(String groupName) {\n    this.groupName = groupName;\n  }\n\n  public String getGroupCondition() {\n    return groupCondition;\n  }\n\n  public void setGroupCondition(String groupCondition) {\n    this.groupCondition = groupCondition;\n  }\n\n  public String getPolicyCondition() {\n    return policyCondition;\n  }\n\n  public void setPolicyCondition(String policyCondition) {\n    this.policyCondition = policyCondition;\n  }\n\n  public boolean isCaseInsensitive() {\n    return caseInsensitive;\n  }\n\n  public void setCaseInsensitive(boolean caseInsensitive) {\n    this.caseInsensitive = caseInsensitive;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/DarklaunchRuleJson.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class DarklaunchRuleJson {\n  private PolicyType policyType;\n\n  private List<DarklaunchRuleItemJson> ruleItems = new ArrayList<>();\n\n  public PolicyType getPolicyType() {\n    return policyType;\n  }\n\n  public void setPolicyType(PolicyType policyType) {\n    this.policyType = policyType;\n  }\n\n  public List<DarklaunchRuleItemJson> getRuleItems() {\n    return ruleItems;\n  }\n\n  public void setRuleItems(List<DarklaunchRuleItemJson> ruleItems) {\n    this.ruleItems = ruleItems;\n  }\n\n  public void addRuleItem(DarklaunchRuleItemJson ruleItem) {\n    this.ruleItems.add(ruleItem);\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/DarklaunchServerListFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.loadbalance.ServerListFilterExt;\nimport org.apache.servicecomb.loadbalance.ServiceCombServer;\n\npublic class DarklaunchServerListFilter implements ServerListFilterExt {\n\n  private static final String POLICY_SERVICE_COMB = \"servicecomb.darklaunch.policy.%s\";\n\n  private static final int HUNDRED = 100;\n\n  private final Random random = new Random();\n\n  public DarklaunchServerListFilter() {\n  }\n\n  @Override\n  public int getOrder() {\n    return HUNDRED;\n  }\n\n  @Override\n  public boolean enabled() {\n    return true;\n  }\n\n  @Override\n  public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList, Invocation invocation) {\n    DarklaunchRule rule = DarklaunchRule.parse(LegacyPropertyFactory\n        .getStringProperty(String.format(POLICY_SERVICE_COMB, invocation.getMicroserviceName())));\n    if (rule == null) {\n      return serverList;\n    }\n    List<ServiceCombServer> defaultGroup = new ArrayList<>();\n    divideServerGroup(serverList, rule, defaultGroup);\n\n    if (rule.getPolicyType() == PolicyType.RULE) {\n      for (DarklaunchRuleItem item : rule.getRuleItems()) {\n        List<ServiceCombServer> ruleServers = getRuleServers(invocation, item, defaultGroup);\n        if (ruleServers != null) {\n          return ruleServers;\n        }\n      }\n    } else {\n      int rate = random.nextInt(HUNDRED);\n      for (DarklaunchRuleItem item : rule.getRuleItems()) {\n        item.getPolicyCondition().setActual(DarklaunchRule.PROP_PERCENT, rate);\n        if (item.getPolicyCondition().match()) {\n          if (item.getServers().isEmpty()) {\n            return defaultGroup;\n          }\n          return item.getServers();\n        }\n        rate = rate - Integer.parseInt(item.getPolicyCondition().expected());\n      }\n    }\n    return defaultGroup;\n  }\n\n  private List<ServiceCombServer> getRuleServers(Invocation invocation, DarklaunchRuleItem item,\n      List<ServiceCombServer> defaultGroup) {\n    invocation.getSwaggerArguments().forEach((k, v) -> item.getPolicyCondition().setActual(k, v));\n    for (String key : invocation.getContext().keySet()) {\n      item.getPolicyCondition().setActual(key, invocation.getContext(key));\n    }\n    if (item.getPolicyCondition().match()) {\n      if (item.getServers().isEmpty()) {\n        return defaultGroup;\n      }\n      return item.getServers();\n    }\n    return null;\n  }\n\n  private void divideServerGroup(List<ServiceCombServer> serverList, DarklaunchRule rule,\n      List<ServiceCombServer> defaultGroup) {\n    for (ServiceCombServer server : serverList) {\n      boolean hasGroup = false;\n      for (DarklaunchRuleItem item : rule.getRuleItems()) {\n        item.getGroupCondition()\n            .setActual(DarklaunchRule.PROP_VERSION, server.getInstance().getVersion());\n        if (item.getGroupCondition().match()) {\n          item.addServer(server);\n          hasGroup = true;\n        }\n      }\n      if (!hasGroup) {\n        defaultGroup.add(server);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/PolicyType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch;\n\npublic enum PolicyType {\n  RULE,\n  RATE\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/AbstractCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic abstract class AbstractCondition implements Condition {\n  private final String key;\n\n  private final String expected;\n\n  private Object actual;\n\n  private SupportedType type = SupportedType.UNKNOWN;\n\n  public AbstractCondition(String key, String expected) {\n    assertValueNotNull(key, expected);\n    this.key = key;\n    this.expected = expected;\n  }\n\n  @Override\n  public String key() {\n    return this.key;\n  }\n\n  @Override\n  public String expected() {\n    return this.expected;\n  }\n\n  @Override\n  public void setActual(String key, Object actual) {\n    assertValueNotNull(key, \"\");\n    if (this.key.equals(key)) {\n      if (actual instanceof String) {\n        this.type = SupportedType.STRING;\n      } else if (actual instanceof Number) {\n        this.type = SupportedType.NUMBER;\n      }\n      this.actual = actual;\n    }\n  }\n\n  protected void assertValueNotNull(String key, Object value) {\n    if (key == null) {\n      throw new IllegalArgumentException(\"Key can not be null.\");\n    }\n    if (value == null) {\n      throw new IllegalArgumentException(\"Argument can not be null. key = \" + key);\n    }\n  }\n\n  public static int compareNum(Object num, String anotherNum) {\n    try {\n      if (num instanceof Integer) {\n        return Integer.compare((Integer) num, Integer.parseInt(anotherNum));\n      }\n      if (num instanceof Long) {\n        return Long.compare((Long) num, Long.parseLong(anotherNum));\n      }\n      if (num instanceof Double) {\n        return Double.compare((Double) num, Double.parseDouble(anotherNum));\n      }\n      if (num instanceof Float) {\n        return Float.compare((Float) num, Float.parseFloat(anotherNum));\n      }\n    } catch (NumberFormatException e) {\n      return 1;\n    }\n    return 1;\n  }\n\n  public Object getActual() {\n    return actual;\n  }\n\n  public SupportedType getType() {\n    return type;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/AndCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class AndCondition extends AbstractCondition {\n  private final Condition[] conditions;\n\n  public AndCondition(Condition... conditions) {\n    super(\"and\", \"and\");\n    this.conditions = conditions;\n  }\n\n  @Override\n  public void setActual(String key, Object actual) {\n    for (Condition condition : this.conditions) {\n      condition.setActual(key, actual);\n    }\n  }\n\n  @Override\n  public boolean match() {\n    for (Condition condition : this.conditions) {\n      if (!condition.match()) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/CaseInsensitiveCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class CaseInsensitiveCondition extends AbstractCondition {\n  private final Condition condition;\n\n  public CaseInsensitiveCondition(Condition condition) {\n    super(condition.key(), condition.expected());\n    this.condition = condition;\n  }\n\n  @Override\n  public void setActual(String key, Object actual) {\n    if (null == actual) {\n      condition.setActual(key, null);\n      return;\n    }\n    actual = actual.toString().toLowerCase();\n    condition.setActual(key, actual);\n  }\n\n  @Override\n  public boolean match() {\n    return condition.match();\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/Condition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\n\npublic interface Condition {\n  String key();\n\n  String expected();\n\n  void setActual(String key, Object actual);\n\n  boolean match();\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/ConditionFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\nimport java.util.Arrays;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.darklaunch.DarklaunchRule;\n\npublic class ConditionFactory {\n  public static final String OP_AND = \"&&\";\n\n  public static final String OP_OR = \"||\";\n\n  public static final String OP_OR_ESCAPE = \"\\\\|\\\\|\";\n\n  private static final String[] OP_LIST = {\">=\", \"<=\", \"!=\", \"=\", \">\", \"<\", \"~\"};\n\n  public static final String SEP_COLON = \",\";\n\n  private static String[] split2Part(String str, String sep) {\n    int index = str.indexOf(sep);\n    if (index > 0) {\n      return new String[] {\n          str.substring(0, index), str.substring(index + sep.length())\n      };\n    } else {\n      return new String[] {str};\n    }\n  }\n\n  private static String[] split(String str, String sep) {\n    return Arrays.stream(str.split(sep))\n            .filter(s -> !StringUtils.isEmpty(s)).toArray(String[]::new);\n  }\n\n  public static Condition buildRateCondition(String strCondition) {\n    return new LessCondition(DarklaunchRule.PROP_PERCENT, strCondition);\n  }\n\n  public static Condition buildCondition(String strCondition, boolean caseInsensitive) {\n    if (strCondition.contains(OP_AND)) {\n      String[] rules = split(strCondition, OP_AND);\n      Condition[] conditions = new Condition[rules.length];\n      for (int i = 0; i < conditions.length; i++) {\n        conditions[i] = buildGroupConditionItem(rules[i], caseInsensitive);\n      }\n      return new AndCondition(conditions);\n    } else if (strCondition.contains(OP_OR)) {\n      String[] rules = split(strCondition, OP_OR_ESCAPE);\n      Condition[] conditions = new Condition[rules.length];\n      for (int i = 0; i < conditions.length; i++) {\n        conditions[i] = buildGroupConditionItem(rules[i], caseInsensitive);\n      }\n      return new OrCondition(conditions);\n    } else {\n      return buildGroupConditionItem(strCondition, caseInsensitive);\n    }\n  }\n\n  private static Condition buildGroupConditionItem(String groupCondition, boolean caseInsensitive) {\n    for (int index = 0; index < OP_LIST.length; index++) {\n      if (groupCondition.contains(OP_LIST[index])) {\n        String[] pairs = split2Part(groupCondition, OP_LIST[index]);\n        if (pairs[1].contains(SEP_COLON)) {\n          String[] values = split(pairs[1], SEP_COLON);\n          Condition[] conditions = new Condition[values.length];\n          for (int i = 0; i < values.length; i++) {\n            conditions[i] = buildCondition(index, pairs[0], values[i], caseInsensitive);\n          }\n          return new OrCondition(conditions);\n        } else {\n          return buildCondition(index, pairs[0], pairs[1], caseInsensitive);\n        }\n      }\n    }\n    throw new IllegalArgumentException(groupCondition);\n  }\n\n  private static Condition buildCondition(int index, String key, String value, boolean caseInsensitive) {\n    value = caseInsensitive ? value.toLowerCase() : value;\n    Condition condition = buildCondition(index, key, value);\n    if (caseInsensitive) {\n      return new CaseInsensitiveCondition(condition);\n    }\n    return condition;\n  }\n\n  private static Condition buildCondition(int index, String key, String value) {\n    switch (index) {\n      case 0:\n        return new GreaterOrEqualCondition(key, value);\n      case 1:\n        return new LessOrEqualCondition(key, value);\n      case 2:\n        return new NotEqualCondition(key, value);\n      case 3:\n        return new EqualCondition(key, value);\n      case 4:\n        return new GreaterCondition(key, value);\n      case 5:\n        return new LessCondition(key, value);\n      default:\n        return new LikeCondition(key, value);\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/EqualCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class EqualCondition extends AbstractCondition {\n  public EqualCondition(String key, String expected) {\n    super(key, expected);\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.NUMBER) {\n      return compareNum(this.getActual(), this.expected()) == 0;\n    } else if (type == SupportedType.STRING) {\n      return ((String) this.getActual()).compareTo(this.expected()) == 0;\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/GreaterCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class GreaterCondition extends AbstractCondition {\n  public GreaterCondition(String key, String expected) {\n    super(key, expected);\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.NUMBER) {\n      return compareNum(this.getActual(), this.expected()) > 0;\n    } else if (type == SupportedType.STRING) {\n      return ((String) this.getActual()).compareTo(this.expected()) > 0;\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/GreaterOrEqualCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class GreaterOrEqualCondition extends AbstractCondition {\n  public GreaterOrEqualCondition(String key, String expected) {\n    super(key, expected);\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.NUMBER) {\n      return compareNum(this.getActual(), this.expected()) >= 0;\n    } else if (type == SupportedType.STRING) {\n      return ((String) this.getActual()).compareTo(this.expected()) >= 0;\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/LessCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class LessCondition extends AbstractCondition {\n  public LessCondition(String key, String expected) {\n    super(key, expected);\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.NUMBER) {\n      return compareNum(this.getActual(), this.expected()) < 0;\n    } else if (type == SupportedType.STRING) {\n      return ((String) this.getActual()).compareTo(this.expected()) < 0;\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/LessOrEqualCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class LessOrEqualCondition extends AbstractCondition {\n  public LessOrEqualCondition(String key, String expected) {\n    super(key, expected);\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.NUMBER) {\n      return compareNum(this.getActual(), this.expected()) <= 0;\n    } else if (type == SupportedType.STRING) {\n      return ((String) this.getActual()).compareTo(this.expected()) <= 0;\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/LikeCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\nimport java.util.regex.Pattern;\n\npublic class LikeCondition extends AbstractCondition {\n  private final Pattern pattern;\n\n  public LikeCondition(String key, String expected) {\n    super(key, expected);\n\n    char[] cs = expected.toCharArray();\n    StringBuilder regExp = new StringBuilder();\n    int lastPos = 0;\n    for (int i = 0; i < cs.length; i++) {\n      if ((cs[i]) == '*') {\n        regExp.append(Pattern.quote(new String(cs, lastPos, i - lastPos)));\n        regExp.append(\".*\");\n        lastPos = i + 1;\n      } else if (cs[i] == '?') {\n        regExp.append(Pattern.quote(new String(cs, lastPos, i - lastPos)));\n        regExp.append(\".\");\n        lastPos = i = 1;\n      }\n    }\n    regExp.append(Pattern.quote(new String(cs, lastPos, cs.length - lastPos)));\n    pattern = Pattern.compile(regExp.toString());\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.STRING) {\n      return  this.pattern.matcher((String) this.getActual()).matches();\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/NotEqualCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class NotEqualCondition extends AbstractCondition {\n\n  public NotEqualCondition(String key, String expected) {\n    super(key, expected);\n  }\n\n  @Override\n  public boolean match() {\n    SupportedType type = this.getType();\n    if (type == SupportedType.NUMBER) {\n      return compareNum(this.getActual(), this.expected()) != 0;\n    } else if (type == SupportedType.STRING) {\n      return ((String) this.getActual()).compareTo(this.expected()) != 0;\n    } else {\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/OrCondition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic class OrCondition extends AbstractCondition {\n  private final Condition[] conditions;\n\n  public OrCondition(Condition... conditions) {\n    super(\"or\", \"or\");\n    this.conditions = conditions;\n  }\n\n  @Override\n  public void setActual(String key, Object actual) {\n    for (Condition condition : this.conditions) {\n      condition.setActual(key, actual);\n    }\n  }\n\n  @Override\n  public boolean match() {\n    for (Condition condition : this.conditions) {\n      if (condition.match()) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/java/org/apache/servicecomb/darklaunch/oper/SupportedType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.darklaunch.oper;\n\npublic enum SupportedType {\n  STRING,\n  NUMBER,\n  UNKNOWN\n}\n"
  },
  {
    "path": "huawei-cloud/darklaunch/src/main/resources/META-INF/services/org.apache.servicecomb.loadbalance.ServerListFilterExt",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.darklaunch.DarklaunchServerListFilter\n"
  },
  {
    "path": "huawei-cloud/dashboard/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>huawei-cloud</artifactId>\n        <groupId>org.apache.servicecomb</groupId>\n        <version>3.4.0-SNAPSHOT</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>dashboard</artifactId>\n    <dependencies>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>foundation-common</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>java-chassis-core</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>registry-service-center</artifactId>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>dashboard-client</artifactId>\n        </dependency>\n\n        <!-- optional dependencies -->\n        <dependency>\n            <groupId>org.apache.servicecomb</groupId>\n            <artifactId>metrics-core</artifactId>\n            <scope>provided</scope>\n        </dependency>\n        <!-- optional dependencies -->\n    </dependencies>\n</project>\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DashboardConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\npublic class DashboardConfiguration {\n  @Bean\n  public MonitorInformationCollector scbMonitorInformationCollector() {\n    return new MonitorInformationCollector();\n  }\n\n  @Bean\n  public MonitorConstant scbMonitorConstant(Environment environment) {\n    return new MonitorConstant(environment);\n  }\n\n  @Bean\n  public MonitorBootListener scbMonitorBootListener() {\n    return new MonitorBootListener();\n  }\n\n  @Bean\n  public DataFactory scbDataFactory() {\n    return new DataFactory();\n  }\n\n  @Bean\n  public MetricsMonitorDataProvider scbMetricsMonitorDataProvider() {\n    return new MetricsMonitorDataProvider();\n  }\n\n  @Bean\n  public DefaultMonitorDataPublisher scbDefaultMonitorDataPublisher() {\n    return new DefaultMonitorDataPublisher();\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DataFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport java.util.List;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataProvider;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataPublisher;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.netty.util.concurrent.DefaultThreadFactory;\n\npublic class DataFactory {\n  private static final Logger LOGGER = LoggerFactory.getLogger(DataFactory.class);\n\n  private static final int CORE_SIZE = 1;\n\n  private boolean hasStart = false;\n\n  @Autowired\n  private List<MonitorDataProvider> dataProviders;\n\n  @Autowired\n  private MonitorDataPublisher publisher;\n\n  @Autowired\n  private MonitorConstant monitorConstant;\n\n  private ScheduledExecutorService executorService = null;\n\n\n  public DataFactory() {\n    ThreadFactory threadFactory = new DefaultThreadFactory(\"monitor-datafactory\");\n    executorService = Executors.newScheduledThreadPool(CORE_SIZE, threadFactory);\n  }\n\n  public void setMonitorDataProviders(List<MonitorDataProvider> dataProviders) {\n    this.dataProviders = dataProviders;\n  }\n\n  public void setMonitorDataPublisher(MonitorDataPublisher publisher) {\n    this.publisher = publisher;\n  }\n\n  void start() {\n    if (!hasStart) {\n      publisher.init();\n\n      StringBuilder sb = new StringBuilder();\n      sb.append(\"Monitor data sender started. Configured data providers is {\");\n      for (MonitorDataProvider provider : dataProviders) {\n        sb.append(provider.getClass().getName());\n        sb.append(\",\");\n      }\n      sb.append(\"}\");\n      LOGGER.info(sb.toString());\n\n      executorService.scheduleWithFixedDelay(() -> {\n        try {\n          sendData();\n        } catch (Throwable e) {\n          LOGGER.error(\"send monitor data error.\", e);\n        }\n      }, monitorConstant.getInterval(), monitorConstant.getInterval(), TimeUnit.MILLISECONDS);\n      hasStart = true;\n    }\n  }\n\n  void sendData() {\n    for (MonitorDataProvider provider : this.dataProviders) {\n      if (provider.enabled()) {\n        this.publisher.publish(provider);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.client.config.RequestConfig;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.dashboard.client.DashboardAddressManager;\nimport org.apache.servicecomb.dashboard.client.DashboardClient;\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpTransportFactory;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataProvider;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataPublisher;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class DefaultMonitorDataPublisher implements MonitorDataPublisher {\n  private static final String SSL_KEY = \"mc.consumer\";\n\n  private DashboardClient dashboardClient;\n\n  private MonitorConstant monitorConstant;\n\n  private Environment environment;\n\n  @Autowired\n  public void setMonitorConstant(MonitorConstant monitorConstant) {\n    this.monitorConstant = monitorConstant;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void init() {\n    DashboardAddressManager addressManager = createDashboardAddressManager();\n\n    RequestConfig.Builder requestBuilder = HttpTransportFactory.defaultRequestConfig();\n    requestBuilder.setConnectionRequestTimeout(1000);\n    requestBuilder.setSocketTimeout(10000);\n\n    HttpTransport httpTransport = createHttpTransport(addressManager, requestBuilder.build(),\n        environment);\n\n    dashboardClient = new DashboardClient(addressManager, httpTransport);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private DashboardAddressManager createDashboardAddressManager() {\n    List<String> addresses = ConfigUtil.parseArrayValue(\n        environment.getProperty(MonitorConstant.SYSTEM_KEY_DASHBOARD_SERVICE, \"\"));\n\n    if (addresses.isEmpty()) {\n      throw new IllegalStateException(\"dashboard address is not configured.\");\n    }\n    String region = environment.getProperty(\"servicecomb.datacenter.region\");\n    String availableZone = environment.getProperty(\"servicecomb.datacenter.availableZone\");\n\n    return new DashboardAddressManager(addresses, EventManager.getEventBus(), region, availableZone);\n  }\n\n  private HttpTransport createHttpTransport(DashboardAddressManager addressManager, RequestConfig requestConfig,\n      Environment environment) {\n    List<AuthHeaderProvider> authHeaderProviders = SPIServiceUtils.getOrLoadSortedService(AuthHeaderProvider.class);\n\n    if (monitorConstant.isProxyEnable()) {\n      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().\n          setDefaultRequestConfig(requestConfig);\n      HttpHost proxy = new HttpHost(monitorConstant.getProxyHost(),\n          monitorConstant.getProxyPort(), \"http\"); // now only support http proxy\n      httpClientBuilder.setProxy(proxy);\n      CredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n      credentialsProvider.setCredentials(new AuthScope(proxy),\n          new UsernamePasswordCredentials(monitorConstant.getProxyUsername(),\n              monitorConstant.getProxyPasswd()));\n      httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n\n      return HttpTransportFactory\n          .createHttpTransport(\n              TransportUtils\n                  .createSSLProperties(addressManager.sslEnabled(), environment, SSL_KEY),\n              getRequestAuthHeaderProvider(authHeaderProviders), httpClientBuilder);\n    }\n\n    return HttpTransportFactory\n        .createHttpTransport(\n            TransportUtils\n                .createSSLProperties(monitorConstant.sslEnabled(), environment, SSL_KEY),\n            getRequestAuthHeaderProvider(authHeaderProviders), requestConfig);\n  }\n\n  private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {\n    return signRequest -> {\n      String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : \"\";\n      Map<String, String> headers = new HashMap<>();\n      authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host)));\n      return headers;\n    };\n  }\n\n  @Override\n  public void publish(MonitorDataProvider provider) {\n    dashboardClient.sendData(provider.getURL(), provider.getData());\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/MetricsMonitorDataProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.dashboard.client.model.InterfaceInfo;\nimport org.apache.servicecomb.dashboard.client.model.MonitorData;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.metrics.PolledEvent;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataProvider;\nimport org.apache.servicecomb.metrics.core.publish.PublishModelFactory;\nimport org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerf;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroup;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.PerfInfo;\nimport org.apache.servicecomb.registry.sc.SCRegistration;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.Subscribe;\n\nimport io.micrometer.core.instrument.Meter;\n\n/**\n * Monitor data based on metrics-core module.\n */\npublic class MetricsMonitorDataProvider implements MonitorDataProvider {\n\n  public static final String CODE_SUCCESS = \"2[0-9]{2}\";\n\n  public static final String CODE_TIMEOUT = \"408\";\n\n  public static final String NAME_PROVIDER = \"Provider.\";\n\n  public static final String NAME_CONSUMER = \"Consumer.\";\n\n  private volatile List<Meter> meters = null;\n\n  private SCRegistration scRegistration;\n\n  private Environment environment;\n\n  private MonitorConstant monitorConstant;\n\n  public MetricsMonitorDataProvider() {\n    EventManager.register(this);\n  }\n\n  @Autowired\n  public void setSCRegistration(SCRegistration scRegistration) {\n    this.scRegistration = scRegistration;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setMonitorConstant(MonitorConstant monitorConstant) {\n    this.monitorConstant = monitorConstant;\n  }\n\n  @Override\n  public boolean enabled() {\n    return environment.getProperty(\"servicecomb.monitor.provider.metrics.enabled\", boolean.class, true);\n  }\n\n  @Override\n  public String getURL() {\n    return String.format(monitorConstant.getMonitorUri(), scRegistration.getMicroserviceInstance().getServiceName());\n  }\n\n  @Override\n  public void extractServiceInfo(MonitorData monitorData) {\n    monitorData.setAppId(scRegistration.getMicroserviceInstance().getApplication());\n    monitorData.setName(scRegistration.getMicroserviceInstance().getServiceName());\n    monitorData.setVersion(scRegistration.getMicroserviceInstance().getVersion());\n    monitorData.setServiceId(scRegistration.getMicroserviceInstance().getBackendMicroservice().getServiceId());\n    monitorData.setInstance(scRegistration.getMicroserviceInstance().getBackendMicroserviceInstance().getHostName());\n    monitorData.setInstanceId(scRegistration.getMicroserviceInstance().getInstanceId());\n    monitorData.setEnvironment(scRegistration.getMicroserviceInstance().getEnvironment());\n  }\n\n  @Override\n  public void extractInterfaceInfo(MonitorData monitorData) {\n    if (meters == null) {\n      return;\n    }\n    PublishModelFactory factory = new PublishModelFactory(meters);\n    DefaultPublishModel model = factory.createDefaultPublishModel();\n\n    Map<String, InterfaceInfo> combinedResults = new HashMap<>();\n    extractProviderInfo(model, combinedResults);\n    extractConsumerInfo(model, combinedResults);\n    extractEdgeInfo(model, combinedResults);\n    combinedResults.forEach((k, v) -> {\n      v.setFailureRate(v.getTotal() == 0 ? 0 : v.getFailure() / (double) v.getTotal());\n      monitorData.addInterfaceInfo(v);\n    });\n  }\n\n  private void extractProviderInfo(DefaultPublishModel model, Map<String, InterfaceInfo> combinedResults) {\n    OperationPerfGroups producerPerf = model.getProducer().getOperationPerfGroups();\n    if (producerPerf == null) {\n      return;\n    }\n\n    for (Map<String, OperationPerfGroup> statusMap : producerPerf.getGroups().values()) {\n      for (OperationPerfGroup perfGroup : statusMap.values()) {\n        for (int i = 0; i < perfGroup.getOperationPerfs().size(); i++) {\n          OperationPerf operationPerf = perfGroup.getOperationPerfs().get(i);\n          PerfInfo stageTotal = operationPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n          String name = NAME_PROVIDER + operationPerf.getOperation();\n          InterfaceInfo interfaceInfo = combinedResults.computeIfAbsent(name,\n              k -> {\n                InterfaceInfo obj = new InterfaceInfo();\n                obj.setName(name);\n                return obj;\n              });\n          // dashboard calculates the latest 10 seconds, different with metrics cycle.\n          interfaceInfo.setTotal(\n              doubleToInt(interfaceInfo.getTotal() + stageTotal.getTotalRequests()));\n          if (perfGroup.getStatus().matches(CODE_SUCCESS)) {\n            interfaceInfo.setQps(stageTotal.getTotalRequests() / 10);\n            interfaceInfo.setLatency(doubleToInt(stageTotal.calcMsLatency()));\n          } else {\n            interfaceInfo.setFailure(\n                doubleToInt(interfaceInfo.getTotal() + stageTotal.getTotalRequests()));\n            if (perfGroup.getStatus().equals(CODE_TIMEOUT)) {\n              interfaceInfo.setCountTimeout(\n                  doubleToInt(interfaceInfo.getCountTimeout() + stageTotal.getTotalRequests()));\n            }\n          }\n        }\n      }\n    }\n  }\n\n  private void extractEdgeInfo(DefaultPublishModel model, Map<String, InterfaceInfo> combinedResults) {\n    OperationPerfGroups edgePerf = model.getEdge().getOperationPerfGroups();\n    if (edgePerf == null) {\n      return;\n    }\n    for (Map<String, OperationPerfGroup> statusMap : edgePerf.getGroups().values()) {\n      for (OperationPerfGroup perfGroup : statusMap.values()) {\n        for (int i = 0; i < perfGroup.getOperationPerfs().size(); i++) {\n          OperationPerf operationPerf = perfGroup.getOperationPerfs().get(i);\n          PerfInfo stageTotal = operationPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n          String name = NAME_CONSUMER + operationPerf.getOperation();\n          InterfaceInfo interfaceInfo = combinedResults.computeIfAbsent(name,\n              k -> {\n                InterfaceInfo obj = new InterfaceInfo();\n                obj.setName(name);\n                return obj;\n              });\n          // dashboard calculates the latest 10 seconds, different with metrics cycle.\n          interfaceInfo.setTotal(\n              doubleToInt(interfaceInfo.getTotal() + stageTotal.getTotalRequests()));\n          if (perfGroup.getStatus().matches(CODE_SUCCESS)) {\n            interfaceInfo.setQps(stageTotal.getTotalRequests() / 10);\n            interfaceInfo.setLatency(doubleToInt(stageTotal.calcMsLatency()));\n          } else {\n            interfaceInfo.setFailure(\n                doubleToInt(interfaceInfo.getTotal() + stageTotal.getTotalRequests()));\n            if (perfGroup.getStatus().equals(CODE_TIMEOUT)) {\n              interfaceInfo.setCountTimeout(\n                  doubleToInt(\n                      interfaceInfo.getCountTimeout() + stageTotal.getTotalRequests()));\n            }\n          }\n        }\n      }\n    }\n  }\n\n  private void extractConsumerInfo(DefaultPublishModel model, Map<String, InterfaceInfo> combinedResults) {\n    OperationPerfGroups consumerPerf = model.getConsumer().getOperationPerfGroups();\n    if (consumerPerf == null) {\n      return;\n    }\n    for (Map<String, OperationPerfGroup> statusMap : consumerPerf.getGroups().values()) {\n      for (OperationPerfGroup perfGroup : statusMap.values()) {\n        for (int i = 0; i < perfGroup.getOperationPerfs().size(); i++) {\n          OperationPerf operationPerf = perfGroup.getOperationPerfs().get(i);\n          PerfInfo stageTotal = operationPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n          String name = NAME_CONSUMER + operationPerf.getOperation();\n          InterfaceInfo interfaceInfo = combinedResults.computeIfAbsent(name,\n              k -> {\n                InterfaceInfo obj = new InterfaceInfo();\n                obj.setName(name);\n                return obj;\n              });\n          // dashboard calculates the latest 10 seconds, different with metrics cycle.\n          interfaceInfo.setTotal(\n              doubleToInt(interfaceInfo.getTotal() + stageTotal.getTotalRequests()));\n          if (perfGroup.getStatus().matches(CODE_SUCCESS)) {\n            interfaceInfo.setQps(stageTotal.getTotalRequests() / 10);\n            interfaceInfo.setLatency(doubleToInt(stageTotal.calcMsLatency()));\n          } else {\n            interfaceInfo.setFailure(\n                doubleToInt(interfaceInfo.getTotal() + stageTotal.getTotalRequests()));\n            if (perfGroup.getStatus().equals(CODE_TIMEOUT)) {\n              interfaceInfo.setCountTimeout(\n                  doubleToInt(\n                      interfaceInfo.getCountTimeout() + stageTotal.getTotalRequests()));\n            }\n          }\n        }\n      }\n    }\n  }\n\n  private int doubleToInt(Double d) {\n    return d.intValue();\n  }\n\n  @Subscribe\n  public void onPolledEvent(PolledEvent event) {\n    this.meters = event.getMeters();\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/MonitorBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class MonitorBootListener implements BootListener {\n\n  @Autowired\n  private DataFactory dataFactory;\n\n  @Autowired\n  private MonitorConstant monitorConstant;\n\n  @Override\n  public void onBootEvent(BootEvent event) {\n    if (!monitorConstant.isMonitorEnabled()) {\n      return;\n    }\n\n    if (EventType.AFTER_REGISTRY == event.getEventType()) {\n      dataFactory.start();\n    }\n  }\n\n  public DataFactory getDataFactory() {\n    return dataFactory;\n  }\n\n  public void setDataFactory(DataFactory dataFactory) {\n    this.dataFactory = dataFactory;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/MonitorInformationCollector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.core.bootup.BootUpInformationCollector;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class MonitorInformationCollector implements BootUpInformationCollector {\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public String collect() {\n    return \"monitor center: \" +\n        ConfigUtil.parseArrayValue(\n            environment.getProperty(MonitorConstant.SYSTEM_KEY_DASHBOARD_SERVICE, \"\"));\n  }\n\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/TransportUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport static org.apache.servicecomb.foundation.ssl.SSLOption.DEFAULT_OPTION;\n\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.springframework.core.env.Environment;\n\npublic class TransportUtils {\n  public static SSLProperties createSSLProperties(boolean sslEnabled, Environment environment, String tag) {\n    SSLProperties sslProperties = new SSLProperties();\n    sslProperties.setEnabled(sslEnabled);\n\n    if (!sslEnabled) {\n      return sslProperties;\n    }\n\n    SSLOption option = new SSLOption();\n    option.setEngine(getStringProperty(environment,\n        DEFAULT_OPTION.getEngine(),\n        \"ssl.\" + tag + \".engine\",\n        \"ssl.engine\"));\n    option.setProtocols(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getProtocols(),\n            \"ssl.\" + tag + \".protocols\",\n            \"ssl.protocols\"));\n    option.setCiphers(\n        getStringProperty(environment, DEFAULT_OPTION.getCiphers(), \"ssl.\" + tag + \".ciphers\", \"ssl.ciphers\"));\n    option.setAuthPeer(\n        getBooleanProperty(environment, DEFAULT_OPTION.isAuthPeer(), \"ssl.\" + tag + \".authPeer\", \"ssl.authPeer\"));\n    option.setCheckCNHost(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNHost(),\n            \"ssl.\" + tag + \".checkCN.host\",\n            \"ssl.checkCN.host\"));\n    option.setCheckCNWhite(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNWhite(),\n            \"ssl.\" + tag + \".checkCN.white\",\n            \"ssl.checkCN.white\"));\n    option.setCheckCNWhiteFile(getStringProperty(environment,\n        DEFAULT_OPTION.getCiphers(),\n        \"ssl.\" + tag + \".checkCN.white.file\",\n        \"ssl.checkCN.white.file\"));\n    option.setAllowRenegotiate(getBooleanProperty(environment,\n        DEFAULT_OPTION.isAllowRenegotiate(),\n        \"ssl.\" + tag + \".allowRenegotiate\",\n        \"ssl.allowRenegotiate\"));\n    option.setStorePath(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getStorePath(),\n            \"ssl.\" + tag + \".storePath\",\n            \"ssl.storePath\"));\n    option.setClientAuth(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getClientAuth(),\n            \"ssl.\" + tag + \".clientAuth\",\n            \"ssl.clientAuth\"));\n    option.setTrustStore(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getTrustStore(),\n            \"ssl.\" + tag + \".trustStore\",\n            \"ssl.trustStore\"));\n    option.setTrustStoreType(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreType(),\n        \"ssl.\" + tag + \".trustStoreType\",\n        \"ssl.trustStoreType\"));\n    option.setTrustStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreValue(),\n        \"ssl.\" + tag + \".trustStoreValue\",\n        \"ssl.trustStoreValue\"));\n    option.setKeyStore(\n        getStringProperty(environment, DEFAULT_OPTION.getKeyStore(), \"ssl.\" + tag + \".keyStore\", \"ssl.keyStore\"));\n    option.setKeyStoreType(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getKeyStoreType(),\n            \"ssl.\" + tag + \".keyStoreType\",\n            \"ssl.keyStoreType\"));\n    option.setKeyStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getKeyStoreValue(),\n        \"ssl.\" + tag + \".keyStoreValue\",\n        \"ssl.keyStoreValue\"));\n    option.setCrl(getStringProperty(environment, DEFAULT_OPTION.getCrl(), \"ssl.\" + tag + \".crl\", \"ssl.crl\"));\n    option.setSslCustomClass(\n        getStringProperty(environment, null, \"ssl.\" + tag + \".sslCustomClass\", \"ssl.sslCustomClass\"));\n\n    sslProperties.setSslOption(option);\n    sslProperties.setSslCustom(SSLCustom.createSSLCustom(option.getSslCustomClass()));\n    return sslProperties;\n  }\n\n  private static String getStringProperty(Environment environment, String defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key);\n      }\n    }\n    return defaultValue;\n  }\n\n  private static boolean getBooleanProperty(Environment environment, boolean defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key, boolean.class, false);\n      }\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/data/CPUMonitorCalc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor.data;\n\n\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.management.ThreadMXBean;\n\npublic class CPUMonitorCalc {\n  private static final int PERCENTAGE = 100;\n\n  private static final CPUMonitorCalc instance = new CPUMonitorCalc();\n\n  private final OperatingSystemMXBean osMxBean;\n\n  private final ThreadMXBean threadMXBean;\n\n  private long preTime = System.nanoTime();\n\n  private long preUsedTime = 0;\n\n  private CPUMonitorCalc() {\n    osMxBean = ManagementFactory.getOperatingSystemMXBean();\n    threadMXBean = ManagementFactory.getThreadMXBean();\n  }\n\n  public static CPUMonitorCalc getInstance() {\n    return instance;\n  }\n\n  public double getProcessCpu() {\n    long totalTime = 0;\n\n    for (long id : threadMXBean.getAllThreadIds()) {\n      totalTime += threadMXBean.getThreadCpuTime(id);\n    }\n\n    long curtime = System.nanoTime();\n    long usedTime = totalTime - preUsedTime;\n    long totalPassedTime = curtime - preTime;\n    preTime = curtime;\n    preUsedTime = totalTime;\n    return (((double) usedTime) / totalPassedTime / osMxBean.getAvailableProcessors()) * PERCENTAGE;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/data/MonitorConstant.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor.data;\n\nimport org.springframework.core.env.Environment;\n\npublic class MonitorConstant {\n  public static final String SYSTEM_KEY_DASHBOARD_SERVICE = \"DashboardService\";\n\n  public static final String MONITOR_URI = \"servicecomb.monitor.client.serverUri\";\n\n  public static final String PROXY_ENABLE = \"servicecomb.proxy.enable\";\n\n  public static final String PROXY_HOST = \"servicecomb.proxy.host\";\n\n  public static final String PROXY_PORT = \"servicecomb.proxy.port\";\n\n  public static final String PROXY_USERNAME = \"servicecomb.proxy.username\";\n\n  public static final String PROXY_PASSWD = \"servicecomb.proxy.passwd\";\n\n  public static final int MIN_INTERVAL_MILLISECONDS = 5000;\n\n  public static final int DEFAULT_TIMEOUT = 5000;\n\n  public static final int DEFAULT_INTERVAL = 10000;\n\n  private final String DOMAIN_NAME;\n\n  private final String CURRENT_VERSION;\n\n  private final String VERSION_V1;\n\n  private final String PREFIX_V2;\n\n  private final String monitorsUri;\n\n  private Environment environment;\n\n  public MonitorConstant(Environment environment) {\n    this.environment = environment;\n    this.VERSION_V1 = \"v1\";\n    this.DOMAIN_NAME = getDomainName();\n    this.PREFIX_V2 = String.format(\"/v2/%s/csemonitor\", DOMAIN_NAME);\n    this.CURRENT_VERSION = getApiVersion();\n\n    if (VERSION_V1.equals(CURRENT_VERSION)) {\n      monitorsUri = \"/csemonitor/v1/metric?service=%s\";\n    } else {\n      monitorsUri = PREFIX_V2 + \"/metric?service=%s\";\n    }\n  }\n\n  public String getMonitorUri() {\n    return this.monitorsUri;\n  }\n\n  public String getDomainName() {\n    return environment.getProperty(\"servicecomb.config.client.domainName\", \"default\");\n  }\n\n  public String getApiVersion() {\n    return environment.getProperty(\"servicecomb.monitor.client.api.version\", \"v2\");\n  }\n\n  public String getServerUrl() {\n    return environment.getProperty(\"servicecomb.monitor.client.serverUri\");\n  }\n\n  public boolean sslEnabled() {\n    return environment.getProperty(\"servicecomb.monitor.client.sslEnabled\", boolean.class, true);\n  }\n\n  public boolean isMonitorEnabled() {\n    return environment.getProperty(\"servicecomb.monitor.client.enabled\", boolean.class, false);\n  }\n\n  public int getConnectionTimeout() {\n    return environment.getProperty(\"servicecomb.monitor.client.timeout\", int.class, DEFAULT_TIMEOUT);\n  }\n\n  public int getInterval() {\n    return Math.max(environment.getProperty(\"servicecomb.monitor.client.interval\", int.class, DEFAULT_INTERVAL),\n        MIN_INTERVAL_MILLISECONDS);\n  }\n\n  public Boolean isProxyEnable() {\n    return Boolean.parseBoolean(getProperty(\"false\", PROXY_ENABLE));\n  }\n\n  public String getProxyHost() {\n    return getProperty(\"127.0.0.1\", PROXY_HOST);\n  }\n\n  public int getProxyPort() {\n    return Integer.parseInt(getProperty(\"8080\", PROXY_PORT));\n  }\n\n  public String getProxyUsername() {\n    return getProperty(null, PROXY_USERNAME);\n  }\n\n  public String getProxyPasswd() {\n    return getProperty(null, PROXY_PASSWD);\n  }\n\n  private String getProperty(String defaultValue, String... keys) {\n    String property = null;\n    for (String key : keys) {\n      property = environment.getProperty(key);\n      if (property != null) {\n        break;\n      }\n    }\n\n    if (property != null) {\n      return property;\n    }\n    return defaultValue;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/model/MonitorDataProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor.model;\n\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.MemoryMXBean;\nimport java.lang.management.MemoryUsage;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.management.RuntimeMXBean;\nimport java.lang.management.ThreadMXBean;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.dashboard.client.model.MonitorData;\nimport org.apache.servicecomb.huaweicloud.dashboard.monitor.data.CPUMonitorCalc;\n\npublic interface MonitorDataProvider {\n  boolean enabled();\n\n  String getURL();\n\n  void extractServiceInfo(MonitorData monitorData);\n\n  default void exactProcessInfo(MonitorData monitorData) {\n    MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();\n    MemoryUsage memoryHeapUsage = memoryMXBean.getHeapMemoryUsage();\n    MemoryUsage memoryNonHeapUsage = memoryMXBean.getNonHeapMemoryUsage();\n    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();\n    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();\n    int threadCount = threadMXBean.getThreadCount();\n    OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();\n\n    double cpu = operatingSystemMXBean.getSystemLoadAverage();\n    monitorData.setCpu(CPUMonitorCalc.getInstance().getProcessCpu());\n    monitorData.setLoadAverage(cpu);\n    monitorData.setThreadCount(threadCount);\n    monitorData.setUptime(runtimeMXBean.getUptime());\n\n    Map<String, Long> memoryInfo = new HashMap<>();\n    memoryInfo.put(\"heapInit\", memoryHeapUsage.getInit());\n    memoryInfo.put(\"headMax\", memoryHeapUsage.getMax());\n    memoryInfo.put(\"heapCommit\", memoryHeapUsage.getCommitted());\n    memoryInfo.put(\"heapUsed\", memoryHeapUsage.getUsed());\n    memoryInfo.put(\"nonHeapInit\", memoryNonHeapUsage.getInit());\n    memoryInfo.put(\"nonHeapCommit\", memoryNonHeapUsage.getCommitted());\n    memoryInfo.put(\"nonHeapUsed\", memoryNonHeapUsage.getUsed());\n    monitorData.setMemory(memoryInfo);\n  }\n\n  void extractInterfaceInfo(MonitorData monitorData);\n\n  default MonitorData getData() {\n    MonitorData monitorData = new MonitorData();\n    extractServiceInfo(monitorData);\n    exactProcessInfo(monitorData);\n    extractInterfaceInfo(monitorData);\n    return monitorData;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/model/MonitorDataPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor.model;\n\npublic interface MonitorDataPublisher {\n  void publish(MonitorDataProvider provider);\n\n  default void init() {\n\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/resources/META-INF/services/org.apache.servicecomb.core.bootup.BootUpInformationCollector",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\norg.apache.servicecomb.huaweicloud.dashboard.monitor.MonitorInformationCollector\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.huaweicloud.dashboard.monitor.DashboardConfiguration\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/test/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/MetricsMonitorDataProviderTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.huaweicloud.dashboard.monitor;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class MetricsMonitorDataProviderTest {\n  @Test\n  public void testCodeMatch() {\n    Assertions.assertTrue(\"200\".matches(MetricsMonitorDataProvider.CODE_SUCCESS));\n    Assertions.assertTrue(\"202\".matches(MetricsMonitorDataProvider.CODE_SUCCESS));\n    Assertions.assertFalse(\"2002\".matches(MetricsMonitorDataProvider.CODE_SUCCESS));\n    Assertions.assertFalse(\"400\".matches(MetricsMonitorDataProvider.CODE_SUCCESS));\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/dashboard/src/test/resources/microservice.yaml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n# spring boot configurations\nserver:\n  port: 9093  # should be same with servicecomb.rest.address to use web container\n\n# override common configurations in common module\nservicecomb-config-order: 10\ninstance_description:\n  environment: production\n\nservicecomb:\n  service:\n    environment: development\n    application: demo-java-chassis-dashboard\n    name: test-dashboard\n    version: 0.0.1\n    registry:\n      address: http://127.0.0.1:30100\n      instance:\n        watch: false\n  kie:\n    serverUri: http://127.0.0.1:30110\n    customLabel: public\n\n  rest:\n    address: 0.0.0.0:9097 # should be same with server.port to use web container\n"
  },
  {
    "path": "huawei-cloud/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n\n  <artifactId>huawei-cloud</artifactId>\n  <name>Java Chassis::Huawei Cloud</name>\n  <packaging>pom</packaging>\n  <modelVersion>4.0.0</modelVersion>\n\n  <modules>\n    <module>servicestage</module>\n    <module>dashboard</module>\n    <module>darklaunch</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "huawei-cloud/servicestage/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>huawei-cloud</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n  <artifactId>servicestage</artifactId>\n  <name>Java Chassis::Huawei Cloud::ServiceStage</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport javax.crypto.Mac;\nimport javax.crypto.spec.SecretKeySpec;\n\nimport org.apache.commons.codec.binary.Hex;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.foundation.auth.Cipher;\nimport org.apache.servicecomb.foundation.auth.DefaultCipher;\nimport org.apache.servicecomb.foundation.auth.ShaAKSKCipher;\nimport org.apache.servicecomb.foundation.bootstrap.BootStrapService;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\npublic class AKSKAuthHeaderProvider implements AuthHeaderProvider, BootStrapService {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AKSKAuthHeaderProvider.class);\n\n  private static final String CONFIG_AKSK_ENABLED = \"servicecomb.credentials.akskEnabled\";\n\n  private static final String CONFIG_ACCESS_KEY = \"servicecomb.credentials.accessKey\";\n\n  private static final String CONFIG_SECRET_KEY = \"servicecomb.credentials.secretKey\";\n\n  private static final String CONFIG_CIPHER = \"servicecomb.credentials.akskCustomCipher\";\n\n  private static final String CONFIG_PROJECT = \"servicecomb.credentials.project\";\n\n  private static final String VALUE_DEFAULT_PROJECT = \"default\";\n\n  private static final String VALUE_DEFAULT_CIPHER = \"default\";\n\n  private static final String X_SERVICE_AK = \"X-Service-AK\";\n\n  private static final String X_SERVICE_SHAAKSK = \"X-Service-ShaAKSK\";\n\n  private static final String X_SERVICE_PROJECT = \"X-Service-Project\";\n\n  private static Environment environment;\n\n  private final Map<String, String> headers = new HashMap<>();\n\n  private boolean loaded = false;\n\n  public AKSKAuthHeaderProvider() {\n  }\n\n  public Map<String, String> authHeaders() {\n    if (!environment.getProperty(CONFIG_AKSK_ENABLED, boolean.class, true)) {\n      return Collections.emptyMap();\n    }\n\n    if (StringUtils.isEmpty(getAccessKey())) {\n      LOGGER.warn(\"ak sk auth enabled but access key is not configured, disable it at runtime. \"\n              + \"Config [{}] to false to disable it implicitly.\",\n          CONFIG_AKSK_ENABLED);\n      return Collections.emptyMap();\n    }\n\n    if (!loaded) {\n      load();\n    }\n    return headers;\n  }\n\n  private synchronized void load() {\n    if (!loaded) {\n      headers.put(X_SERVICE_AK, getAccessKey());\n      headers.put(X_SERVICE_SHAAKSK, getSecretKey());\n      headers.put(X_SERVICE_PROJECT, getProject());\n      loaded = true;\n    }\n  }\n\n  private String getAccessKey() {\n    return environment.getProperty(CONFIG_ACCESS_KEY, \"\");\n  }\n\n  private String getCipher() {\n    return environment.getProperty(CONFIG_CIPHER, VALUE_DEFAULT_CIPHER);\n  }\n\n  private String getSecretKey() {\n    String secretKey = environment.getProperty(CONFIG_SECRET_KEY, \"\");\n    String decodedSecretKey = new String(findCipher().decrypt(secretKey.toCharArray()));\n\n    // ShaAKSKCipher 不解密, 认证的时候不处理；其他算法解密为 plain，需要 encode 为 ShaAKSKCipher 去认证。\n    if (ShaAKSKCipher.CIPHER_NAME.equalsIgnoreCase(getCipher())) {\n      return decodedSecretKey;\n    } else {\n      return sha256Encode(decodedSecretKey, getAccessKey());\n    }\n  }\n\n  private String getProject() {\n    String project = environment.getProperty(CONFIG_PROJECT, VALUE_DEFAULT_PROJECT);\n    if (StringUtils.isEmpty(project)) {\n      return project;\n    }\n    return URLEncoder.encode(project, StandardCharsets.UTF_8);\n  }\n\n  private Cipher findCipher() {\n    if (DefaultCipher.CIPHER_NAME.equals(getCipher())) {\n      return DefaultCipher.getInstance();\n    }\n\n    List<Cipher> ciphers = SPIServiceUtils.getOrLoadSortedService(Cipher.class);\n    return ciphers.stream().filter(c -> c.name().equals(getCipher())).findFirst()\n        .orElseThrow(() -> new IllegalArgumentException(\"failed to find cipher named \" + getCipher()));\n  }\n\n  public static String sha256Encode(String key, String data) {\n    try {\n      Mac sha256HMAC = Mac.getInstance(\"HmacSHA256\");\n      SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8),\n          \"HmacSHA256\");\n      sha256HMAC.init(secretKey);\n      return Hex.encodeHexString(sha256HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8)));\n    } catch (Exception e) {\n      throw new IllegalArgumentException(\"Can not encode ak sk. Please check the value is correct.\", e);\n    }\n  }\n\n  @Override\n  public void startup(Environment environment) {\n    AKSKAuthHeaderProvider.environment = environment;\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/CasEnvConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport static org.apache.commons.lang3.StringUtils.EMPTY;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\n\npublic class CasEnvConfig {\n  private static final String APPLICATION_ID = \"CAS_APPLICATION_ID\";\n\n  private static final String COMPONENT_NAME = \"CAS_COMPONENT_NAME\";\n\n  private static final String INSTANCE_VERSION = \"CAS_INSTANCE_VERSION\";\n\n  private static final String INSTANCE_ID = \"CAS_INSTANCE_ID\";\n\n  private static final String ENVIRONMENT_ID = \"CAS_ENVIRONMENT_ID\";\n\n  private static final String SERVICE_PROPS = \"SERVICECOMB_SERVICE_PROPS\";\n\n  private static final String INSTANCE_PROPS = \"SERVICECOMB_INSTANCE_PROPS\";\n\n  public static final CasEnvConfig INSTANCE = new CasEnvConfig();\n\n  private Map<String, String> parseProps(String value) {\n    Map<String, String> rs = new HashMap<>();\n    if (StringUtils.isEmpty(value)) {\n      return rs;\n    }\n    return Arrays.stream(value.split(\",\")).map(v -> v.split(\":\"))\n        .filter(v -> v.length == 2)\n        .collect(Collectors.toMap(v -> v[0], v -> v[1]));\n  }\n\n  public Map<String, String> getNonEmptyInstanceProperties() {\n    Map<String, String> map = new HashMap<>();\n\n    map.put(APPLICATION_ID, LegacyPropertyFactory\n        .getStringProperty(APPLICATION_ID, EMPTY));\n    map.put(COMPONENT_NAME, LegacyPropertyFactory\n        .getStringProperty(COMPONENT_NAME, EMPTY));\n    map.put(INSTANCE_VERSION, LegacyPropertyFactory\n        .getStringProperty(INSTANCE_VERSION, EMPTY));\n    map.put(INSTANCE_ID, LegacyPropertyFactory\n        .getStringProperty(INSTANCE_ID, EMPTY));\n    map.put(ENVIRONMENT_ID, LegacyPropertyFactory\n        .getStringProperty(ENVIRONMENT_ID, EMPTY));\n\n    Map<String, String> instanceProps = map.entrySet().stream()\n        .filter(entry -> StringUtils.isNotEmpty(entry.getValue()))\n        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));\n\n    instanceProps.putAll(parseProps(LegacyPropertyFactory\n        .getStringProperty(INSTANCE_PROPS, EMPTY)));\n\n    return instanceProps;\n  }\n\n  public Map<String, String> getNonEmptyServiceProperties() {\n    return parseProps(LegacyPropertyFactory\n        .getStringProperty(SERVICE_PROPS, EMPTY));\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/CasEnvVariablesAdapter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class CasEnvVariablesAdapter implements InitializingBean {\n\n  private RegistrationManager registrationManager;\n\n  @Autowired\n  public void setRegistrationManager(RegistrationManager registrationManager) {\n    this.registrationManager = registrationManager;\n  }\n\n  @Override\n  public void afterPropertiesSet() throws Exception {\n    Map<String, String> extras = CasEnvConfig.INSTANCE.getNonEmptyServiceProperties();\n    extras.forEach((k, v) -> this.registrationManager.addProperty(k, v));\n    extras = CasEnvConfig.INSTANCE.getNonEmptyInstanceProperties();\n    extras.forEach((k, v) -> this.registrationManager.addProperty(k, v));\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport static org.apache.servicecomb.foundation.ssl.SSLOption.DEFAULT_OPTION;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.servicecomb.foundation.auth.Cipher;\nimport org.apache.servicecomb.foundation.auth.DefaultCipher;\nimport org.apache.servicecomb.foundation.bootstrap.BootStrapService;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.vertx.VertxConst;\nimport org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpTransportFactory;\nimport org.apache.servicecomb.registry.sc.SCClientUtils;\nimport org.apache.servicecomb.service.center.client.ServiceCenterAddressManager;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterRawClient;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class RBACBootStrapService implements BootStrapService {\n  private static final String RBAC_ADDRESS = \"servicecomb.service.registry.address\";\n\n  public static final String DEFAULT_REGISTRY_NAME = \"default\";\n\n  public static final String RBAC_ENABLED = \"servicecomb.credentials.rbac.enabled\";\n\n  public static final String ACCOUNT_NAME_KEY = \"servicecomb.credentials.account.name\";\n\n  public static final String PASSWORD_KEY = \"servicecomb.credentials.account.password\";\n\n  public static final String CIPHER_KEY = \"servicecomb.credentials.cipher\";\n\n  public static final String PROJECT_KEY = \"servicecomb.credentials.project\";\n\n  private static final String SSL_TAG = \"sc.consumer\";\n\n  @Override\n  public void startup(Environment environment) {\n    if (!getBooleanProperty(environment, false, RBAC_ENABLED)) {\n      return;\n    }\n\n    ServiceCenterAddressManager addressManager = createAddressManager(environment);\n    addressManager.setEventBus(EventManager.getEventBus());\n    SSLProperties sslProperties = createSSLProperties(environment);\n    sslProperties.setEnabled(addressManager.sslEnabled());\n\n    ServiceCenterClient serviceCenterClient =\n        new ServiceCenterClient(new ServiceCenterRawClient.Builder()\n            .setTenantName(\"default\")\n            .setAddressManager(addressManager)\n            .setHttpTransport(createHttpTransport(environment, sslProperties)).build(), addressManager);\n\n    Map<String, ServiceCenterClient> clients = new HashMap<>(1);\n    clients.put(DEFAULT_REGISTRY_NAME, serviceCenterClient);\n    TokenCacheManager.getInstance().setServiceCenterClients(clients);\n    TokenCacheManager.getInstance().addTokenCache(\n        DEFAULT_REGISTRY_NAME,\n        getStringProperty(environment, null, ACCOUNT_NAME_KEY),\n        getStringProperty(environment, null, PASSWORD_KEY),\n        getCipher(getStringProperty(environment, DefaultCipher.CIPHER_NAME, CIPHER_KEY)));\n  }\n\n  private static HttpTransport createHttpTransport(Environment environment, SSLProperties sslProperties) {\n    if (isProxyEnable(environment)) {\n      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().\n          setDefaultRequestConfig(HttpTransportFactory.defaultRequestConfig().build());\n      HttpHost proxy = new HttpHost(getProxyHost(environment),\n          getProxyPort(environment), \"http\");  // now only support http proxy\n      httpClientBuilder.setProxy(proxy);\n      CredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n      credentialsProvider.setCredentials(new AuthScope(proxy),\n          new UsernamePasswordCredentials(getProxyUsername(environment),\n              getProxyPasswd(environment)));\n      httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n\n      return HttpTransportFactory\n          .createHttpTransport(sslProperties,\n              new DefaultRequestAuthHeaderProvider(), httpClientBuilder);\n    }\n\n    return HttpTransportFactory\n        .createHttpTransport(sslProperties,\n            new DefaultRequestAuthHeaderProvider(), HttpTransportFactory.defaultRequestConfig().build());\n  }\n\n  @VisibleForTesting\n  Cipher getCipher(String cipherName) {\n    if (DefaultCipher.CIPHER_NAME.equals(cipherName)) {\n      return DefaultCipher.getInstance();\n    }\n\n    List<Cipher> ciphers = SPIServiceUtils.getOrLoadSortedService(Cipher.class);\n    return ciphers.stream().filter(c -> c.name().equals(cipherName)).findFirst()\n        .orElseThrow(() -> new IllegalArgumentException(\"failed to find cipher named \" + cipherName));\n  }\n\n  private ServiceCenterAddressManager createAddressManager(Environment environment) {\n    return SCClientUtils.createAddressManager(getProjectName(environment), getRBACAddressList(environment),\n        environment);\n  }\n\n  private SSLProperties createSSLProperties(Environment environment) {\n    SSLProperties sslProperties = new SSLProperties();\n\n    SSLOption option = new SSLOption();\n    option.setEngine(getStringProperty(environment,\n        DEFAULT_OPTION.getEngine(),\n        \"ssl.\" + SSL_TAG + \".engine\",\n        \"ssl.engine\"));\n    option.setProtocols(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getProtocols(),\n            \"ssl.\" + SSL_TAG + \".protocols\",\n            \"ssl.protocols\"));\n    option.setCiphers(\n        getStringProperty(environment, DEFAULT_OPTION.getCiphers(), \"ssl.\" + SSL_TAG + \".ciphers\", \"ssl.ciphers\"));\n    option.setAuthPeer(\n        getBooleanProperty(environment, DEFAULT_OPTION.isAuthPeer(), \"ssl.\" + SSL_TAG + \".authPeer\", \"ssl.authPeer\"));\n    option.setCheckCNHost(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNHost(),\n            \"ssl.\" + SSL_TAG + \".checkCN.host\",\n            \"ssl.checkCN.host\"));\n    option.setCheckCNWhite(\n        getBooleanProperty(environment,\n            DEFAULT_OPTION.isCheckCNWhite(),\n            \"ssl.\" + SSL_TAG + \".checkCN.white\",\n            \"ssl.checkCN.white\"));\n    option.setCheckCNWhiteFile(getStringProperty(environment,\n        DEFAULT_OPTION.getCiphers(),\n        \"ssl.\" + SSL_TAG + \".checkCN.white.file\",\n        \"ssl.checkCN.white.file\"));\n    option.setAllowRenegotiate(getBooleanProperty(environment,\n        DEFAULT_OPTION.isAllowRenegotiate(),\n        \"ssl.\" + SSL_TAG + \".allowRenegotiate\",\n        \"ssl.allowRenegotiate\"));\n    option.setStorePath(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getStorePath(),\n            \"ssl.\" + SSL_TAG + \".storePath\",\n            \"ssl.storePath\"));\n    option.setClientAuth(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getClientAuth(),\n            \"ssl.\" + SSL_TAG + \".clientAuth\",\n            \"ssl.clientAuth\"));\n    option.setTrustStore(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getTrustStore(),\n            \"ssl.\" + SSL_TAG + \".trustStore\",\n            \"ssl.trustStore\"));\n    option.setTrustStoreType(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreType(),\n        \"ssl.\" + SSL_TAG + \".trustStoreType\",\n        \"ssl.trustStoreType\"));\n    option.setTrustStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getTrustStoreValue(),\n        \"ssl.\" + SSL_TAG + \".trustStoreValue\",\n        \"ssl.trustStoreValue\"));\n    option.setKeyStore(\n        getStringProperty(environment, DEFAULT_OPTION.getKeyStore(), \"ssl.\" + SSL_TAG + \".keyStore\", \"ssl.keyStore\"));\n    option.setKeyStoreType(\n        getStringProperty(environment,\n            DEFAULT_OPTION.getKeyStoreType(),\n            \"ssl.\" + SSL_TAG + \".keyStoreType\",\n            \"ssl.keyStoreType\"));\n    option.setKeyStoreValue(getStringProperty(environment,\n        DEFAULT_OPTION.getKeyStoreValue(),\n        \"ssl.\" + SSL_TAG + \".keyStoreValue\",\n        \"ssl.keyStoreValue\"));\n    option.setCrl(getStringProperty(environment, DEFAULT_OPTION.getCrl(), \"ssl.\" + SSL_TAG + \".crl\", \"ssl.crl\"));\n    option.setSslCustomClass(\n        getStringProperty(environment, null, \"ssl.\" + SSL_TAG + \".sslCustomClass\", \"ssl.sslCustomClass\"));\n\n    sslProperties.setSslOption(option);\n    sslProperties.setSslCustom(SSLCustom.createSSLCustom(option.getSslCustomClass()));\n    return sslProperties;\n  }\n\n  private String getStringProperty(Environment environment, String defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return environment.getProperty(key);\n      }\n    }\n    return defaultValue;\n  }\n\n  private boolean getBooleanProperty(Environment environment, boolean defaultValue, String... keys) {\n    for (String key : keys) {\n      if (environment.getProperty(key) != null) {\n        return Boolean.parseBoolean(environment.getProperty(key));\n      }\n    }\n    return defaultValue;\n  }\n\n  private String getProjectName(Environment environment) {\n    return getStringProperty(environment, \"default\", PROJECT_KEY);\n  }\n\n  private List<String> getRBACAddressList(Environment environment) {\n    String address = environment.getProperty(RBAC_ADDRESS, \"http://127.0.0.1:30100\");\n    return Arrays.asList(address.split(\",\"));\n  }\n\n\n  public static Boolean isProxyEnable(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_ENABLE, boolean.class, false);\n  }\n\n  public static String getProxyHost(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_HOST, \"127.0.0.1\");\n  }\n\n  public static int getProxyPort(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_PORT, int.class, 8080);\n  }\n\n  public static String getProxyUsername(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_USERNAME);\n  }\n\n  public static String getProxyPasswd(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_PASSWD);\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/ServiceStageConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ServiceStageConfiguration {\n  @Bean\n  public CasEnvVariablesAdapter casEnvVariablesAdapter() {\n    return new CasEnvVariablesAdapter();\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\n\npublic class TokenAuthHeaderProvider implements AuthHeaderProvider {\n  @Override\n  public Map<String, String> authHeaders(String host) {\n    String token = TokenCacheManager.getInstance().getToken(host);\n    if (StringUtils.isEmpty(token)) {\n      return new HashMap<>();\n    }\n\n    HashMap<String, String> header = new HashMap<>();\n    header.put(\"Authorization\", \"Bearer \" + token);\n    return Collections.unmodifiableMap(header);\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport java.net.URI;\nimport java.util.Map;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.auth.Cipher;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.http.client.event.OperationEvents;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.model.RbacTokenRequest;\nimport org.apache.servicecomb.service.center.client.model.RbacTokenResponse;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.cache.CacheBuilder;\nimport com.google.common.cache.CacheLoader;\nimport com.google.common.cache.LoadingCache;\nimport com.google.common.eventbus.Subscribe;\nimport com.google.common.util.concurrent.Futures;\nimport com.google.common.util.concurrent.ListenableFuture;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic final class TokenCacheManager {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TokenCacheManager.class);\n\n  // special token used for special conditions\n  // e.g. un-authorized: will query token after token expired period\n  // e.g. not found:  will query token after token expired period\n  public static final String INVALID_TOKEN = \"\";\n\n  private static final TokenCacheManager INSTANCE = new TokenCacheManager();\n\n  private Map<String, ServiceCenterClient> serviceCenterClients;\n\n  private TokenCache tokenCache;\n\n  public static TokenCacheManager getInstance() {\n    return INSTANCE;\n  }\n\n  private TokenCacheManager() {\n  }\n\n  public void setServiceCenterClients(Map<String, ServiceCenterClient> serviceCenterClients) {\n    this.serviceCenterClients = serviceCenterClients;\n  }\n\n  public void addTokenCache(String registryName, String accountName, String password, Cipher cipher) {\n    tokenCache = new TokenCache(registryName, accountName, password, cipher);\n  }\n\n  public String getToken(String host) {\n    if (tokenCache == null) {\n      return null;\n    }\n    return tokenCache.getToken(host);\n  }\n\n  public class TokenCache {\n    private static final long TOKEN_REFRESH_TIME_IN_SECONDS = 20 * 60 * 1000;\n\n    private final String registryName;\n\n    private final String accountName;\n\n    private final String password;\n\n    private ExecutorService executorService;\n\n    private LoadingCache<String, String> cache;\n\n    private final Cipher cipher;\n\n    public TokenCache(String registryName, String accountName, String password,\n        Cipher cipher) {\n      this.registryName = registryName;\n      this.accountName = accountName;\n      this.password = password;\n      this.cipher = cipher;\n\n      if (enabled()) {\n        executorService = Executors.newFixedThreadPool(1, t -> new Thread(t, \"rbac-executor-\" + this.registryName) {\n          @Override\n          public void run() {\n            try {\n              super.run();\n            } catch (Throwable e) {\n              LOGGER.error(\"\", e);\n            }\n          }\n        });\n        cache = CacheBuilder.newBuilder()\n            .maximumSize(10)\n            .refreshAfterWrite(refreshTime(), TimeUnit.MILLISECONDS)\n            .build(new CacheLoader<String, String>() {\n              @Override\n              public String load(String key) throws Exception {\n                return createHeaders(key);\n              }\n\n              @Override\n              public ListenableFuture<String> reload(String key, String oldValue) throws Exception {\n                return Futures.submit(() -> createHeaders(key), executorService);\n              }\n            });\n        EventManager.getEventBus().register(this);\n      }\n    }\n\n    @Subscribe\n    public void onNotPermittedEvent(OperationEvents.UnAuthorizedOperationEvent event) {\n      LOGGER.warn(\"address {} unAuthorized, refresh cache token!\", event.getAddress());\n      cache.refresh(getHostByAddress(event.getAddress()));\n    }\n\n    private String getHostByAddress(String address) {\n      try {\n        URI uri = URI.create(address);\n        return uri.getHost();\n      } catch (Exception e) {\n        LOGGER.error(\"get host by address [{}] error!\", address, e);\n        return registryName;\n      }\n    }\n\n    private String createHeaders(String host) {\n      LOGGER.info(\"start to create RBAC headers for host: {}\", host);\n\n      ServiceCenterClient serviceCenterClient = serviceCenterClients.get(this.registryName);\n\n      RbacTokenRequest request = new RbacTokenRequest();\n      request.setName(accountName);\n      request.setPassword(new String(cipher.decrypt(password.toCharArray())));\n\n      RbacTokenResponse rbacTokenResponse = serviceCenterClient.queryToken(request, host);\n\n      if (Status.UNAUTHORIZED.getStatusCode() == rbacTokenResponse.getStatusCode()\n          || Status.FORBIDDEN.getStatusCode() == rbacTokenResponse.getStatusCode()) {\n        // password wrong, do not try anymore\n        LOGGER.warn(\"username or password may be wrong, stop trying to query tokens.\");\n        return INVALID_TOKEN;\n      }\n      if (Status.NOT_FOUND.getStatusCode() == rbacTokenResponse.getStatusCode()) {\n        // service center not support, do not try\n        LOGGER.warn(\"service center do not support RBAC token, you should not config account info\");\n        return INVALID_TOKEN;\n      }\n      if (Status.INTERNAL_SERVER_ERROR.getStatusCode() == rbacTokenResponse.getStatusCode()) {\n        // return null for server_error, so the token information can be re-fetched on the next call.\n        // It will prompt 'CacheLoader returned null for key xxx'\n        LOGGER.warn(\"service center query RBAC token error!\");\n        return null;\n      }\n\n      LOGGER.info(\"refresh host [{}] token successfully {}\", host, rbacTokenResponse.getStatusCode());\n      return rbacTokenResponse.getToken();\n    }\n\n    protected long refreshTime() {\n      return TOKEN_REFRESH_TIME_IN_SECONDS;\n    }\n\n    public String getToken(String host) {\n      if (!enabled()) {\n        return null;\n      }\n      String address = host;\n      if (StringUtils.isEmpty(address)) {\n        address = registryName;\n      }\n      try {\n        return cache.get(address);\n      } catch (Exception e) {\n        LOGGER.error(\"failed to create token\", e);\n        return null;\n      }\n    }\n\n    private boolean enabled() {\n      return !StringUtils.isEmpty(this.accountName)\n          && !StringUtils.isEmpty(this.password);\n    }\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.auth.AuthHeaderProvider",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.huaweicloud.servicestage.AKSKAuthHeaderProvider\norg.apache.servicecomb.huaweicloud.servicestage.TokenAuthHeaderProvider\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.auth.Cipher",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.foundation.auth.ShaAKSKCipher\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.bootstrap.BootStrapService",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.huaweicloud.servicestage.RBACBootStrapService\norg.apache.servicecomb.huaweicloud.servicestage.AKSKAuthHeaderProvider\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/resources/META-INF/services/org.apache.servicecomb.serviceregistry.adapter.EnvAdapter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.huaweicloud.servicestage.CasEnvVariablesAdapter\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.huaweicloud.servicestage.ServiceStageConfiguration\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/test/java/org/apache/servicecomb/huaweicloud/servicestage/TestAKSKAuthHeaderProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestAKSKAuthHeaderProvider {\n  @Test\n  public void test_project_name_properly_encoded_en() {\n    Environment environment = Mockito.mock(Environment.class);\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.akskEnabled\",\n        boolean.class, true)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.project\",\n        \"default\")).thenReturn(\"hello\");\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.accessKey\",\n        \"\")).thenReturn(\"access key\");\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.secretKey\",\n        \"\")).thenReturn(\"secret key\");\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.akskCustomCipher\",\n        \"default\")).thenReturn(\"default\");\n\n    AKSKAuthHeaderProvider provider = new AKSKAuthHeaderProvider();\n    provider.startup(environment);\n    Assertions.assertEquals(\"hello\", provider.authHeaders().get(\"X-Service-Project\"));\n  }\n\n  @Test\n  public void test_project_name_properly_encoded_cn() {\n    Environment environment = Mockito.mock(Environment.class);\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.akskEnabled\",\n        boolean.class, true)).thenReturn(true);\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.project\",\n        \"default\")).thenReturn(\"测试\");\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.accessKey\",\n        \"\")).thenReturn(\"access key\");\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.secretKey\",\n        \"\")).thenReturn(\"secret key\");\n    Mockito.when(environment.getProperty(\"servicecomb.credentials.akskCustomCipher\",\n        \"default\")).thenReturn(\"default\");\n    AKSKAuthHeaderProvider provider = new AKSKAuthHeaderProvider();\n    provider.startup(environment);\n    Assertions.assertEquals(\"%E6%B5%8B%E8%AF%95\", provider.authHeaders().get(\"X-Service-Project\"));\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/test/java/org/apache/servicecomb/huaweicloud/servicestage/TestEnvVariablesAdapter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.huaweicloud.servicestage;\n\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\n\npublic class TestEnvVariablesAdapter {\n\n  @BeforeAll\n  public static void init() {\n    System.setProperty(\"CAS_APPLICATION_ID\", \"application-id\");\n    System.setProperty(\"CAS_ENVIRONMENT_ID\", \"env-id\");\n    System.setProperty(\"SERVICECOMB_SERVICE_PROPS\", \"component:ConsumerService,other:A\");\n    System.setProperty(\"SERVICECOMB_INSTANCE_PROPS\", \"route:gray\");\n  }\n\n  @Test\n  public void testProcessInstance() {\n    // TODO: set CAS properties for service center\n    CasEnvVariablesAdapter adapter = new CasEnvVariablesAdapter();\n//    MicroserviceInstance instance = new MicroserviceInstance();\n//    adapter.beforeRegisterInstance(instance);\n//\n//    Assertions.assertEquals(3, instance.getProperties().size());\n//    Assertions.assertEquals(\"application-id\", instance.getProperties().get(\"CAS_APPLICATION_ID\"));\n//    Assertions.assertEquals(\"env-id\", instance.getProperties().get(\"CAS_ENVIRONMENT_ID\"));\n//    Assertions.assertEquals(\"gray\", instance.getProperties().get(\"route\"));\n//\n//    Microservice microservice = new Microservice();\n//    adapter.beforeRegisterService(microservice);\n//    Assertions.assertEquals(2, microservice.getProperties().size());\n//    Assertions.assertEquals(\"ConsumerService\", microservice.getProperties().get(\"component\"));\n//    Assertions.assertEquals(\"A\", microservice.getProperties().get(\"other\"));\n  }\n\n  @AfterAll\n  public static void destroy() {\n    System.getProperties().remove(\"CAS_APPLICATION_ID\");\n    System.getProperties().remove(\"CAS_ENVIRONMENT_ID\");\n    System.getProperties().remove(\"SERVICECOMB_SERVICE_PROPS\");\n    System.getProperties().remove(\"SERVICECOMB_INSTANCE_PROPS\");\n  }\n}\n"
  },
  {
    "path": "huawei-cloud/servicestage/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "metrics/metrics-core/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>metrics</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>metrics-core</artifactId>\n  <name>Java Chassis::Metrics::Core</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-metrics</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/InvocationMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.apache.servicecomb.metrics.core.meter.ConsumerMeters;\nimport org.apache.servicecomb.metrics.core.meter.EdgeMeters;\nimport org.apache.servicecomb.metrics.core.meter.ProducerMeters;\nimport org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class InvocationMetersInitializer implements MetricsInitializer {\n  private ConsumerMeters consumerMeters;\n\n  private ProducerMeters producerMeters;\n\n  private EdgeMeters edgeMeters;\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    consumerMeters = new ConsumerMeters(meterRegistry, config);\n    producerMeters = new ProducerMeters(meterRegistry, config);\n    edgeMeters = new EdgeMeters(meterRegistry, config);\n\n    eventBus.register(this);\n  }\n\n  protected AbstractInvocationMeters findInvocationMeters(Invocation invocation) {\n    if (invocation.isConsumer()) {\n      return consumerMeters.getInvocationMeters();\n    }\n    if (invocation.isEdge()) {\n      return edgeMeters.getInvocationMeters();\n    }\n    return producerMeters.getInvocationMeters();\n  }\n\n  @Subscribe\n  @AllowConcurrentEvents\n  public void onInvocationStart(InvocationStartEvent event) {\n    AbstractInvocationMeters invocationMeters = findInvocationMeters(event.getInvocation());\n    invocationMeters.onInvocationStart(event);\n  }\n\n  @Subscribe\n  @AllowConcurrentEvents\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    AbstractInvocationMeters invocationMeters = findInvocationMeters(event.getInvocation());\n    invocationMeters.onInvocationFinish(event);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsBootListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport org.apache.servicecomb.core.BootListener;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrap;\n\npublic class MetricsBootListener implements BootListener {\n  private final MetricsBootstrap metricsBootstrap;\n\n  public MetricsBootListener(MetricsBootstrap metricsBootstrap) {\n    this.metricsBootstrap = metricsBootstrap;\n  }\n\n  @Override\n  public void onBeforeProducerProvider(BootEvent event) {\n\n  }\n\n  public MetricsBootstrap getMetricsBootstrap() {\n    return metricsBootstrap;\n  }\n\n  @Override\n  public void onAfterRegistry(BootEvent event) {\n    metricsBootstrap.start(EventManager.getEventBus());\n  }\n\n  @Override\n  public void onBeforeClose(BootEvent event) {\n    metricsBootstrap.shutdown();\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/MetricsCoreConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrap;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.metrics.core.publish.DefaultLogPublisher;\nimport org.apache.servicecomb.metrics.core.publish.SlowInvocationLogger;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport io.micrometer.core.instrument.Clock;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.CountingMode;\n\n@Configuration\npublic class MetricsCoreConfiguration {\n  @Bean\n  public MetricsBootstrapConfig metricsBootstrapConfig(Environment environment) {\n    return new MetricsBootstrapConfig(environment);\n  }\n\n  @Bean\n  @ConditionalOnMissingBean\n  public MeterRegistry meterRegistry(MetricsBootstrapConfig config) {\n    return new SimpleMeterRegistryExt(s -> {\n      if (\"simple.step\".equals(s)) {\n        return Duration.ofMillis(config.getMsPollInterval()).toString();\n      }\n      if (\"simple.mode\".equals(s)) {\n        return CountingMode.STEP.name();\n      }\n      return null;\n    }, Clock.SYSTEM);\n  }\n\n  @Bean\n  public MetricsBootListener metricsBootListener(MetricsBootstrap metricsBootstrap) {\n    return new MetricsBootListener(metricsBootstrap);\n  }\n\n  @Bean\n  public MetricsBootstrap metricsBootstrap(MetricsBootstrapConfig config) {\n    return new MetricsBootstrap(config);\n  }\n\n  // Begin MetricsInitializers\n\n  @Bean\n  public DefaultLogPublisher defaultLogPublisher() {\n    return new DefaultLogPublisher();\n  }\n\n  @Bean\n  public InvocationMetersInitializer invocationMetersInitializer() {\n    return new InvocationMetersInitializer();\n  }\n\n  @Bean\n  public ThreadPoolMetersInitializer threadPoolMetersInitializer() {\n    return new ThreadPoolMetersInitializer();\n  }\n\n  @Bean\n  public VertxMetersInitializer vertxMetersInitializer() {\n    return new VertxMetersInitializer();\n  }\n\n  @Bean\n  public OsMetersInitializer osMetersInitializer() {\n    return new OsMetersInitializer();\n  }\n\n  @Bean\n  public SlowInvocationLogger slowInvocationLogger(SCBEngine scbEngine) {\n    return new SlowInvocationLogger(scbEngine);\n  }\n\n  // End MetricsInitializers\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/OsMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.OsMeter;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class OsMetersInitializer implements MetricsInitializer, PeriodMeter {\n  private OsMeter osMeter;\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    osMeter = new OsMeter(meterRegistry);\n  }\n\n  public OsMeter getOsMeter() {\n    return osMeter;\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    if (osMeter != null) {\n      osMeter.poll(msNow, secondInterval);\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/SimpleMeterRegistryExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport io.micrometer.core.instrument.Clock;\nimport io.micrometer.core.instrument.DistributionSummary;\nimport io.micrometer.core.instrument.Meter;\nimport io.micrometer.core.instrument.cumulative.CumulativeDistributionSummary;\nimport io.micrometer.core.instrument.distribution.DistributionStatisticConfig;\nimport io.micrometer.core.instrument.distribution.HistogramGauges;\nimport io.micrometer.core.instrument.distribution.StepBucketHistogram;\nimport io.micrometer.core.instrument.simple.SimpleConfig;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\n\n/**\n * Custom SimpleMeterRegistry to support StepDistributionSummary\n */\npublic class SimpleMeterRegistryExt extends SimpleMeterRegistry {\n  private final SimpleConfig config;\n\n  public SimpleMeterRegistryExt(SimpleConfig config, Clock clock) {\n    super(config, clock);\n    this.config = config;\n  }\n\n  @Override\n  protected DistributionSummary newDistributionSummary(Meter.Id id,\n      DistributionStatisticConfig distributionStatisticConfig, double scale) {\n    DistributionStatisticConfig merged = distributionStatisticConfig\n        .merge(DistributionStatisticConfig.builder().expiry(config.step()).build());\n\n    DistributionSummary summary;\n    switch (config.mode()) {\n      case CUMULATIVE:\n        summary = new CumulativeDistributionSummary(id, clock, merged, scale, false);\n        break;\n      case STEP:\n      default:\n        summary = new StepDistributionSummaryExt(id, clock, merged, scale, config.step().toMillis(),\n            new StepBucketHistogram(clock, config.step().toMillis(), distributionStatisticConfig,\n                false, false));\n        break;\n    }\n\n    HistogramGauges.registerWithCommonFormat(summary, this);\n\n    return summary;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/StepDistributionSummaryExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport io.micrometer.core.instrument.Clock;\nimport io.micrometer.core.instrument.distribution.DistributionStatisticConfig;\nimport io.micrometer.core.instrument.distribution.Histogram;\nimport io.micrometer.core.instrument.step.StepDistributionSummary;\n\npublic class StepDistributionSummaryExt extends StepDistributionSummary {\n  public StepDistributionSummaryExt(Id id, Clock clock,\n      DistributionStatisticConfig distributionStatisticConfig, double scale, long stepMillis,\n      Histogram histogram) {\n    super(id, clock, distributionStatisticConfig, scale, stepMillis, histogram);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/SystemMetrics.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.core;\n\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.MemoryMXBean;\nimport java.lang.management.OperatingSystemMXBean;\nimport java.lang.management.ThreadMXBean;\n\npublic class SystemMetrics {\n  private final OperatingSystemMXBean systemMXBean;\n\n  private final ThreadMXBean threadMXBean;\n\n  private final MemoryMXBean memoryMXBean;\n\n  public SystemMetrics() {\n    this(ManagementFactory.getOperatingSystemMXBean(), ManagementFactory.getThreadMXBean(),\n        ManagementFactory.getMemoryMXBean());\n  }\n\n  public SystemMetrics(OperatingSystemMXBean systemMXBean, ThreadMXBean threadMXBean,\n      MemoryMXBean memoryMXBean) {\n    this.systemMXBean = systemMXBean;\n    this.threadMXBean = threadMXBean;\n    this.memoryMXBean = memoryMXBean;\n  }\n\n  public double getCpuLoad() {\n    return systemMXBean.getSystemLoadAverage();\n  }\n\n  public int getCpuRunningThreads() {\n    return threadMXBean.getThreadCount();\n  }\n\n  public long getHeapInit() {\n    return memoryMXBean.getHeapMemoryUsage().getInit();\n  }\n\n  public long getHeapMax() {\n    return memoryMXBean.getHeapMemoryUsage().getMax();\n  }\n\n  public long getHeapCommit() {\n    return memoryMXBean.getHeapMemoryUsage().getCommitted();\n  }\n\n  public long getHeapUsed() {\n    return memoryMXBean.getHeapMemoryUsage().getUsed();\n  }\n\n  public long getNonHeapInit() {\n    return memoryMXBean.getNonHeapMemoryUsage().getInit();\n  }\n\n  public long getNonHeapMax() {\n    return memoryMXBean.getNonHeapMemoryUsage().getMax();\n  }\n\n  public long getNonHeapCommit() {\n    return memoryMXBean.getNonHeapMemoryUsage().getCommitted();\n  }\n\n  public long getNonHeapUsed() {\n    return memoryMXBean.getNonHeapMemoryUsage().getUsed();\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/ThreadPoolMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport java.util.HashMap;\nimport java.util.IdentityHashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ThreadPoolExecutor;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.executor.GroupExecutor;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.apache.servicecomb.metrics.core.meter.pool.ThreadPoolMeter;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class ThreadPoolMetersInitializer implements MetricsInitializer, PeriodMeter {\n  private MeterRegistry meterRegistry;\n\n  private Map<String, ThreadPoolMeter> threadPoolMeters = new HashMap<>();\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    this.meterRegistry = meterRegistry;\n\n    createThreadPoolMeters();\n  }\n\n  public void createThreadPoolMeters() {\n    Map<Executor, Executor> operationExecutors = collectionOperationExecutors();\n    // currently, all operation executors come from bean\n    Map<String, Executor> beanExecutors = BeanUtils.getContext().getBeansOfType(Executor.class);\n\n    for (Entry<String, Executor> entry : beanExecutors.entrySet()) {\n      Executor executor = entry.getValue();\n      if (!operationExecutors.containsKey(executor)) {\n        continue;\n      }\n\n      if (executor instanceof GroupExecutor) {\n        createThreadPoolMeters(entry.getKey(), (GroupExecutor) executor);\n        continue;\n      }\n\n      createThreadPoolMeters(entry.getKey(), executor);\n    }\n  }\n\n  protected Map<Executor, Executor> collectionOperationExecutors() {\n    Map<Executor, Executor> operationExecutors = new IdentityHashMap<>();\n    //only one instance in the values\n    MicroserviceMeta microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();\n    for (OperationMeta operationMeta : microserviceMeta.getOperations()) {\n      operationExecutors.put(operationMeta.getExecutor(), operationMeta.getExecutor());\n    }\n    return operationExecutors;\n  }\n\n  protected void createThreadPoolMeters(String threadPoolName, GroupExecutor groupExecutor) {\n    for (int idx = 0; idx < groupExecutor.getExecutorList().size(); idx++) {\n      Executor executor = groupExecutor.getExecutorList().get(idx);\n      createThreadPoolMeters(threadPoolName + \"-group\" + idx, executor);\n    }\n  }\n\n  public void createThreadPoolMeters(String threadPoolName, Executor executor) {\n    if (!(executor instanceof ThreadPoolExecutor threadPoolExecutor)) {\n      return;\n    }\n\n    threadPoolMeters.computeIfAbsent(threadPoolName,\n        (key) -> new ThreadPoolMeter(meterRegistry, threadPoolName, threadPoolExecutor));\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    threadPoolMeters.forEach((key, value) -> value.poll(msNow, secondInterval));\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/VertxMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.apache.servicecomb.foundation.vertx.SharedVertxFactory;\nimport org.apache.servicecomb.metrics.core.meter.vertx.HttpClientEndpointsMeter;\nimport org.apache.servicecomb.metrics.core.meter.vertx.ServerEndpointsMeter;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class VertxMetersInitializer implements MetricsInitializer, PeriodMeter {\n  public static final String VERTX_ENDPOINTS = \"servicecomb.vertx.endpoints\";\n\n  public static final String ENDPOINTS_TYPE = \"type\";\n\n  public static final String ENDPOINTS_CLIENT = \"client\";\n\n  public static final String ENDPOINTS_SERVER = \"server\";\n\n  private HttpClientEndpointsMeter httpClientEndpointsMeter;\n\n  private ServerEndpointsMeter serverEndpointsMeter;\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    httpClientEndpointsMeter = new HttpClientEndpointsMeter(meterRegistry, VERTX_ENDPOINTS,\n        Tags.of(ENDPOINTS_TYPE, ENDPOINTS_CLIENT),\n        SharedVertxFactory.getMetricsFactory(config.getEnvironment())\n            .getVertxMetrics()\n            .getClientEndpointMetricManager());\n\n    serverEndpointsMeter = new ServerEndpointsMeter(meterRegistry, VERTX_ENDPOINTS,\n        Tags.of(ENDPOINTS_TYPE, ENDPOINTS_SERVER),\n        SharedVertxFactory.getMetricsFactory(config.getEnvironment())\n            .getVertxMetrics()\n            .getServerEndpointMetricMap());\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    httpClientEndpointsMeter.poll(msNow, secondInterval);\n    serverEndpointsMeter.poll(msNow, secondInterval);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ConsumerMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;\nimport org.apache.servicecomb.metrics.core.meter.invocation.ConsumerInvocationMeters;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class ConsumerMeters {\n  private final AbstractInvocationMeters invocationMeters;\n\n  public ConsumerMeters(MeterRegistry meterRegistry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    invocationMeters = new ConsumerInvocationMeters(meterRegistry, metricsBootstrapConfig);\n  }\n\n  public AbstractInvocationMeters getInvocationMeters() {\n    return invocationMeters;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/EdgeMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.core.meter;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;\nimport org.apache.servicecomb.metrics.core.meter.invocation.EdgeInvocationMeters;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class EdgeMeters {\n  private final AbstractInvocationMeters invocationMeters;\n\n\n  public EdgeMeters(MeterRegistry meterRegistry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    this.invocationMeters = new EdgeInvocationMeters(meterRegistry, metricsBootstrapConfig);\n  }\n\n  public AbstractInvocationMeters getInvocationMeters() {\n    return invocationMeters;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ProducerMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.metrics.core.meter.invocation.AbstractInvocationMeters;\nimport org.apache.servicecomb.metrics.core.meter.invocation.ProducerInvocationMeters;\n\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class ProducerMeters {\n  private final AbstractInvocationMeters invocationMeters;\n\n  public ProducerMeters(MeterRegistry meterRegistry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    invocationMeters = new ProducerInvocationMeters(meterRegistry, metricsBootstrapConfig);\n  }\n\n  public AbstractInvocationMeters getInvocationMeters() {\n    return invocationMeters;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/ThreadPoolMonitorPublishModelFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.meter.pool.ThreadPoolMeter;\nimport org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel;\n\nimport io.micrometer.core.instrument.Measurement;\n\npublic class ThreadPoolMonitorPublishModelFactory {\n  interface Setter {\n    void set(ThreadPoolPublishModel model, Measurement measurement);\n  }\n\n  public static Map<String, ThreadPoolPublishModel> create(MeasurementTree tree) {\n    Map<String, ThreadPoolPublishModel> result = new HashMap<>(8);\n    readMeasurement(result, tree, ThreadPoolMeter.TASK_COUNT,\n        (model, measurement) -> model.setAvgTaskCount(measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.COMPLETED_TASK_COUNT,\n        (model, measurement) -> model.setAvgCompletedTaskCount(measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.CURRENT_THREADS_BUSY,\n        (model, measurement) -> model.setCurrentThreadsBusy((int) measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.MAX_THREADS,\n        (model, measurement) -> model.setMaxThreads((int) measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.POOL_SIZE,\n        (model, measurement) -> model.setPoolSize((int) measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.CORE_POOL_SIZE,\n        (model, measurement) -> model.setCorePoolSize((int) measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.QUEUE_SIZE,\n        (model, measurement) -> model.setQueueSize((int) measurement.getValue()));\n    readMeasurement(result, tree, ThreadPoolMeter.REJECTED_COUNT,\n        (model, measurement) -> model.setRejected(measurement.getValue()));\n    return result;\n  }\n\n  protected static void readMeasurement(Map<String, ThreadPoolPublishModel> threadPools, MeasurementTree tree,\n      String name, Setter setter) {\n    MeasurementNode node = tree.findChild(ThreadPoolMeter.THREAD_POOL_METER);\n    if (node == null) {\n      return;\n    }\n\n    for (String threadPoolName : node.getChildren().keySet()) {\n      MeasurementNode measure = node.findChild(threadPoolName, name);\n      if (measure == null) {\n        continue;\n      }\n      ThreadPoolPublishModel model = threadPools.computeIfAbsent(threadPoolName, tpn -> new ThreadPoolPublishModel());\n      setter.set(model, measure.getMeasurements().get(0));\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport java.time.Duration;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.meter.LatencyDistributionConfig;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.micrometer.core.instrument.DistributionSummary;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\nimport io.micrometer.core.instrument.Timer;\n\npublic abstract class AbstractInvocationMeter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractInvocationMeter.class);\n\n  // total time distribution\n  private final DistributionSummary totalSummary;\n\n  //total time\n  private final Timer totalTimer;\n\n  // prepare time\n  private final Timer prepareTimer;\n\n  protected final MetricsBootstrapConfig metricsBootstrapConfig;\n\n  public AbstractInvocationMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      MetricsBootstrapConfig metricsBootstrapConfig) {\n    this.metricsBootstrapConfig = metricsBootstrapConfig;\n\n    double[] sla = toSla(metricsBootstrapConfig.getLatencyDistribution());\n    if (sla != null) {\n      totalSummary = DistributionSummary.builder(name)\n          .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_DISTRIBUTION))\n          .distributionStatisticExpiry(Duration.ofMillis(metricsBootstrapConfig.getMsPollInterval()))\n          .serviceLevelObjectives(sla).register(meterRegistry);\n    } else {\n      totalSummary = null;\n    }\n    this.totalTimer = Timer.builder(name).tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE\n        , MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_TOTAL)).register(meterRegistry);\n    this.prepareTimer = Timer.builder(name).tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE\n        , MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PREPARE)).register(meterRegistry);\n  }\n\n  private static double[] toSla(String config) {\n    if (StringUtils.isEmpty(config)) {\n      return null;\n    }\n    config = config.trim() + \",\" + LatencyDistributionConfig.MAX_LATENCY;\n    String[] array = config.split(\"\\\\s*,+\\\\s*\");\n    double[] result = new double[array.length];\n\n    for (int idx = 0; idx < array.length - 1; idx++) {\n      long msMin = Long.parseLong(array[idx]);\n      long msMax = Long.parseLong(array[idx + 1]);\n      if (msMin >= msMax) {\n        LOGGER.error(\"invalid latency scope, min={}, max={}.\", array[idx], array[idx + 1]);\n        return null;\n      }\n\n      result[idx] = msMin;\n    }\n    result[array.length - 1] = LatencyDistributionConfig.MAX_LATENCY;\n\n    if (Double.compare(0, result[0]) == 0) {\n      double[] target = new double[result.length - 1];\n      System.arraycopy(result, 1, target, 0, target.length);\n      return target;\n    }\n\n    return result;\n  }\n\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    InvocationStageTrace stageTrace = event.getInvocation().getInvocationStageTrace();\n    totalTimer.record(stageTrace.calcTotal(), TimeUnit.NANOSECONDS);\n    prepareTimer.record(stageTrace.calcPrepare(), TimeUnit.NANOSECONDS);\n    if (totalSummary != null) {\n      totalSummary.record(TimeUnit.NANOSECONDS.toMillis(stageTrace.calcTotal()));\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.event.InvocationStartEvent;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic abstract class AbstractInvocationMeters {\n  protected MeterRegistry registry;\n\n  private final Map<String, AbstractInvocationMeter> metersMap = new ConcurrentHashMapEx<>();\n\n  // not care for concurrency, just for make build key faster\n  private int maxKeyLen = 64;\n\n  protected MetricsBootstrapConfig metricsBootstrapConfig;\n\n  public AbstractInvocationMeters(MeterRegistry registry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    this.registry = registry;\n    this.metricsBootstrapConfig = metricsBootstrapConfig;\n  }\n\n  protected AbstractInvocationMeter getOrCreateMeters(Invocation invocation, Response response) {\n    // build string key is faster than use Id to locate timer directly\n    StringBuilder keyBuilder = new StringBuilder(maxKeyLen);\n    String invocationName = invocation.getInvocationType().name();\n\n    keyBuilder\n        .append(invocationName)\n        .append(invocation.getRealTransportName())\n        .append(invocation.getMicroserviceQualifiedName())\n        .append(response.getStatusCode());\n    if (keyBuilder.length() > maxKeyLen) {\n      maxKeyLen = keyBuilder.length();\n    }\n\n    return metersMap.computeIfAbsent(keyBuilder.toString(), k -> {\n      AbstractInvocationMeter meter = createMeter(MeterInvocationConst.INVOCATION_NAME, Tags.empty()\n          .and(MeterInvocationConst.TAG_ROLE, invocationName)\n          .and(MeterInvocationConst.TAG_TRANSPORT, invocation.getRealTransportName())\n          .and(MeterInvocationConst.TAG_OPERATION, invocation.getMicroserviceQualifiedName())\n          .and(MeterInvocationConst.TAG_STATUS, String.valueOf(response.getStatusCode())));\n      return meter;\n    });\n  }\n\n  protected abstract AbstractInvocationMeter createMeter(String name, Tags tags);\n\n  public void onInvocationStart(InvocationStartEvent event) {\n  }\n\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    AbstractInvocationMeter meters = getOrCreateMeters(event.getInvocation(), event.getResponse());\n    meters.onInvocationFinish(event);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\nimport io.micrometer.core.instrument.Timer;\n\npublic class ConsumerInvocationMeter extends AbstractInvocationMeter {\n  private final Timer consumerEncodeRequestTimer;\n\n  private final Timer consumerDecodeResponseTimer;\n\n  private final Timer consumerGetConnectionTimer;\n\n  private final Timer consumerSendRequestTimer;\n\n  private final Timer consumerWaitResponseTimer;\n\n  public ConsumerInvocationMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      MetricsBootstrapConfig metricsBootstrapConfig) {\n    super(meterRegistry, name, tags, metricsBootstrapConfig);\n    consumerSendRequestTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_CONSUMER_SEND)).register(meterRegistry);\n    consumerGetConnectionTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_CONSUMER_CONNECTION)).register(meterRegistry);\n    consumerEncodeRequestTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_CONSUMER_ENCODE_REQUEST))\n        .register(meterRegistry);\n    consumerDecodeResponseTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_CONSUMER_DECODE_RESPONSE))\n        .register(meterRegistry);\n    consumerWaitResponseTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_CONSUMER_WAIT)).register(meterRegistry);\n  }\n\n  @Override\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    super.onInvocationFinish(event);\n\n    InvocationStageTrace invocationStageTrace = event.getInvocation().getInvocationStageTrace();\n    consumerEncodeRequestTimer.record(invocationStageTrace.calcConsumerEncodeRequest(), TimeUnit.NANOSECONDS);\n    consumerSendRequestTimer.record(invocationStageTrace.calcConsumerSendRequest(), TimeUnit.NANOSECONDS);\n    consumerGetConnectionTimer.record(invocationStageTrace.calcConnection(), TimeUnit.NANOSECONDS);\n    consumerWaitResponseTimer.record(invocationStageTrace.calcWait(), TimeUnit.NANOSECONDS);\n    consumerDecodeResponseTimer.record(invocationStageTrace.calcConsumerDecodeResponse(), TimeUnit.NANOSECONDS);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ConsumerInvocationMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class ConsumerInvocationMeters extends AbstractInvocationMeters {\n  public ConsumerInvocationMeters(MeterRegistry meterRegistry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    super(meterRegistry, metricsBootstrapConfig);\n  }\n\n  @Override\n  protected AbstractInvocationMeter createMeter(String name, Tags tags) {\n    return new ConsumerInvocationMeter(registry, name, tags, this.metricsBootstrapConfig);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/EdgeInvocationMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\nimport io.micrometer.core.instrument.Timer;\n\npublic class EdgeInvocationMeter extends ConsumerInvocationMeter {\n  private final Timer providerDecodeRequestTimer;\n\n  private final Timer providerEncodeResponseTimer;\n\n  private final Timer sendResponseTimer;\n\n  public EdgeInvocationMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      MetricsBootstrapConfig metricsBootstrapConfig) {\n    super(meterRegistry, name, tags, metricsBootstrapConfig);\n    providerDecodeRequestTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_DECODE_REQUEST))\n        .register(meterRegistry);\n    providerEncodeResponseTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_ENCODE_RESPONSE))\n        .register(meterRegistry);\n    sendResponseTimer = Timer.builder(name).tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_SEND))\n        .register(meterRegistry);\n  }\n\n  @Override\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    super.onInvocationFinish(event);\n    InvocationStageTrace invocationStageTrace = event.getInvocation().getInvocationStageTrace();\n\n    providerDecodeRequestTimer.record(invocationStageTrace.calcProviderDecodeRequest(), TimeUnit.NANOSECONDS);\n    providerEncodeResponseTimer.record(invocationStageTrace.calcProviderEncodeResponse(), TimeUnit.NANOSECONDS);\n    sendResponseTimer.record(invocationStageTrace.calcProviderSendResponse(), TimeUnit.NANOSECONDS);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/EdgeInvocationMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class EdgeInvocationMeters extends ConsumerInvocationMeters {\n  public EdgeInvocationMeters(MeterRegistry meterRegistry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    super(meterRegistry, metricsBootstrapConfig);\n  }\n\n  @Override\n  protected AbstractInvocationMeter createMeter(String name, Tags tags) {\n    return new EdgeInvocationMeter(registry, name, tags, metricsBootstrapConfig);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/MeterInvocationConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\npublic interface MeterInvocationConst {\n  String INVOCATION_NAME = \"servicecomb.invocation\";\n\n  // consumer or producer\n  String TAG_ROLE = \"role\";\n\n  String TAG_OPERATION = \"operation\";\n\n  String TAG_TRANSPORT = \"transport\";\n\n  String TAG_TYPE = \"type\";\n\n  String TAG_STAGE = \"stage\";\n\n  String TAG_DISTRIBUTION = \"distribution\";\n\n  String TAG_STATUS = \"status\";\n\n  String EDGE_INVOCATION_NAME = \"EDGE\";\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\nimport io.micrometer.core.instrument.Timer;\n\npublic class ProducerInvocationMeter extends AbstractInvocationMeter {\n  private final Timer executorQueueTimer;\n\n  private final Timer executionTimer;\n\n  private final Timer providerDecodeRequestTimer;\n\n  private final Timer providerEncodeResponseTimer;\n\n  private final Timer sendResponseTimer;\n\n  public ProducerInvocationMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      MetricsBootstrapConfig metricsBootstrapConfig) {\n    super(meterRegistry, name, tags, metricsBootstrapConfig);\n    executorQueueTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_QUEUE))\n        .register(meterRegistry);\n    executionTimer = Timer.builder(name).tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_BUSINESS))\n        .register(meterRegistry);\n    providerDecodeRequestTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_DECODE_REQUEST))\n        .register(meterRegistry);\n    providerEncodeResponseTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_ENCODE_RESPONSE))\n        .register(meterRegistry);\n    sendResponseTimer = Timer.builder(name)\n        .tags(tags.and(MeterInvocationConst.TAG_TYPE, MeterInvocationConst.TAG_STAGE,\n            MeterInvocationConst.TAG_STAGE, InvocationStageTrace.STAGE_PROVIDER_SEND))\n        .register(meterRegistry);\n  }\n\n  @Override\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    super.onInvocationFinish(event);\n\n    InvocationStageTrace invocationStageTrace = event.getInvocation().getInvocationStageTrace();\n    executorQueueTimer.record(invocationStageTrace.calcQueue(), TimeUnit.NANOSECONDS);\n    executionTimer.record(invocationStageTrace.calcBusinessExecute(), TimeUnit.NANOSECONDS);\n    providerDecodeRequestTimer.record(invocationStageTrace.calcProviderDecodeRequest(), TimeUnit.NANOSECONDS);\n    providerEncodeResponseTimer.record(invocationStageTrace.calcProviderEncodeResponse(), TimeUnit.NANOSECONDS);\n    sendResponseTimer.record(invocationStageTrace.calcProviderSendResponse(), TimeUnit.NANOSECONDS);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.invocation;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class ProducerInvocationMeters extends AbstractInvocationMeters {\n  public ProducerInvocationMeters(MeterRegistry meterRegistry, MetricsBootstrapConfig metricsBootstrapConfig) {\n    super(meterRegistry, metricsBootstrapConfig);\n  }\n\n  @Override\n  protected AbstractInvocationMeter createMeter(String name, Tags tags) {\n    return new ProducerInvocationMeter(registry, name, tags, metricsBootstrapConfig);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/NetMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.commons.lang3.SystemUtils;\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.Tags;\n\npublic class NetMeter implements PeriodMeter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(NetMeter.class);\n\n  public static final String STATISTIC = \"statistic\";\n\n  public static final String INTERFACE = \"interface\";\n\n  public static final Tag TAG_RECEIVE = Tag.of(STATISTIC, \"receive\");\n\n  public static final Tag TAG_PACKETS_RECEIVE = Tag.of(STATISTIC, \"receivePackets\");\n\n  public static final Tag TAG_SEND = Tag.of(STATISTIC, \"send\");\n\n  public static final Tag TAG_PACKETS_SEND = Tag.of(STATISTIC, \"sendPackets\");\n\n  private final Map<String, InterfaceUsage> interfaceUsageMap = new ConcurrentHashMap<>();\n\n  private boolean isOsLinux = SystemUtils.IS_OS_LINUX;\n\n  protected final MeterRegistry meterRegistry;\n\n  protected final String name;\n\n  protected final Tags tags;\n\n  public NetMeter(MeterRegistry meterRegistry, String name, Tags tags) {\n    this.meterRegistry = meterRegistry;\n    this.name = name;\n    this.tags = tags;\n    poll(0, 0);\n  }\n\n  @VisibleForTesting\n  public void setOsLinux(boolean osLinux) {\n    isOsLinux = osLinux;\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    if (isOsLinux) {\n      refreshNet(secondInterval);\n    }\n  }\n\n  /*\n   * Inter-|   Receive                                                            |  Transmit\n   *  face |bytes      packets     errs drop fifo  frame      compressed multicast|bytes       packets     errs   drop  fifo colls carrier compressed\n   *  eth0: 2615248100 32148518    0    0    0     0          0          0         87333034794 21420267    0      0     0     0    0    0\n   *        0          1           2    3    4     5          6          7          8          9\n   */\n  protected void refreshNet(long secondInterval) {\n    try {\n      File file = new File(\"/proc/net/dev\");\n      List<String> netInfo = FileUtils.readLines(file, StandardCharsets.UTF_8);\n\n      //the first two lines is useless\n      for (int i = 2; i < netInfo.size(); i++) {\n        String interfaceData = netInfo.get(i);\n        String[] strings = interfaceData.split(\":\");\n        if (strings.length != 2) {\n          LOGGER.warn(\" there is something wrong with {} \", interfaceData);\n          continue;\n        }\n\n        String interfaceName = strings[0].trim();\n\n        InterfaceUsage interfaceUsage = interfaceUsageMap.computeIfAbsent(interfaceName,\n            key -> new InterfaceUsage(meterRegistry, name, tags, key));\n        interfaceUsage.update(strings[1], secondInterval);\n      }\n    } catch (IOException e) {\n      LOGGER.error(\"Failed to read net info/\", e);\n    }\n  }\n\n  public Map<String, InterfaceUsage> getInterfaceUsageMap() {\n    return interfaceUsageMap;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/OsMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os;\n\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\n/**\n * name=os type=cpu value = 0\n * name=os type=processCpu value = 0\n * name=os type=net interface=eth0 statistic=send value=100\n * name=os type=net interface=eth0 statistic=receive value=100\n * name=os type=net interface=eth0 statistic=sendPackets value=100\n * name=os type=net interface=eth0 statistic=receivePackets value=100\n */\npublic class OsMeter implements PeriodMeter {\n  public static final String OS_NAME = \"os\";\n\n  public static final String OS_TYPE = \"type\";\n\n  public static final String OS_TYPE_NET = \"net\";\n\n  private final SystemMeter systemMeter;\n\n  private final NetMeter netMeter;\n\n  public OsMeter(MeterRegistry meterRegistry) {\n    systemMeter = new SystemMeter(meterRegistry, OS_NAME);\n    netMeter = new NetMeter(meterRegistry, OS_NAME, Tags.of(OS_TYPE, OS_TYPE_NET));\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    systemMeter.poll(msNow, secondInterval);\n    netMeter.poll(msNow, secondInterval);\n  }\n\n  @VisibleForTesting\n  public SystemMeter getCpuMeter() {\n    return systemMeter;\n  }\n\n  @VisibleForTesting\n  public NetMeter getNetMeter() {\n    return netMeter;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/SystemMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os;\n\nimport java.lang.management.ManagementFactory;\n\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\n\nimport com.google.common.annotations.VisibleForTesting;\nimport com.sun.management.OperatingSystemMXBean;\n\nimport io.micrometer.core.instrument.Gauge;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class SystemMeter implements PeriodMeter {\n  public static final String SYSTEM_LOAD_AVERAGE = \"sla\";\n\n  public static final String CPU_USAGE = \"cpu\";\n\n  public static final String PROCESS_CPU_USAGE = \"processCpu\";\n\n  public static final String MEMORY_USAGE = \"memory\";\n\n  private OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);\n\n  public SystemMeter(MeterRegistry meterRegistry, String name) {\n    Gauge.builder(name, () -> getOsBean().getSystemLoadAverage())\n        .tags(Tags.of(OsMeter.OS_TYPE, SYSTEM_LOAD_AVERAGE))\n        .register(meterRegistry);\n\n    Gauge.builder(name, () -> getOsBean().getCpuLoad())\n        .tags(Tags.of(OsMeter.OS_TYPE, CPU_USAGE))\n        .register(meterRegistry);\n\n    Gauge.builder(name, () -> getOsBean().getProcessCpuLoad())\n        .tags(Tags.of(OsMeter.OS_TYPE, PROCESS_CPU_USAGE))\n        .register(meterRegistry);\n\n    Gauge.builder(name, () -> (getOsBean().getTotalMemorySize() - getOsBean().getFreeMemorySize())\n            / (double) getOsBean().getTotalMemorySize())\n        .tags(Tags.of(OsMeter.OS_TYPE, MEMORY_USAGE))\n        .register(meterRegistry);\n  }\n\n  @VisibleForTesting\n  public void setOsBean(OperatingSystemMXBean mock) {\n    this.osBean = mock;\n  }\n\n  private OperatingSystemMXBean getOsBean() {\n    return this.osBean;\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/InterfaceUsage.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os.net;\n\nimport static org.apache.servicecomb.metrics.core.meter.os.NetMeter.INTERFACE;\nimport static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_PACKETS_RECEIVE;\nimport static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_PACKETS_SEND;\nimport static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_RECEIVE;\nimport static org.apache.servicecomb.metrics.core.meter.os.NetMeter.TAG_SEND;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.micrometer.core.instrument.Gauge;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.Tags;\n\npublic class InterfaceUsage {\n  private final String interfaceName;\n\n  private final NetStat receive;\n\n  private final NetStat send;\n\n  private final NetStat packetsReceive;\n\n  private final NetStat packetsSend;\n\n  public InterfaceUsage(MeterRegistry meterRegistry, String name, Tags tags, String interfaceName) {\n    this.interfaceName = interfaceName;\n    tags = tags.and(Tag.of(INTERFACE, interfaceName));\n\n    // recv/Bps\n    receive = new NetStat(0);\n    Gauge.builder(name, receive::getRate).tags(tags.and(TAG_RECEIVE)).register(meterRegistry);\n    // send/Bps\n    send = new NetStat(8);\n    Gauge.builder(name, send::getRate).tags(tags.and(TAG_SEND)).register(meterRegistry);\n    // recv/pps\n    packetsReceive = new NetStat(1);\n    Gauge.builder(name, packetsReceive::getRate).tags(tags.and(TAG_PACKETS_RECEIVE)).register(meterRegistry);\n    // send/pps\n    packetsSend = new NetStat(9);\n    Gauge.builder(name, packetsSend::getRate).tags(tags.and(TAG_PACKETS_SEND)).register(meterRegistry);\n  }\n\n  public void update(String interfaceData, long secondInterval) {\n    String[] netInfo = interfaceData.trim().split(\"\\\\s+\");\n    receive.update(netInfo, secondInterval);\n    send.update(netInfo, secondInterval);\n    packetsReceive.update(netInfo, secondInterval);\n    packetsSend.update(netInfo, secondInterval);\n  }\n\n  @VisibleForTesting\n  public NetStat getReceive() {\n    return receive;\n  }\n\n  @VisibleForTesting\n  public NetStat getSend() {\n    return send;\n  }\n\n  @VisibleForTesting\n  public NetStat getPacketsReceive() {\n    return packetsReceive;\n  }\n\n  @VisibleForTesting\n  public NetStat getPacketsSend() {\n    return packetsSend;\n  }\n\n  public String getName() {\n    return interfaceName;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/os/net/NetStat.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os.net;\n\n\npublic class NetStat {\n  private final int index;\n\n  // send/recv bytes/packets\n  private long lastValue;\n\n  // Bps/pps\n  private double rate;\n\n  public NetStat(int index) {\n    this.index = index;\n  }\n\n  public void clearRate() {\n    rate = 0;\n  }\n\n  public void update(String[] netInfo, long secondInterval) {\n    long currentValue = Long.parseLong(netInfo[index]);\n    rate = (double) (currentValue - lastValue) / secondInterval;\n    lastValue = currentValue;\n  }\n\n  public long getLastValue() {\n    return lastValue;\n  }\n\n  public double getRate() {\n    return rate;\n  }\n\n  public int getIndex() {\n    return index;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/pool/ThreadPoolMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.pool;\n\nimport java.util.concurrent.ThreadPoolExecutor;\n\nimport org.apache.servicecomb.core.executor.ThreadPoolExecutorEx;\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\n\nimport io.micrometer.core.instrument.Gauge;\nimport io.micrometer.core.instrument.MeterRegistry;\n\npublic class ThreadPoolMeter implements PeriodMeter {\n  public static final String THREAD_POOL_METER = \"servicecomb.threadpool\";\n\n  public static final String ID = \"id\";\n\n  public static final String STAGE = \"stage\";\n\n  public static final String REJECTED_COUNT = \"rejectedCount\";\n\n  public static final String TASK_COUNT = \"taskCount\";\n\n  public static final String COMPLETED_TASK_COUNT = \"completedTaskCount\";\n\n  public static final String CURRENT_THREADS_BUSY = \"currentThreadsBusy\";\n\n  public static final String MAX_THREADS = \"maxThreads\";\n\n  public static final String POOL_SIZE = \"poolSize\";\n\n  public static final String CORE_POOL_SIZE = \"corePoolSize\";\n\n  public static final String QUEUE_SIZE = \"queueSize\";\n\n  private final ThreadPoolExecutor threadPoolExecutor;\n\n  private long currentTask;\n\n  private long lastTask;\n\n  private long currentCompletedTask;\n\n  private long lastCompletedTask;\n\n  public ThreadPoolMeter(MeterRegistry meterRegistry, String threadPoolName, ThreadPoolExecutor threadPoolExecutor) {\n    this.threadPoolExecutor = threadPoolExecutor;\n\n    Gauge.builder(THREAD_POOL_METER, () -> currentTask)\n        .tags(ID, threadPoolName, STAGE, TASK_COUNT)\n        .register(meterRegistry);\n    Gauge.builder(THREAD_POOL_METER, () -> currentCompletedTask)\n        .tags(ID, threadPoolName, STAGE, COMPLETED_TASK_COUNT)\n        .register(meterRegistry);\n    Gauge.builder(THREAD_POOL_METER, threadPoolExecutor::getActiveCount)\n        .tags(ID, threadPoolName, STAGE, CURRENT_THREADS_BUSY)\n        .register(meterRegistry);\n    Gauge.builder(THREAD_POOL_METER, threadPoolExecutor::getMaximumPoolSize)\n        .tags(ID, threadPoolName, STAGE, MAX_THREADS)\n        .register(meterRegistry);\n    Gauge.builder(THREAD_POOL_METER, threadPoolExecutor::getPoolSize)\n        .tags(ID, threadPoolName, STAGE, POOL_SIZE)\n        .register(meterRegistry);\n    Gauge.builder(THREAD_POOL_METER, threadPoolExecutor::getCorePoolSize)\n        .tags(ID, threadPoolName, STAGE, CORE_POOL_SIZE)\n        .register(meterRegistry);\n    Gauge.builder(THREAD_POOL_METER, () -> threadPoolExecutor.getQueue().size())\n        .tags(ID, threadPoolName, STAGE, QUEUE_SIZE)\n        .register(meterRegistry);\n\n    if (threadPoolExecutor instanceof ThreadPoolExecutorEx) {\n      Gauge.builder(THREAD_POOL_METER, () -> ((ThreadPoolExecutorEx) (threadPoolExecutor)).getRejectedCount())\n          .tags(ID, threadPoolName, STAGE, REJECTED_COUNT)\n          .register(meterRegistry);\n    }\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    long temp = threadPoolExecutor.getTaskCount();\n    currentTask = temp - lastTask;\n    lastTask = temp;\n\n    temp = threadPoolExecutor.getCompletedTaskCount();\n    currentCompletedTask = temp - lastCompletedTask;\n    lastCompletedTask = temp;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/vertx/EndpointMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.vertx;\n\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\n\nimport io.micrometer.core.instrument.Gauge;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.Tags;\n\npublic class EndpointMeter implements PeriodMeter {\n  private static final double SNV_MILLI_SECONDS = 1.0 / TimeUnit.MILLISECONDS.toNanos(1L);\n\n  public static final String ADDRESS = \"address\";\n\n  public static final String STATISTIC = \"statistic\";\n\n  public static final String CONNECT_COUNT = \"connectCount\";\n\n  public static final String DISCONNECT_COUNT = \"disconnectCount\";\n\n  public static final String CONNECTIONS = \"connections\";\n\n  public static final String BYTES_READ = \"bytesRead\";\n\n  public static final String BYTES_WRITTEN = \"bytesWritten\";\n\n  public static final String REQUESTS = \"requests\";\n\n  public static final String LATENCY = \"latency\";\n\n  protected DefaultEndpointMetric metric;\n\n  protected final MeterRegistry meterRegistry;\n\n  private final Gauge connectCount;\n\n  private final Gauge disconnectCount;\n\n  private final Gauge connections;\n\n  private final Gauge bytesRead;\n\n  private final Gauge bytesWritten;\n\n  private final Gauge requests;\n\n  private final Gauge latency;\n\n  private long currentConnectCount;\n\n  private long lastConnectCount;\n\n  private long currentDisconnectCount;\n\n  private long lastDisconnectCount;\n\n  private long currentBytesRead;\n\n  private long lastBytesRead;\n\n  private long currentBytesWritten;\n\n  private long lastBytesWritten;\n\n  private long currentRequests;\n\n  private long lastRequests;\n\n  private long currentRequestsForLatency;\n\n  private long lastRequestsForLatency;\n\n  private long currentLatency;\n\n  private long lastLatency;\n\n  public EndpointMeter(MeterRegistry meterRegistry, String name, Tags tags, DefaultEndpointMetric metric) {\n    this.meterRegistry = meterRegistry;\n    this.metric = metric;\n\n    tags = tags.and(Tag.of(ADDRESS, metric.getAddress()));\n    connectCount = Gauge.builder(name, () -> currentConnectCount)\n        .tags(tags.and(Tag.of(STATISTIC, CONNECT_COUNT)))\n        .register(meterRegistry);\n    disconnectCount = Gauge.builder(name, () -> currentDisconnectCount)\n        .tags(tags.and(Tag.of(STATISTIC, DISCONNECT_COUNT)))\n        .register(meterRegistry);\n    connections = Gauge.builder(name, () -> this.metric.getConnectCount() - this.metric.getDisconnectCount())\n        .tags(tags.and(Tag.of(STATISTIC, CONNECTIONS)))\n        .register(meterRegistry);\n    bytesRead = Gauge.builder(name, () -> currentBytesRead)\n        .tags(tags.and(Tag.of(STATISTIC, BYTES_READ)))\n        .register(meterRegistry);\n    bytesWritten = Gauge.builder(name, () -> currentBytesWritten)\n        .tags(tags.and(Tag.of(STATISTIC, BYTES_WRITTEN)))\n        .register(meterRegistry);\n    requests = Gauge.builder(name, () -> currentRequests)\n        .tags(tags.and(Tag.of(STATISTIC, REQUESTS)))\n        .register(meterRegistry);\n    latency = Gauge.builder(name, () -> currentRequestsForLatency == 0 ? 0 :\n            (currentLatency) / ((double) (currentRequestsForLatency)) * SNV_MILLI_SECONDS)\n        .tags(tags.and(Tag.of(STATISTIC, LATENCY)))\n        .register(meterRegistry);\n  }\n\n  public DefaultEndpointMetric getMetric() {\n    return metric;\n  }\n\n  public void destroy() {\n    this.meterRegistry.remove(connectCount);\n    this.meterRegistry.remove(disconnectCount);\n    this.meterRegistry.remove(connections);\n    this.meterRegistry.remove(bytesRead);\n    this.meterRegistry.remove(bytesWritten);\n    this.meterRegistry.remove(requests);\n    this.meterRegistry.remove(latency);\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    long temp = metric.getConnectCount();\n    currentConnectCount = temp - lastConnectCount;\n    lastConnectCount = temp;\n\n    temp = metric.getDisconnectCount();\n    currentDisconnectCount = temp - lastDisconnectCount;\n    lastDisconnectCount = temp;\n\n    temp = metric.getBytesRead();\n    currentBytesRead = temp - lastBytesRead;\n    lastBytesRead = temp;\n\n    temp = metric.getBytesWritten();\n    currentBytesWritten = temp - lastBytesWritten;\n    lastBytesWritten = temp;\n\n    temp = metric.getRequests();\n    currentRequests = temp - lastRequests;\n    lastRequests = temp;\n\n    temp = metric.getRequests();\n    currentRequestsForLatency = temp - lastRequestsForLatency;\n    lastRequestsForLatency = temp;\n    temp = metric.getLatency();\n    currentLatency = temp - lastLatency;\n    lastLatency = temp;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/vertx/HttpClientEndpointMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.vertx;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\n\nimport io.micrometer.core.instrument.Gauge;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.Tags;\n\npublic class HttpClientEndpointMeter extends EndpointMeter {\n  public static final String QUEUE_COUNT = \"queueCount\";\n\n  private final Gauge queueCount;\n\n  private long currentQueueCount;\n\n  public HttpClientEndpointMeter(MeterRegistry meterRegistry, String name, Tags tags, DefaultEndpointMetric metric) {\n    super(meterRegistry, name, tags, metric);\n    queueCount = Gauge.builder(name, () -> currentQueueCount)\n        .tags(tags.and(Tag.of(STATISTIC, QUEUE_COUNT), Tag.of(ADDRESS, metric.getAddress())))\n        .register(meterRegistry);\n  }\n\n  @Override\n  public void destroy() {\n    super.destroy();\n    this.meterRegistry.remove(queueCount);\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    super.poll(msNow, secondInterval);\n\n    currentQueueCount = ((DefaultClientEndpointMetric) metric).getQueueCount();\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/vertx/HttpClientEndpointsMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.vertx;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class HttpClientEndpointsMeter extends VertxEndpointsMeter {\n  public <T extends DefaultEndpointMetric> HttpClientEndpointsMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      DefaultClientEndpointMetricManager clientEndpointMetricManager) {\n    super(meterRegistry, name, tags, clientEndpointMetricManager.getClientEndpointMetricMap());\n  }\n\n  @Override\n  protected EndpointMeter createEndpointMeter(DefaultEndpointMetric metric) {\n    return new HttpClientEndpointMeter(meterRegistry, name, tags, metric);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/vertx/ServerEndpointMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.vertx;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric;\n\nimport io.micrometer.core.instrument.Gauge;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.Tags;\n\npublic class ServerEndpointMeter extends EndpointMeter {\n  public static final String REJECT_BY_CONNECTION_LIMIT = \"rejectByConnectionLimit\";\n\n  private final Gauge rejectByConnectionLimit;\n\n  private long lastRejectByConnectionLimit;\n\n  private long currentRejectByConnectionLimit;\n\n  public ServerEndpointMeter(MeterRegistry meterRegistry, String name, Tags tags, DefaultEndpointMetric metric) {\n    super(meterRegistry, name, tags, metric);\n    rejectByConnectionLimit = Gauge.builder(name, () -> currentRejectByConnectionLimit)\n        .tags(tags.and(Tag.of(STATISTIC, REJECT_BY_CONNECTION_LIMIT), Tag.of(ADDRESS, metric.getAddress())))\n        .register(meterRegistry);\n  }\n\n  @Override\n  public void destroy() {\n    super.destroy();\n    this.meterRegistry.remove(rejectByConnectionLimit);\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    super.poll(msNow, secondInterval);\n\n    long current = ((DefaultServerEndpointMetric) metric).getRejectByConnectionLimitCount();\n    currentRejectByConnectionLimit = current - lastRejectByConnectionLimit;\n    lastRejectByConnectionLimit = current;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/vertx/ServerEndpointsMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.vertx;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class ServerEndpointsMeter extends VertxEndpointsMeter {\n  public <T extends DefaultEndpointMetric> ServerEndpointsMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      Map<String, T> endpointMetricMap) {\n    super(meterRegistry, name, tags, endpointMetricMap);\n  }\n\n  @Override\n  protected EndpointMeter createEndpointMeter(DefaultEndpointMetric metric) {\n    return new ServerEndpointMeter(meterRegistry, name, tags, metric);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/vertx/VertxEndpointsMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.vertx;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.metrics.meter.PeriodMeter;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\n\npublic class VertxEndpointsMeter implements PeriodMeter {\n  private final Map<String, DefaultEndpointMetric> endpointMetricMap;\n\n  protected final MeterRegistry meterRegistry;\n\n  protected final String name;\n\n  protected final Tags tags;\n\n  private final Map<String, EndpointMeter> endpointMeterMap = new ConcurrentHashMapEx<>();\n\n  @SuppressWarnings(\"unchecked\")\n  public <T extends DefaultEndpointMetric> VertxEndpointsMeter(MeterRegistry meterRegistry, String name, Tags tags,\n      Map<String, T> endpointMetricMap) {\n    this.meterRegistry = meterRegistry;\n    this.name = name;\n    this.tags = tags;\n    this.endpointMetricMap = (Map<String, DefaultEndpointMetric>) endpointMetricMap;\n  }\n\n  private void syncMeters(long msNow, long secondInterval) {\n    for (EndpointMeter meter : endpointMeterMap.values()) {\n      if (!endpointMetricMap.containsKey(meter.getMetric().getAddress())) {\n        EndpointMeter removed = endpointMeterMap.remove(meter.getMetric().getAddress());\n        removed.destroy();\n      }\n    }\n    for (DefaultEndpointMetric metric : endpointMetricMap.values()) {\n      EndpointMeter updated = endpointMeterMap.computeIfAbsent(metric.getAddress(),\n          address -> createEndpointMeter(metric));\n      updated.poll(msNow, secondInterval);\n    }\n  }\n\n  protected EndpointMeter createEndpointMeter(DefaultEndpointMetric metric) {\n    return new EndpointMeter(meterRegistry, name, tags, metric);\n  }\n\n  @Override\n  public void poll(long msNow, long secondInterval) {\n    syncMeters(msNow, secondInterval);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/AbstractMeasurementNodeLogPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\n\npublic abstract class AbstractMeasurementNodeLogPublisher {\n  protected StringBuilder sb;\n\n  protected MeasurementNode measurementNode;\n\n  private final boolean exists;\n\n  public AbstractMeasurementNodeLogPublisher(MeasurementTree tree, StringBuilder sb, String... childNames) {\n    this.sb = sb;\n    measurementNode = tree.findChild(childNames);\n    exists = measurementNode != null && !measurementNode.getMeasurements().isEmpty();\n  }\n\n  public boolean isExists() {\n    return exists;\n  }\n\n  public abstract void print(boolean printDetail);\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/ClientEndpointsLogPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.VertxMetersInitializer;\nimport org.apache.servicecomb.metrics.core.meter.vertx.EndpointMeter;\nimport org.apache.servicecomb.metrics.core.meter.vertx.HttpClientEndpointMeter;\n\npublic class ClientEndpointsLogPublisher extends AbstractMeasurementNodeLogPublisher {\n  public ClientEndpointsLogPublisher(MeasurementTree tree, StringBuilder sb, String meterName) {\n    super(tree, sb, VertxMetersInitializer.VERTX_ENDPOINTS, meterName);\n  }\n\n  @Override\n  public void print(boolean printDetail) {\n    if (!printDetail) {\n      return;\n    }\n    appendLine(sb, \"    client.endpoints:\");\n    appendLine(sb,\n        \"      connectCount disconnectCount queue         connections requests latency send(Bps) receive(Bps) remote\");\n\n    List<MeasurementNode> measurements = new ArrayList<>(measurementNode.getChildren().size());\n    measurements.addAll(measurementNode.getChildren().values());\n    measurements.sort(MeasurementNode::compareTo);\n    for (MeasurementNode address : measurements) {\n      appendLine(sb, \"      %-12.0f %-15.0f %-13.0f %-11.0f %-8.0f %-7.0f %-9s %-12s %s\",\n          address.findChild(EndpointMeter.CONNECT_COUNT).summary(),\n          address.findChild(EndpointMeter.DISCONNECT_COUNT).summary(),\n          address.findChild(HttpClientEndpointMeter.QUEUE_COUNT).summary(),\n          address.findChild(EndpointMeter.CONNECTIONS).summary(),\n          address.findChild(EndpointMeter.REQUESTS).summary(),\n          address.findChild(EndpointMeter.LATENCY).summary(),\n          NetUtils.humanReadableBytes((long) address.findChild(EndpointMeter.BYTES_WRITTEN).summary()),\n          NetUtils.humanReadableBytes((long) address.findChild(EndpointMeter.BYTES_READ).summary()),\n          address.getName()\n      );\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/DefaultLogPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.apache.servicecomb.foundation.metrics.PolledEvent;\nimport org.apache.servicecomb.foundation.metrics.meter.LatencyDistributionConfig;\nimport org.apache.servicecomb.foundation.metrics.meter.LatencyScopeConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.metrics.core.VertxMetersInitializer;\nimport org.apache.servicecomb.metrics.core.meter.os.NetMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.OsMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.SystemMeter;\nimport org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerf;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroup;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.PerfInfo;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.base.Strings;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\nimport io.micrometer.core.instrument.Meter;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.vertx.core.Vertx;\n\npublic class DefaultLogPublisher implements MetricsInitializer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(\"scb-metrics\");\n\n  public static final String ENABLED = \"servicecomb.metrics.publisher.defaultLog.enabled\";\n\n  // for a client, maybe will connect to too many endpoints, so default not print detail, just print summary\n  public static final String ENDPOINTS_CLIENT_DETAIL_ENABLED = \"servicecomb.metrics.publisher.defaultLog.endpoints.client.detail.enabled\";\n\n  private static final String FIRST_LINE_SIMPLE_FORMAT = \"  %-11s\\n\";\n\n  private static final String SIMPLE_FORMAT = \"              %-8.1f %-18s %s%s\\n\";\n\n  //details\n  private static final String PRODUCER_DETAILS_FORMAT = \"\"\n      + \"        prepare: %-18s decode-request       : %-18s queue : %-18s business-execute: %s\\n\"\n      + \"        encode-response: %-18s send: %-18s\\n\";\n\n  private static final String CONSUMER_DETAILS_FORMAT = \"\"\n      + \"        prepare     : %-18s connection : %-18s encode-request: %-18s send     : %s\\n\"\n      + \"        wait  : %-18s decode-response    : %-18s\\n\";\n\n  private static final String EDGE_DETAILS_FORMAT = \"\"\n      + \"        prepare     : %-18s provider-decode       : %-18s connection : %-18s consumer-encode : %s\\n\"\n      + \"        consumer-send : %-18s wait     : %-18s consumer-decode  : %-18s provider-encode    : %s\\n\"\n      + \"        provider-send    : %-18s\\n\";\n\n  private LatencyDistributionConfig latencyDistributionConfig;\n\n  /**\n   * if config is 0,1,10,100 then header will be:<br>\n   *   [0,1)  [1,10) [10,100) [100,)\n   */\n  private String latencyDistributionHeader = \"\";\n\n  /**\n   * if config is 0,1,10,100 then format will be:<br>\n   *   %-7d %-7d %-9d %-7d\n   */\n  private String latencyDistributionFormat = \"\";\n\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    if (!environment.getProperty(ENABLED, boolean.class, false)) {\n      return;\n    }\n\n    initLatencyDistribution(config);\n\n    eventBus.register(this);\n  }\n\n  private void initLatencyDistribution(MetricsBootstrapConfig config) {\n    // default length is 7 which include a space, one minute 999999 requests, TPS is 16666, mostly it's enough\n    int leastLatencyScopeStrLength = config.getMinScopeLength();\n\n    latencyDistributionConfig = new LatencyDistributionConfig(config.getLatencyDistribution());\n    String header;\n    for (LatencyScopeConfig scopeConfig : latencyDistributionConfig.getScopeConfigs()) {\n      if (scopeConfig.getMsMax() == LatencyDistributionConfig.MAX_LATENCY) {\n        header = String.format(\"[%d,) \", scopeConfig.getMsMin());\n      } else {\n        header = String.format(\"[%d,%d) \", scopeConfig.getMsMin(), scopeConfig.getMsMax());\n      }\n      header = Strings.padEnd(header, leastLatencyScopeStrLength, ' ');\n      latencyDistributionHeader += header;\n\n      String format = \"%-\" + (header.length() - 1) + \"d \";\n      latencyDistributionFormat += format;\n    }\n  }\n\n  @Subscribe\n  public void onPolledEvent(PolledEvent event) {\n    try {\n      printLog(event.getMeters());\n    } catch (Throwable e) {\n      // make development easier\n      LOGGER.error(\"Failed to print perf log.\", e);\n    }\n  }\n\n  protected void printLog(List<Meter> meters) {\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"\\n\");\n    PublishModelFactory factory = new PublishModelFactory(meters);\n    DefaultPublishModel model = factory.createDefaultPublishModel();\n\n    printOsLog(factory.getTree(), sb);\n    printVertxMetrics(factory.getTree(), sb);\n    printThreadPoolMetrics(model, sb);\n\n    printConsumerLog(model, sb);\n    printProducerLog(model, sb);\n    printEdgeLog(model, sb);\n\n    LOGGER.info(sb.toString());\n  }\n\n  protected void printOsLog(MeasurementTree tree, StringBuilder sb) {\n    MeasurementNode osNode = tree.findChild(OsMeter.OS_NAME);\n    if (osNode == null || osNode.getMeasurements().isEmpty()) {\n      return;\n    }\n\n    appendLine(sb, \"os:\");\n    printCpuLog(sb, osNode);\n    printNetLog(sb, osNode);\n  }\n\n  private void printNetLog(StringBuilder sb, MeasurementNode osNode) {\n    MeasurementNode netNode = osNode.findChild(OsMeter.OS_TYPE_NET);\n    if (netNode == null || netNode.getMeasurements().isEmpty()) {\n      return;\n    }\n\n    appendLine(sb, \"  net:\");\n    appendLine(sb, \"    send(Bps)    recv(Bps)    send(pps)    recv(pps)    interface\");\n\n    StringBuilder tmpSb = new StringBuilder();\n    for (MeasurementNode interfaceNode : netNode.getChildren().values()) {\n      double sendRate = interfaceNode.findChild(NetMeter.TAG_SEND.getValue()).summary();\n      double sendPacketsRate = interfaceNode.findChild(NetMeter.TAG_PACKETS_SEND.getValue()).summary();\n      double receiveRate = interfaceNode.findChild(NetMeter.TAG_RECEIVE.getValue()).summary();\n      double receivePacketsRate = interfaceNode.findChild(NetMeter.TAG_PACKETS_RECEIVE.getValue()).summary();\n      if (sendRate == 0 && receiveRate == 0 && receivePacketsRate == 0 && sendPacketsRate == 0) {\n        continue;\n      }\n      appendLine(tmpSb, \"    %-12s %-12s %-12s %-12s %s\",\n          NetUtils.humanReadableBytes((long) sendRate),\n          NetUtils.humanReadableBytes((long) receiveRate),\n          NetUtils.humanReadableBytes((long) sendPacketsRate),\n          NetUtils.humanReadableBytes((long) receivePacketsRate),\n          interfaceNode.getName());\n    }\n    if (tmpSb.length() != 0) {\n      sb.append(tmpSb);\n    }\n  }\n\n  private void printCpuLog(StringBuilder sb, MeasurementNode osNode) {\n    MeasurementNode cpuNode = osNode.findChild(SystemMeter.CPU_USAGE);\n    MeasurementNode processNode = osNode.findChild(SystemMeter.PROCESS_CPU_USAGE);\n    MeasurementNode memoryNode = osNode.findChild(SystemMeter.MEMORY_USAGE);\n    MeasurementNode slaNode = osNode.findChild(SystemMeter.SYSTEM_LOAD_AVERAGE);\n    appendLine(sb, \"  cpu:\");\n    appendLine(sb, \"    all usage: %.2f%%    process usage: %.2f%%    sla: %.2f    memory usage: %.2f%%\",\n        cpuNode.summary() * 100, processNode.summary() * 100,\n        slaNode.summary(), memoryNode.summary() * 100);\n  }\n\n  protected void printThreadPoolMetrics(DefaultPublishModel model, StringBuilder sb) {\n    if (model.getThreadPools().isEmpty()) {\n      return;\n    }\n    sb.append(\"threadPool:\\n\");\n    sb.append(\"  coreSize maxThreads poolSize currentBusy rejected queueSize taskCount taskFinished name\\n\");\n    for (Entry<String, ThreadPoolPublishModel> entry : model.getThreadPools().entrySet()) {\n      ThreadPoolPublishModel threadPoolPublishModel = entry.getValue();\n      sb.append(String.format(\"  %-8d %-10d %-8d %-11d %-8.0f %-9d %-9.1f %-12.1f %s\\n\",\n          threadPoolPublishModel.getCorePoolSize(),\n          threadPoolPublishModel.getMaxThreads(),\n          threadPoolPublishModel.getPoolSize(),\n          threadPoolPublishModel.getCurrentThreadsBusy(),\n          threadPoolPublishModel.getRejected(),\n          threadPoolPublishModel.getQueueSize(),\n          threadPoolPublishModel.getAvgTaskCount(),\n          threadPoolPublishModel.getAvgCompletedTaskCount(),\n          entry.getKey()));\n    }\n  }\n\n  protected void printEdgeLog(DefaultPublishModel model, StringBuilder sb) {\n    OperationPerfGroups edgePerf = model.getEdge().getOperationPerfGroups();\n    if (edgePerf == null) {\n      return;\n    }\n    sb.append(\"\"\n            + \"edge:\\n\"\n            + \" simple:\\n\"\n            + \"  status      requests      latency       \")\n        .append(latencyDistributionHeader)\n        .append(\"operation\\n\");\n    StringBuilder detailsBuilder = new StringBuilder();\n    //print sample\n    for (Map<String, OperationPerfGroup> statusMap : edgePerf.getGroups().values()) {\n      for (OperationPerfGroup perfGroup : statusMap.values()) {\n        //append sample\n        sb.append(printSamplePerf(perfGroup));\n        //append details\n        detailsBuilder.append(printEdgeDetailsPerf(perfGroup));\n      }\n    }\n    sb.append(\" details:\\n\").append(detailsBuilder);\n  }\n\n  protected void printConsumerLog(DefaultPublishModel model, StringBuilder sb) {\n    OperationPerfGroups consumerPerf = model.getConsumer().getOperationPerfGroups();\n    if (consumerPerf == null) {\n      return;\n    }\n    sb.append(\"\"\n            + \"consumer:\\n\"\n            + \" simple:\\n\"\n            + \"  status      requests      latency       \")\n        .append(latencyDistributionHeader)\n        .append(\"operation\\n\");\n    StringBuilder detailsBuilder = new StringBuilder();\n    //print sample\n    for (Map<String, OperationPerfGroup> statusMap : consumerPerf.getGroups().values()) {\n      for (OperationPerfGroup perfGroup : statusMap.values()) {\n        //append sample\n        sb.append(printSamplePerf(perfGroup));\n        //append details\n        detailsBuilder.append(printConsumerDetailsPerf(perfGroup));\n      }\n    }\n    sb.append(\" details:\\n\").append(detailsBuilder);\n  }\n\n  protected void printProducerLog(DefaultPublishModel model, StringBuilder sb) {\n    OperationPerfGroups producerPerf = model.getProducer().getOperationPerfGroups();\n    if (producerPerf == null) {\n      return;\n    }\n    sb.append(\"\"\n            + \"producer:\\n\"\n            + \" simple:\\n\"\n            + \"  status      requests      latency       \")\n        .append(latencyDistributionHeader)\n        .append(\"operation\\n\");\n    // use detailsBuilder, we can traverse the map only once\n    StringBuilder detailsBuilder = new StringBuilder();\n    //print sample\n    for (Map<String, OperationPerfGroup> statusMap : producerPerf.getGroups().values()) {\n      for (OperationPerfGroup perfGroup : statusMap.values()) {\n        //append sample\n        sb.append(printSamplePerf(perfGroup));\n        //append details\n        detailsBuilder.append(printProducerDetailsPerf(perfGroup));\n      }\n    }\n    //print details\n    sb.append(\" details:\\n\").append(detailsBuilder);\n  }\n\n  private StringBuilder printSamplePerf(OperationPerfGroup perfGroup) {\n    StringBuilder sb = new StringBuilder();\n    String status = perfGroup.getTransport() + \".\" + perfGroup.getStatus() + \":\";\n    sb.append(String.format(FIRST_LINE_SIMPLE_FORMAT, status));\n\n    for (int i = 0; i < perfGroup.getOperationPerfs().size(); i++) {\n      OperationPerf operationPerf = perfGroup.getOperationPerfs().get(i);\n      if (isIgnoreEmptyPerf(operationPerf)) {\n        continue;\n      }\n      PerfInfo stageTotal = operationPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n      sb.append(String.format(SIMPLE_FORMAT, stageTotal.getTotalRequests(),\n          getDetailsFromPerf(stageTotal),\n          formatLatencyDistribution(operationPerf),\n          operationPerf.getOperation()));\n    }\n    OperationPerf summaryOperation = perfGroup.getSummary();\n    PerfInfo stageSummaryTotal = summaryOperation.findStage(InvocationStageTrace.STAGE_TOTAL);\n    //print summary\n    sb.append(String.format(SIMPLE_FORMAT, stageSummaryTotal.getTotalRequests(),\n        getDetailsFromPerf(stageSummaryTotal),\n        formatLatencyDistribution(summaryOperation),\n        \"(summary)\"));\n    return sb;\n  }\n\n  private String formatLatencyDistribution(OperationPerf operationPerf) {\n    return String.format(latencyDistributionFormat, (Object[]) operationPerf.getLatencyDistribution());\n  }\n\n  private StringBuilder printProducerDetailsPerf(OperationPerfGroup perfGroup) {\n    StringBuilder sb = new StringBuilder();\n    //append rest.\"200\":\n    sb.append(\"    \")\n        .append(perfGroup.getTransport())\n        .append(\".\")\n        .append(perfGroup.getStatus())\n        .append(\":\\n\");\n    PerfInfo prepare, queue, providerDecode, providerEncode, execute, sendResp;\n    for (OperationPerf operationPerf : perfGroup.getOperationPerfs()) {\n      if (isIgnoreEmptyPerf(operationPerf)) {\n        continue;\n      }\n      prepare = operationPerf.findStage(InvocationStageTrace.STAGE_PREPARE);\n      queue = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_QUEUE);\n      providerDecode = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_DECODE_REQUEST);\n      providerEncode = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_ENCODE_RESPONSE);\n      execute = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_BUSINESS);\n      sendResp = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_SEND);\n\n      sb.append(\"      \")\n          .append(operationPerf.getOperation())\n          .append(\":\\n\")\n          .append(String.format(PRODUCER_DETAILS_FORMAT,\n              getDetailsFromPerf(prepare),\n              getDetailsFromPerf(providerDecode),\n              getDetailsFromPerf(queue),\n              getDetailsFromPerf(execute),\n              getDetailsFromPerf(providerEncode),\n              getDetailsFromPerf(sendResp)\n          ));\n    }\n\n    return sb;\n  }\n\n  private StringBuilder printConsumerDetailsPerf(OperationPerfGroup perfGroup) {\n    StringBuilder sb = new StringBuilder();\n    //append rest.\"200\":\n    sb.append(\"    \")\n        .append(perfGroup.getTransport())\n        .append(\".\")\n        .append(perfGroup.getStatus())\n        .append(\":\\n\");\n\n    PerfInfo prepare, encodeRequest, decodeResponse, sendReq, getConnect,\n        waitResp;\n    for (OperationPerf operationPerf : perfGroup.getOperationPerfs()) {\n      if (isIgnoreEmptyPerf(operationPerf)) {\n        continue;\n      }\n      prepare = operationPerf.findStage(InvocationStageTrace.STAGE_PREPARE);\n      encodeRequest = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_ENCODE_REQUEST);\n      decodeResponse = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_DECODE_RESPONSE);\n      sendReq = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_SEND);\n      getConnect = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_CONNECTION);\n      waitResp = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_WAIT);\n\n      sb.append(\"      \")\n          .append(operationPerf.getOperation())\n          .append(\":\\n\")\n          .append(String.format(CONSUMER_DETAILS_FORMAT,\n              getDetailsFromPerf(prepare),\n              getDetailsFromPerf(getConnect),\n              getDetailsFromPerf(encodeRequest),\n              getDetailsFromPerf(sendReq),\n              getDetailsFromPerf(waitResp),\n              getDetailsFromPerf(decodeResponse)\n          ));\n    }\n\n    return sb;\n  }\n\n  private StringBuilder printEdgeDetailsPerf(OperationPerfGroup perfGroup) {\n    StringBuilder sb = new StringBuilder();\n    //append rest.\"200\":\n    sb.append(\"    \")\n        .append(perfGroup.getTransport())\n        .append(\".\")\n        .append(perfGroup.getStatus())\n        .append(\":\\n\");\n\n    PerfInfo prepare, connection, decodeProviderRequest, encodeProviderResponse,\n        encodeConsumerRequest, decodeConsumerResponse, sendReq, getConnect,\n        waitResp, sendResp;\n    for (OperationPerf operationPerf : perfGroup.getOperationPerfs()) {\n      if (isIgnoreEmptyPerf(operationPerf)) {\n        continue;\n      }\n      prepare = operationPerf.findStage(InvocationStageTrace.STAGE_PREPARE);\n      connection = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_CONNECTION);\n      decodeProviderRequest = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_DECODE_REQUEST);\n      encodeProviderResponse = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_ENCODE_RESPONSE);\n      encodeConsumerRequest = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_ENCODE_REQUEST);\n      sendReq = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_SEND);\n      decodeConsumerResponse = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_DECODE_RESPONSE);\n      waitResp = operationPerf.findStage(InvocationStageTrace.STAGE_CONSUMER_WAIT);\n      sendResp = operationPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_SEND);\n\n      sb.append(\"      \")\n          .append(operationPerf.getOperation())\n          .append(\":\\n\")\n          .append(String.format(EDGE_DETAILS_FORMAT,\n              getDetailsFromPerf(prepare),\n              getDetailsFromPerf(decodeProviderRequest),\n              getDetailsFromPerf(connection),\n              getDetailsFromPerf(encodeConsumerRequest),\n              getDetailsFromPerf(sendReq),\n              getDetailsFromPerf(waitResp),\n              getDetailsFromPerf(decodeConsumerResponse),\n              getDetailsFromPerf(encodeProviderResponse),\n              getDetailsFromPerf(sendResp)\n          ));\n    }\n\n    return sb;\n  }\n\n  private boolean isIgnoreEmptyPerf(OperationPerf operationPerf) {\n    PerfInfo stageTotal = operationPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n    // max latency is calculated in ring algorithm, maybe not 0\n    if (Double.compare(0D, stageTotal.getTotalRequests()) == 0\n        && Double.compare(0D, stageTotal.getMsMaxLatency()) == 0) {\n      return true;\n    }\n    return false;\n  }\n\n  protected void printVertxMetrics(MeasurementTree tree, StringBuilder sb) {\n    appendLine(sb, \"vertx:\");\n\n    appendLine(sb, \"  instances:\");\n    appendLine(sb, \"    name       eventLoopContext-created\");\n    for (Entry<String, Vertx> entry : VertxUtils.getVertxMap().entrySet()) {\n      appendLine(sb, \"    %-10s %d\",\n          entry.getKey(),\n          // TODO will be fixed by next vertx update.entry.getValue().getEventLoopContextCreatedCount()\n          0);\n    }\n\n    ClientEndpointsLogPublisher client = new ClientEndpointsLogPublisher(tree, sb,\n        VertxMetersInitializer.ENDPOINTS_CLIENT);\n    ServerEndpointsLogPublisher server = new ServerEndpointsLogPublisher(tree, sb,\n        VertxMetersInitializer.ENDPOINTS_SERVER);\n    if (client.isExists() || server.isExists()) {\n      appendLine(sb, \"  transport:\");\n      if (client.isExists()) {\n        client.print(environment.getProperty(ENDPOINTS_CLIENT_DETAIL_ENABLED, boolean.class, true));\n      }\n\n      if (server.isExists()) {\n        server.print(true);\n      }\n    }\n  }\n\n  private static String getDetailsFromPerf(PerfInfo perfInfo) {\n    String result = \"\";\n    if (perfInfo != null) {\n      result = String.format(\"%.3f/%.3f\", perfInfo.calcMsLatency(), perfInfo.getMsMaxLatency());\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/PublishModelFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.metrics.publish.DefaultTagFinder;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.VertxMetersInitializer;\nimport org.apache.servicecomb.metrics.core.meter.ThreadPoolMonitorPublishModelFactory;\nimport org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;\nimport org.apache.servicecomb.metrics.core.meter.os.NetMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.OsMeter;\nimport org.apache.servicecomb.metrics.core.meter.pool.ThreadPoolMeter;\nimport org.apache.servicecomb.metrics.core.meter.vertx.EndpointMeter;\nimport org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\n\nimport io.micrometer.core.instrument.Meter;\n\npublic class PublishModelFactory {\n  private final MeasurementTree tree;\n\n  public PublishModelFactory(List<Meter> meters) {\n    tree = createMeasurementTree(meters);\n  }\n\n  protected MeasurementTree createMeasurementTree(List<Meter> meters) {\n    MeasurementGroupConfig groupConfig = createMeasurementGroupConfig();\n\n    MeasurementTree tree = new MeasurementTree();\n    tree.from(meters.iterator(), groupConfig);\n    return tree;\n  }\n\n  public MeasurementTree getTree() {\n    return tree;\n  }\n\n  protected MeasurementGroupConfig createMeasurementGroupConfig() {\n    MeasurementGroupConfig groupConfig = new MeasurementGroupConfig();\n    groupConfig.addGroup(MeterInvocationConst.INVOCATION_NAME,\n        MeterInvocationConst.TAG_ROLE,\n        MeterInvocationConst.TAG_TRANSPORT,\n        MeterInvocationConst.TAG_OPERATION,\n        MeterInvocationConst.TAG_STATUS,\n        MeterInvocationConst.TAG_TYPE,\n        new DefaultTagFinder(MeterInvocationConst.TAG_STAGE, true));\n\n    groupConfig.addGroup(OsMeter.OS_NAME,\n        OsMeter.OS_TYPE,\n        new DefaultTagFinder(NetMeter.INTERFACE, true),\n        new DefaultTagFinder(NetMeter.STATISTIC, true));\n\n    groupConfig.addGroup(VertxMetersInitializer.VERTX_ENDPOINTS,\n        VertxMetersInitializer.ENDPOINTS_TYPE,\n        EndpointMeter.ADDRESS, EndpointMeter.STATISTIC);\n\n    groupConfig.addGroup(ThreadPoolMeter.THREAD_POOL_METER,\n        ThreadPoolMeter.ID, ThreadPoolMeter.STAGE);\n\n    return groupConfig;\n  }\n\n  protected OperationPerfGroups generateOperationPerfGroups(MeasurementTree tree, String invocationTypeName) {\n    MeasurementNode node = tree.findChild(MeterInvocationConst.INVOCATION_NAME, invocationTypeName);\n    if (node == null) {\n      return null;\n    }\n\n    OperationPerfGroups groups = new OperationPerfGroups();\n\n    // group by transport\n    for (MeasurementNode transportNode : node.getChildren().values()) {\n      // group by operation\n      for (MeasurementNode operationNode : transportNode.getChildren().values()) {\n        // group by status\n        for (MeasurementNode statusNode : operationNode.getChildren().values()) {\n          PublishUtils.addOperationPerfGroups(groups, transportNode.getName(), operationNode.getName(), statusNode);\n        }\n      }\n    }\n\n    return groups;\n  }\n\n  public DefaultPublishModel createDefaultPublishModel() {\n    DefaultPublishModel model = new DefaultPublishModel();\n\n    model.getConsumer()\n        .setOperationPerfGroups(generateOperationPerfGroups(tree, InvocationType.CONSUMER.name()));\n\n    model.getProducer()\n        .setOperationPerfGroups(generateOperationPerfGroups(tree, InvocationType.PROVIDER.name()));\n\n    model.getEdge()\n        .setOperationPerfGroups(generateOperationPerfGroups(tree, MeterInvocationConst.EDGE_INVOCATION_NAME));\n\n    model.setThreadPools(ThreadPoolMonitorPublishModelFactory.create(tree));\n\n    return model;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/PublishUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerf;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroup;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.PerfInfo;\n\nimport io.micrometer.core.instrument.Statistic;\n\npublic final class PublishUtils {\n  private PublishUtils() {\n  }\n\n  public static PerfInfo createPerfInfo(MeasurementNode stageNode) {\n    PerfInfo perfInfo = new PerfInfo();\n    perfInfo.setTotalRequests(stageNode.findChild(Statistic.COUNT.name()).summary());\n    perfInfo.setMsTotalTime(stageNode.findChild(Statistic.TOTAL_TIME.name()).summary() * 1000);\n    perfInfo.setMsMaxLatency(stageNode.findChild(Statistic.MAX.name()).summary() * 1000);\n    return perfInfo;\n  }\n\n  public static OperationPerf createOperationPerf(String operation, MeasurementNode statusNode) {\n    OperationPerf operationPerf = new OperationPerf();\n\n    operationPerf.setOperation(operation);\n    MeasurementNode stageNode = statusNode.findChild(MeterInvocationConst.TAG_STAGE);\n    stageNode.getChildren().values().forEach(mNode -> {\n      PerfInfo perfInfo = createPerfInfo(mNode);\n      operationPerf.getStages().put(mNode.getName(), perfInfo);\n    });\n\n    MeasurementNode latencyNode = statusNode.findChild(MeterInvocationConst.TAG_DISTRIBUTION);\n    if (latencyNode != null && latencyNode.getMeasurements() != null) {\n      operationPerf.setLatencyDistribution(latencyNode.getMeasurements().stream()\n          .map(m -> (int) m.getValue())\n          .toArray(Integer[]::new));\n    }\n    return operationPerf;\n  }\n\n  public static void addOperationPerfGroups(OperationPerfGroups operationPerfGroups, String transport, String operation,\n      MeasurementNode statusNode) {\n    Map<String, OperationPerfGroup> statusMap = operationPerfGroups\n        .getGroups()\n        .computeIfAbsent(transport, tn -> new HashMap<>());\n    OperationPerfGroup group = statusMap\n        .computeIfAbsent(statusNode.getName(), status -> new OperationPerfGroup(transport, status));\n    OperationPerf operationPerf = createOperationPerf(operation, statusNode);\n    group.addOperationPerf(operationPerf);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/ServerEndpointsLogPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.VertxMetersInitializer;\nimport org.apache.servicecomb.metrics.core.meter.vertx.EndpointMeter;\nimport org.apache.servicecomb.metrics.core.meter.vertx.ServerEndpointMeter;\n\npublic class ServerEndpointsLogPublisher extends AbstractMeasurementNodeLogPublisher {\n  public ServerEndpointsLogPublisher(MeasurementTree tree, StringBuilder sb, String meterName) {\n    super(tree, sb, VertxMetersInitializer.VERTX_ENDPOINTS, meterName);\n  }\n\n  @Override\n  public void print(boolean printDetail) {\n    if (!printDetail) {\n      return;\n    }\n    appendLine(sb, \"    server.endpoints:\");\n    appendLine(sb,\n        \"      connectCount disconnectCount rejectByLimit connections requests latency send(Bps) receive(Bps) listen\");\n\n    for (MeasurementNode address : measurementNode.getChildren().values()) {\n      if (printDetail) {\n        appendLine(sb, \"      %-12.0f %-15.0f %-13.0f %-11.0f %-8.0f %-7.0f %-9s %-12s %s\",\n            address.findChild(EndpointMeter.CONNECT_COUNT).summary(),\n            address.findChild(EndpointMeter.DISCONNECT_COUNT).summary(),\n            address.findChild(ServerEndpointMeter.REJECT_BY_CONNECTION_LIMIT).summary(),\n            address.findChild(EndpointMeter.CONNECTIONS).summary(),\n            address.findChild(EndpointMeter.REQUESTS).summary(),\n            address.findChild(EndpointMeter.LATENCY).summary(),\n            NetUtils.humanReadableBytes((long) address.findChild(EndpointMeter.BYTES_WRITTEN).summary()),\n            NetUtils.humanReadableBytes((long) address.findChild(EndpointMeter.BYTES_READ).summary()),\n            address.getName()\n        );\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_CONSUMER_CONNECTION;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_CONSUMER_DECODE_RESPONSE;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_CONSUMER_ENCODE_REQUEST;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_CONSUMER_SEND;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_CONSUMER_WAIT;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PREPARE;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PROVIDER_BUSINESS;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PROVIDER_DECODE_REQUEST;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PROVIDER_ENCODE_RESPONSE;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PROVIDER_QUEUE;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PROVIDER_SEND;\nimport static org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_TOTAL;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.OperationConfig;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.AllowConcurrentEvents;\nimport com.google.common.eventbus.Subscribe;\n\npublic class SlowInvocationLogger {\n  private static final Logger LOGGER = LoggerFactory.getLogger(\"scb-slow\");\n\n  public SlowInvocationLogger(SCBEngine scbEngine) {\n    scbEngine.getEventBus().register(this);\n  }\n\n  @Subscribe\n  @AllowConcurrentEvents\n  public void onInvocationFinish(InvocationFinishEvent event) {\n    Invocation invocation = event.getInvocation();\n    OperationConfig operationConfig = invocation.getOperationMeta().getConfig();\n    if (!operationConfig.isSlowInvocationEnabled() ||\n        invocation.getInvocationStageTrace().calcTotal() < operationConfig.getNanoSlowInvocation()) {\n      return;\n    }\n\n    if (invocation.isProducer()) {\n      logSlowProvider(invocation, event.getResponse(), operationConfig);\n      return;\n    }\n\n    if (invocation.isEdge()) {\n      logSlowEdge(invocation, event.getResponse(), operationConfig);\n      return;\n    }\n\n    logSlowConsumer(invocation, event.getResponse(), operationConfig);\n  }\n\n  private static String collectClientAddress(Invocation invocation) {\n    HttpServletRequestEx requestEx = invocation.getRequestEx();\n    return requestEx == null ? \"unknown\" : requestEx.getRemoteAddr() + \":\" + requestEx.getRemotePort();\n  }\n\n  private static String collectTargetAddress(Invocation invocation) {\n    Endpoint endpoint = invocation.getEndpoint();\n    return endpoint == null ? \"unknown\" : endpoint.getEndpoint();\n  }\n\n  private static String formatTime(long doubleNano) {\n    long micros = TimeUnit.NANOSECONDS.toMicros(doubleNano);\n    return micros / 1000 + \".\" + micros % 1000;\n  }\n\n  private static void logSlowProvider(Invocation invocation, Response response, OperationConfig operationConfig) {\n    RestOperationMeta restOperationMeta = invocation.getOperationMeta().getExtData(RestConst.SWAGGER_REST_OPERATION);\n    InvocationStageTrace stageTrace = invocation.getInvocationStageTrace();\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"Slow Provider invocation [\").append(invocation.getInvocationQualifiedName())\n        .append(\"](\").append(operationConfig.getMsSlowInvocation()).append(\" ms\")\n        .append(\")[\").append(invocation.getTraceId()).append(\"]\\n\")\n        .append(formatPair(\"  \", \"http method\", restOperationMeta.getHttpMethod()))\n        .append(formatPair(\"  \", \"url\", restOperationMeta.getAbsolutePath()))\n        .append(formatPair(\"  \", \"endpoint\", collectClientAddress(invocation)))\n        .append(formatPair(\"  \", \"status code\", String.valueOf(response.getStatusCode())))\n\n        .append(formatPair(\"    \", STAGE_TOTAL, stageTrace.calcTotal()))\n        .append(formatPair(\"    \", STAGE_PREPARE, stageTrace.calcPrepare()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_DECODE_REQUEST, stageTrace.calcProviderDecodeRequest()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_QUEUE, stageTrace.calcQueue()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_BUSINESS, stageTrace.calcBusinessExecute()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_ENCODE_RESPONSE, stageTrace.calcProviderEncodeResponse()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_SEND, stageTrace.calcProviderSendResponse()));\n\n    List<String> sorted = new ArrayList<>(stageTrace.getStages().keySet());\n    sorted.stream().sorted().forEach(key -> {\n      sb.append(formatPair(\"    \", key,\n          InvocationStageTrace.calc(stageTrace.getStages().get(key).getEndTime(),\n              stageTrace.getStages().get(key).getBeginTime())));\n    });\n\n    LOGGER.warn(sb.toString());\n  }\n\n  protected static String formatPair(String padding, String name, String value) {\n    return String.format(\"%-20s: %20s\\n\", padding + name, value);\n  }\n\n  protected static String formatPair(String padding, String name, long time) {\n    return String.format(\"%-20s: %8sms\\n\", padding + name, formatTime(time));\n  }\n\n  private static void logSlowConsumer(Invocation invocation, Response response, OperationConfig operationConfig) {\n    RestOperationMeta restOperationMeta = invocation.getOperationMeta().getExtData(RestConst.SWAGGER_REST_OPERATION);\n    InvocationStageTrace stageTrace = invocation.getInvocationStageTrace();\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"Slow Consumer invocation [\").append(invocation.getInvocationQualifiedName())\n        .append(\"](\").append(operationConfig.getMsSlowInvocation()).append(\" ms\")\n        .append(\")[\").append(invocation.getTraceId()).append(\"]\\n\")\n        .append(formatPair(\"  \", \"http method\", restOperationMeta.getHttpMethod()))\n        .append(formatPair(\"  \", \"url\", restOperationMeta.getAbsolutePath()))\n        .append(formatPair(\"  \", \"endpoint\", collectTargetAddress(invocation)))\n        .append(formatPair(\"  \", \"status code\", String.valueOf(response.getStatusCode())))\n        .append(formatPair(\"    \", STAGE_TOTAL, stageTrace.calcTotal()))\n        .append(formatPair(\"    \", STAGE_PREPARE, stageTrace.calcPrepare()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_CONNECTION, stageTrace.calcConnection()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_ENCODE_REQUEST, stageTrace.calcConsumerEncodeRequest()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_SEND, stageTrace.calcConsumerSendRequest()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_WAIT, stageTrace.calcWait()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_DECODE_RESPONSE, stageTrace.calcConsumerDecodeResponse()));\n\n    List<String> sorted = new ArrayList<>(stageTrace.getStages().keySet());\n    sorted.stream().sorted().forEach(key -> {\n      sb.append(formatPair(\"    \", key,\n          InvocationStageTrace.calc(stageTrace.getStages().get(key).getEndTime(),\n              stageTrace.getStages().get(key).getBeginTime())));\n    });\n\n    LOGGER.warn(sb.toString());\n  }\n\n  private static void logSlowEdge(Invocation invocation, Response response, OperationConfig operationConfig) {\n    RestOperationMeta restOperationMeta = invocation.getOperationMeta().getExtData(RestConst.SWAGGER_REST_OPERATION);\n    InvocationStageTrace stageTrace = invocation.getInvocationStageTrace();\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"Slow Edge invocation [\").append(invocation.getInvocationQualifiedName())\n        .append(\"](\").append(operationConfig.getMsSlowInvocation()).append(\" ms\")\n        .append(\")[\").append(invocation.getTraceId()).append(\"]\\n\")\n        .append(formatPair(\"  \", \"http method\", restOperationMeta.getHttpMethod()))\n        .append(formatPair(\"  \", \"url\", restOperationMeta.getAbsolutePath()))\n        .append(formatPair(\"  \", \"endpoint\", collectTargetAddress(invocation)))\n        .append(formatPair(\"  \", \"status code\", String.valueOf(response.getStatusCode())))\n        .append(formatPair(\"    \", STAGE_TOTAL, stageTrace.calcTotal()))\n        .append(formatPair(\"    \", STAGE_PREPARE, stageTrace.calcPrepare()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_DECODE_REQUEST, stageTrace.calcProviderDecodeRequest()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_CONNECTION, stageTrace.calcConnection()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_ENCODE_REQUEST, stageTrace.calcConsumerEncodeRequest()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_SEND, stageTrace.calcConsumerSendRequest()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_WAIT, stageTrace.calcWait()))\n        .append(formatPair(\"    \", STAGE_CONSUMER_DECODE_RESPONSE, stageTrace.calcConsumerDecodeResponse()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_ENCODE_RESPONSE, stageTrace.calcProviderEncodeResponse()))\n        .append(formatPair(\"    \", STAGE_PROVIDER_SEND, stageTrace.calcProviderSendResponse()))\n    ;\n\n    List<String> sorted = new ArrayList<>(stageTrace.getStages().keySet());\n    sorted.stream().sorted().forEach(key -> {\n      sb.append(formatPair(\"    \", key,\n          InvocationStageTrace.calc(stageTrace.getStages().get(key).getEndTime(),\n              stageTrace.getStages().get(key).getBeginTime())));\n    });\n\n    LOGGER.warn(sb.toString());\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/ConsumerPublishModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model;\n\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\n\npublic class ConsumerPublishModel {\n  private OperationPerfGroups operationPerfGroups;\n\n  public OperationPerfGroups getOperationPerfGroups() {\n    return operationPerfGroups;\n  }\n\n  public void setOperationPerfGroups(OperationPerfGroups operationPerfGroups) {\n    this.operationPerfGroups = operationPerfGroups;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/DefaultPublishModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class DefaultPublishModel {\n  private ConsumerPublishModel consumer = new ConsumerPublishModel();\n\n  private ProducerPublishModel producer = new ProducerPublishModel();\n\n  private EdgePublishModel edge = new EdgePublishModel();\n\n  private Map<String, ThreadPoolPublishModel> threadPools = new HashMap<>();\n\n  public ConsumerPublishModel getConsumer() {\n    return consumer;\n  }\n\n  public void setConsumer(ConsumerPublishModel consumer) {\n    this.consumer = consumer;\n  }\n\n  public ProducerPublishModel getProducer() {\n    return producer;\n  }\n\n  public EdgePublishModel getEdge() {\n    return edge;\n  }\n\n  public void setEdge(EdgePublishModel edge) {\n    this.edge = edge;\n  }\n\n  public void setProducer(ProducerPublishModel producer) {\n    this.producer = producer;\n  }\n\n  public Map<String, ThreadPoolPublishModel> getThreadPools() {\n    return threadPools;\n  }\n\n  public void setThreadPools(Map<String, ThreadPoolPublishModel> threadPools) {\n    this.threadPools = threadPools;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/EdgePublishModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.core.publish.model;\n\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\n\npublic class EdgePublishModel extends ConsumerPublishModel {\n  private OperationPerfGroups operationPerfGroups;\n\n  public OperationPerfGroups getOperationPerfGroups() {\n    return operationPerfGroups;\n  }\n\n  public void setOperationPerfGroups(OperationPerfGroups operationPerfGroups) {\n    this.operationPerfGroups = operationPerfGroups;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/ProducerPublishModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model;\n\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\n\npublic class ProducerPublishModel {\n  private OperationPerfGroups operationPerfGroups;\n\n  public OperationPerfGroups getOperationPerfGroups() {\n    return operationPerfGroups;\n  }\n\n  public void setOperationPerfGroups(OperationPerfGroups operationPerfGroups) {\n    this.operationPerfGroups = operationPerfGroups;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/ThreadPoolPublishModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model;\n\npublic class ThreadPoolPublishModel {\n  private double avgTaskCount;\n\n  private double avgCompletedTaskCount;\n\n  private int currentThreadsBusy;\n\n  private int maxThreads;\n\n  private int poolSize;\n\n  private int corePoolSize;\n\n  private int queueSize;\n\n  private double rejected = Double.NaN;\n\n  public double getAvgTaskCount() {\n    return avgTaskCount;\n  }\n\n  public void setAvgTaskCount(double avgTaskCount) {\n    this.avgTaskCount = avgTaskCount;\n  }\n\n  public double getAvgCompletedTaskCount() {\n    return avgCompletedTaskCount;\n  }\n\n  public void setAvgCompletedTaskCount(double avgCompletedTaskCount) {\n    this.avgCompletedTaskCount = avgCompletedTaskCount;\n  }\n\n  public int getCurrentThreadsBusy() {\n    return currentThreadsBusy;\n  }\n\n  public void setCurrentThreadsBusy(int currentThreadsBusy) {\n    this.currentThreadsBusy = currentThreadsBusy;\n  }\n\n  public int getMaxThreads() {\n    return maxThreads;\n  }\n\n  public void setMaxThreads(int maxThreads) {\n    this.maxThreads = maxThreads;\n  }\n\n  public int getPoolSize() {\n    return poolSize;\n  }\n\n  public void setPoolSize(int poolSize) {\n    this.poolSize = poolSize;\n  }\n\n  public int getCorePoolSize() {\n    return corePoolSize;\n  }\n\n  public void setCorePoolSize(int corePoolSize) {\n    this.corePoolSize = corePoolSize;\n  }\n\n  public int getQueueSize() {\n    return queueSize;\n  }\n\n  public void setQueueSize(int queueSize) {\n    this.queueSize = queueSize;\n  }\n\n  public double getRejected() {\n    return rejected;\n  }\n\n  public void setRejected(double rejected) {\n    this.rejected = rejected;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/invocation/OperationPerf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class OperationPerf {\n  private String operation;\n\n  private Map<String, PerfInfo> stages = new HashMap<>();\n\n  private Integer[] latencyDistribution;\n\n  public String getOperation() {\n    return operation;\n  }\n\n  public void setOperation(String operation) {\n    this.operation = operation;\n  }\n\n  public Map<String, PerfInfo> getStages() {\n    return stages;\n  }\n\n  public Integer[] getLatencyDistribution() {\n    return latencyDistribution;\n  }\n\n  public void setLatencyDistribution(Integer[] latencyDistribution) {\n    this.latencyDistribution = latencyDistribution;\n  }\n\n  public void setStages(Map<String, PerfInfo> stages) {\n    this.stages = stages;\n  }\n\n  public PerfInfo findStage(String stage) {\n    return stages.get(stage);\n  }\n\n  public void add(OperationPerf operationPerf) {\n    operationPerf.stages.forEach((key, value) -> {\n      PerfInfo perfInfo = stages.computeIfAbsent(key, n -> new PerfInfo());\n      perfInfo.add(value);\n    });\n\n    if (operationPerf.getLatencyDistribution() == null) {\n      return;\n    }\n\n    if (latencyDistribution == null) {\n      latencyDistribution = new Integer[operationPerf.getLatencyDistribution().length];\n      Arrays.fill(latencyDistribution, 0);\n    }\n    for (int idx = 0; idx < operationPerf.getLatencyDistribution().length; idx++) {\n      latencyDistribution[idx] += operationPerf.getLatencyDistribution()[idx];\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/invocation/OperationPerfGroup.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class OperationPerfGroup {\n  private final String transport;\n\n  private final String status;\n\n  private final List<OperationPerf> operationPerfs = new ArrayList<>();\n\n  private OperationPerf summary;\n\n  public OperationPerfGroup(String transport, String status) {\n    this.transport = transport;\n    this.status = status;\n  }\n\n  public String getTransport() {\n    return transport;\n  }\n\n  public String getStatus() {\n    return status;\n  }\n\n  public List<OperationPerf> getOperationPerfs() {\n    return operationPerfs;\n  }\n\n  public OperationPerf getSummary() {\n    return summary;\n  }\n\n  public void addOperationPerf(OperationPerf operationPerf) {\n    operationPerfs.add(operationPerf);\n\n    if (summary == null) {\n      summary = new OperationPerf();\n      summary.setOperation(\"\");\n    }\n    summary.add(operationPerf);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/invocation/OperationPerfGroups.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class OperationPerfGroups {\n  // first key:  transport\n  // second key: statusCode\n  private Map<String, Map<String, OperationPerfGroup>> groups = new HashMap<>();\n\n  public Map<String, Map<String, OperationPerfGroup>> getGroups() {\n    return groups;\n  }\n\n  public void setGroups(Map<String, Map<String, OperationPerfGroup>> groups) {\n    this.groups = groups;\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/model/invocation/PerfInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\npublic class PerfInfo {\n  private double totalRequests;\n\n  private double msTotalTime;\n\n  private double msMaxLatency;\n\n  public double getTotalRequests() {\n    return totalRequests;\n  }\n\n  public void setTotalRequests(double totalRequests) {\n    this.totalRequests = totalRequests;\n  }\n\n  public double getMsTotalTime() {\n    return msTotalTime;\n  }\n\n  public void setMsTotalTime(double msTotalTime) {\n    this.msTotalTime = msTotalTime;\n  }\n\n  public double getMsMaxLatency() {\n    return msMaxLatency;\n  }\n\n  public void setMsMaxLatency(double msMaxLatency) {\n    this.msMaxLatency = msMaxLatency;\n  }\n\n  public void add(PerfInfo other) {\n    totalRequests += other.totalRequests;\n    msTotalTime += other.msTotalTime;\n    if (msMaxLatency < other.msMaxLatency) {\n      msMaxLatency = other.msMaxLatency;\n    }\n  }\n\n  public double calcMsLatency() {\n    return (totalRequests != 0) ? msTotalTime / totalRequests : 0;\n  }\n\n  @Override\n  public String toString() {\n    return \"PerfInfo [tps=\" + totalRequests + \", msTotalTime=\" + msTotalTime + \", msLatency=\" + calcMsLatency()\n        + \", msMaxLatency=\"\n        + msMaxLatency + \"]\";\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.metrics.core.MetricsCoreConfiguration\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/AssertUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport java.util.List;\n\nimport org.junit.jupiter.api.Assertions;\n\nimport io.micrometer.core.instrument.Measurement;\n\npublic class AssertUtil {\n\n  public static void assertMeasure(List<Measurement> measurements, int index, String expected) {\n    Assertions.assertEquals(String.format(\"Measurement{%s}\", expected), measurements.get(index).toString());\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.Mockito;\nimport org.mockito.junit.jupiter.MockitoExtension;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\n\n@ExtendWith(MockitoExtension.class)\npublic class TestInvocationMetersInitializer {\n  EventBus eventBus = new EventBus();\n\n  MeterRegistry registry = new SimpleMeterRegistry();\n\n  InvocationMetersInitializer invocationMetersInitializer = new InvocationMetersInitializer();\n\n  @Mock\n  Invocation invocation;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setup() {\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n    invocationMetersInitializer.init(registry, eventBus, new MetricsBootstrapConfig(environment));\n  }\n\n  @Test\n  public void consumerInvocation() {\n    InvocationFinishEvent event = Mockito.mock(InvocationFinishEvent.class);\n    Mockito.when(invocation.isConsumer()).thenReturn(true);\n    Mockito.when(invocation.getInvocationType()).thenReturn(InvocationType.CONSUMER);\n    Mockito.when(invocation.getRealTransportName()).thenReturn(CoreConst.RESTFUL);\n    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn(\"m.s.o\");\n    InvocationStageTrace invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    Mockito.when(invocationStageTrace.calcTotal()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcPrepare()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcConnection()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcConsumerEncodeRequest()).thenReturn(4L);\n    Mockito.when(invocationStageTrace.calcConsumerSendRequest()).thenReturn(5L);\n    Mockito.when(invocationStageTrace.calcWait()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcConsumerDecodeResponse()).thenReturn(9L);\n    Mockito.when(event.getInvocation()).thenReturn(invocation);\n    Response mockResponse = Mockito.spy(Response.class);\n    Mockito.when(event.getResponse()).thenReturn(mockResponse);\n    Mockito.doReturn(0).when(mockResponse).getStatusCode();\n\n    eventBus.post(event);\n    eventBus.post(event);\n\n    MeasurementTree tree = new MeasurementTree();\n    tree.from(registry.getMeters().iterator(),\n        new MeasurementGroupConfig(MeterInvocationConst.INVOCATION_NAME, \"stage\"));\n    List<Measurement> measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"total\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"prepare\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"consumer-send\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.0E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=5.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"connection\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"consumer-encode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=8.0E-9\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=4.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"connection\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"wait\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"consumer-decode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n  }\n\n  @Test\n  public void edgeInvocation() {\n    InvocationFinishEvent event = Mockito.mock(InvocationFinishEvent.class);\n    Mockito.when(invocation.getInvocationType()).thenReturn(InvocationType.EDGE);\n    Mockito.when(invocation.isEdge()).thenReturn(true);\n    Mockito.when(invocation.getRealTransportName()).thenReturn(CoreConst.RESTFUL);\n    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn(\"m.s.o\");\n    InvocationStageTrace invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    Mockito.when(invocationStageTrace.calcTotal()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcPrepare()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcProviderDecodeRequest()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcConnection()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcConsumerEncodeRequest()).thenReturn(4L);\n    Mockito.when(invocationStageTrace.calcConsumerSendRequest()).thenReturn(5L);\n    Mockito.when(invocationStageTrace.calcConsumerDecodeResponse()).thenReturn(8L);\n    Mockito.when(invocationStageTrace.calcWait()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcProviderEncodeResponse()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcProviderSendResponse()).thenReturn(9L);\n    Mockito.when(event.getInvocation()).thenReturn(invocation);\n    Response mockResponse = Mockito.spy(Response.class);\n    Mockito.when(event.getResponse()).thenReturn(mockResponse);\n    Mockito.doReturn(0).when(mockResponse).getStatusCode();\n\n    eventBus.post(event);\n    eventBus.post(event);\n\n    MeasurementTree tree = new MeasurementTree();\n    tree.from(registry.getMeters().iterator(),\n        new MeasurementGroupConfig(MeterInvocationConst.INVOCATION_NAME, \"stage\"));\n\n    List<Measurement> measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"total\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"prepare\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"consumer-send\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.0E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=5.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"connection\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"consumer-encode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=8.0E-9\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=4.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"wait\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"consumer-decode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.6E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=8.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"provider-decode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"provider-encode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"provider-send\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n  }\n\n  @Test\n  public void producerInvocation() {\n    InvocationFinishEvent event = Mockito.mock(InvocationFinishEvent.class);\n    Mockito.when(invocation.isConsumer()).thenReturn(false);\n    Mockito.when(invocation.getInvocationType()).thenReturn(InvocationType.PROVIDER);\n    Mockito.when(invocation.getRealTransportName()).thenReturn(CoreConst.RESTFUL);\n    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn(\"m.s.o\");\n    InvocationStageTrace invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    Mockito.when(invocationStageTrace.calcTotal()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcPrepare()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcProviderDecodeRequest()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcQueue()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcBusinessExecute()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcProviderEncodeResponse()).thenReturn(9L);\n    Mockito.when(invocationStageTrace.calcProviderSendResponse()).thenReturn(9L);\n    Mockito.when(event.getInvocation()).thenReturn(invocation);\n    Response mockResponse = Mockito.spy(Response.class);\n    Mockito.when(event.getResponse()).thenReturn(mockResponse);\n    Mockito.doReturn(0).when(mockResponse).getStatusCode();\n\n    eventBus.post(event);\n    eventBus.post(event);\n\n    MeasurementTree tree = new MeasurementTree();\n    tree.from(registry.getMeters().iterator(),\n        new MeasurementGroupConfig(MeterInvocationConst.INVOCATION_NAME, \"stage\"));\n\n    List<Measurement> measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"total\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"prepare\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"queue\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"execute\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"provider-decode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"provider-encode\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n\n    measurements = tree.findChild(MeterInvocationConst.INVOCATION_NAME, \"provider-send\")\n        .getMeasurements();\n    Assertions.assertEquals(3, measurements.size());\n    AssertUtil.assertMeasure(measurements, 0,\n        \"statistic='COUNT', value=2.0\");\n    AssertUtil.assertMeasure(measurements, 1,\n        \"statistic='TOTAL_TIME', value=1.8E-8\");\n    AssertUtil.assertMeasure(measurements, 2,\n        \"statistic='MAX', value=9.0E-9\");\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestOsMeterInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport java.io.File;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.meter.os.NetMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.OsMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.SystemMeter;\nimport org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\n\nimport com.google.common.eventbus.EventBus;\nimport com.sun.management.OperatingSystemMXBean;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\n@ExtendWith(MockitoExtension.class)\npublic class TestOsMeterInitializer {\n  MeterRegistry registry = new SimpleMeterRegistry();\n\n  @Mock\n  EventBus eventBus;\n\n  @Test\n  public void init() {\n    List<String> list = new ArrayList<>();\n    list.add(\"13  1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1\");\n    list.add(\"useless\");\n    list.add(\"eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n\n    try (MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class)) {\n      fileUtilsMockedStatic.when(() -> {\n        FileUtils.readLines(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(list);\n      OsMetersInitializer osMetersInitializer = new OsMetersInitializer();\n      osMetersInitializer.init(registry, eventBus, null);\n\n      OsMeter osMeter = osMetersInitializer.getOsMeter();\n      SystemMeter systemMeter = osMeter.getCpuMeter();\n      OperatingSystemMXBean osBean = Mockito.mock(OperatingSystemMXBean.class);\n      Mockito.when(osBean.getCpuLoad()).thenReturn(3.2D);\n      Mockito.when(osBean.getProcessCpuLoad()).thenReturn(1.2D);\n      systemMeter.setOsBean(osBean);\n      NetMeter netMeter = osMeter.getNetMeter();\n      netMeter.setOsLinux(true);\n\n      osMetersInitializer.poll(System.currentTimeMillis(), 1000);\n\n      MeasurementTree tree = new MeasurementTree();\n      MeasurementGroupConfig group = new MeasurementGroupConfig();\n      group.addGroup(OsMeter.OS_NAME, OsMeter.OS_TYPE);\n      tree.from(registry.getMeters().iterator(), group);\n\n      Assertions.assertEquals(1.2D,\n              tree.findChild(OsMeter.OS_NAME, SystemMeter.PROCESS_CPU_USAGE).summary(), 0.0);\n      Assertions.assertEquals(3.2D,\n              tree.findChild(OsMeter.OS_NAME, SystemMeter.CPU_USAGE).summary(), 0.0);\n\n      Map<String, InterfaceUsage> interfaceInfoMap = netMeter.getInterfaceUsageMap();\n      Assertions.assertEquals(1, interfaceInfoMap.size());\n      InterfaceUsage eth0 = interfaceInfoMap.get(\"eth0\");\n      // recv Bps\n      Assertions.assertEquals(0L, eth0.getReceive().getLastValue());\n      Assertions.assertEquals(0, eth0.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, eth0.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(0L, eth0.getSend().getLastValue());\n      Assertions.assertEquals(0, eth0.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, eth0.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(0L, eth0.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(0, eth0.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(0L, eth0.getPacketsSend().getLastValue());\n      Assertions.assertEquals(0, eth0.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, eth0.getPacketsSend().getIndex());\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestThreadPoolMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.RunnableScheduledFuture;\nimport java.util.concurrent.ScheduledThreadPoolExecutor;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.executor.GroupExecutor;\nimport org.apache.servicecomb.core.executor.ThreadPoolExecutorEx;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.meter.pool.ThreadPoolMeter;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.context.ApplicationContext;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestThreadPoolMetersInitializer {\n  MeterRegistry registry = new SimpleMeterRegistry();\n\n  ThreadPoolMetersInitializer threadPoolMetersInitializer = new ThreadPoolMetersInitializer();\n\n  ThreadPoolExecutorEx threadPoolExecutor = Mockito.mock(ThreadPoolExecutorEx.class);\n\n  @Mocked\n  BlockingQueue<Runnable> queue;\n\n  @Mocked\n  GroupExecutor groupExecutor;\n\n  ExecutorService executor = Mockito.mock(ExecutorService.class);\n\n  @Mocked\n  ApplicationContext applicationContext;\n\n  @Mocked\n  MicroserviceMeta microserviceMeta;\n\n  @Mocked\n  OperationMeta operationMetaExecutor;\n\n  @Mocked\n  OperationMeta operationMetaSameExecutor;\n\n  @Mocked\n  OperationMeta operationMetaFixedThreadExecutor;\n\n  @Test\n  public void init() {\n    new Expectations(SCBEngine.class) {\n      {\n        SCBEngine.getInstance().getProducerMicroserviceMeta();\n        result = microserviceMeta;\n      }\n    };\n    Map<String, Executor> beanExecutors = new HashMap<>();\n    beanExecutors.put(\"executor\", executor);\n    beanExecutors.put(\"groupExecutor\", groupExecutor);\n    beanExecutors.put(\"threadPoolExecutor\", threadPoolExecutor);\n    new Expectations(BeanUtils.class) {\n      {\n        BeanUtils.getContext();\n        result = applicationContext;\n        applicationContext.getBeansOfType(Executor.class);\n        result = beanExecutors;\n      }\n    };\n\n    Mockito.when(threadPoolExecutor.getQueue()).thenReturn(queue);\n    new Expectations() {\n      {\n        microserviceMeta.getOperations();\n        result = Arrays.asList(operationMetaExecutor, operationMetaSameExecutor, operationMetaFixedThreadExecutor);\n        operationMetaExecutor.getExecutor();\n        result = executor;\n        operationMetaSameExecutor.getExecutor();\n        result = executor;\n        operationMetaFixedThreadExecutor.getExecutor();\n        result = groupExecutor;\n\n        groupExecutor.getExecutorList();\n        result = Arrays.asList(threadPoolExecutor);\n\n        queue.size();\n        result = 10d;\n      }\n    };\n\n    new MockUp<ScheduledThreadPoolExecutor>() {\n      @Mock\n      void delayedExecute(RunnableScheduledFuture<?> task) {\n\n      }\n    };\n\n    threadPoolMetersInitializer.init(registry, null, null);\n\n    MeasurementTree tree = new MeasurementTree();\n    MeasurementGroupConfig group = new MeasurementGroupConfig();\n    group.addGroup(ThreadPoolMeter.THREAD_POOL_METER, ThreadPoolMeter.ID,\n        ThreadPoolMeter.STAGE);\n    tree.from(registry.getMeters().iterator(), group);\n\n    MeasurementNode node = tree.findChild(ThreadPoolMeter.THREAD_POOL_METER);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"maxThreads\").summary(), 0, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"rejectedCount\").summary(), 0, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"completedTaskCount\").summary(), 0, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"currentThreadsBusy\").summary(), 0, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"corePoolSize\").summary(), 0, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"poolSize\").summary(), 0, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"queueSize\").summary(), 10, 0);\n    Assertions.assertEquals(node.findChild(\"groupExecutor-group0\", \"taskCount\").summary(), 0, 0);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestVertxMetersInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.metrics.core.publish.DefaultLogPublisher.ENDPOINTS_CLIENT_DETAIL_ENABLED;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.PolledEvent;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.apache.servicecomb.foundation.vertx.SharedVertxFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.metrics.core.publish.DefaultLogPublisher;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.Meter;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport io.vertx.core.AbstractVerticle;\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.Future;\nimport io.vertx.core.Promise;\nimport io.vertx.core.http.HttpClient;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpClientResponse;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServer;\nimport io.vertx.core.impl.SysProps;\nimport io.vertx.ext.web.Router;\n\npublic class TestVertxMetersInitializer {\n  MeterRegistry registry = new SimpleMeterRegistry();\n\n  EventBus eventBus = new EventBus();\n\n  VertxMetersInitializer vertxMetersInitializer = new VertxMetersInitializer();\n\n  DefaultLogPublisher logPublisher = new DefaultLogPublisher();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  LogCollector logCollector = new LogCollector();\n\n  static HttpClient client;\n\n  static HttpServer server;\n\n  static int port;\n\n  static String body = \"body\";\n\n  public static class TestServerVerticle extends AbstractVerticle {\n    @Override\n    public void start(Promise<Void> startPromise) {\n      Router mainRouter = Router.router(vertx);\n      mainRouter.route(\"/\").handler(context -> context.response().end(body));\n\n      server = vertx.createHttpServer();\n      server.requestHandler(mainRouter);\n      Future<HttpServer> future = server.listen(0, \"0.0.0.0\");\n      future.onComplete((s, f) -> {\n        if (f == null) {\n          port = s.actualPort();\n          startPromise.complete();\n          return;\n        }\n\n        startPromise.fail(f);\n      });\n    }\n  }\n\n  public static class TestClientVerticle extends AbstractVerticle {\n    @Override\n    public void start(Promise<Void> startPromise) {\n      client = vertx.createHttpClient();\n      Future<HttpClientRequest> future = client.request(HttpMethod.GET, port, \"127.0.0.1\", \"/\");\n      future.onComplete((s, f) -> {\n        if (f == null) {\n          Future<HttpClientResponse> responseFuture = s.send(body);\n          responseFuture.onComplete((rs, rf) -> {\n            if (rf == null) {\n              rs.bodyHandler((buffer) -> startPromise.complete());\n            } else {\n              startPromise.fail(f);\n            }\n          });\n        }\n      });\n    }\n  }\n\n  @BeforeEach\n  public void setup() {\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n    HttpClients.load();\n  }\n\n  @AfterEach\n  public void tearDown() {\n    logCollector.clear();\n    HttpClients.destroy();\n    if (client != null) {\n      client.shutdown();\n    }\n    if (server != null) {\n      server.shutdown();\n    }\n  }\n\n  @Test\n  public void init() throws InterruptedException {\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n    Mockito.when(environment.getProperty(DefaultLogPublisher.ENABLED, boolean.class, false)).thenReturn(false);\n    VertxUtils\n        .blockDeploy(SharedVertxFactory.getSharedVertx(environment), TestServerVerticle.class, new DeploymentOptions());\n    VertxUtils\n        .blockDeploy(SharedVertxFactory.getSharedVertx(environment), TestClientVerticle.class, new DeploymentOptions());\n\n    vertxMetersInitializer.init(registry, eventBus, new MetricsBootstrapConfig(environment));\n    logPublisher.setEnvironment(environment);\n    logPublisher.init(registry, eventBus, null);\n\n    vertxMetersInitializer.poll(0, 1);\n    List<Meter> meters = registry.getMeters();\n\n    testLog(logCollector, meters, true);\n    logCollector.clear();\n\n    testLog(logCollector, meters, false);\n  }\n\n  private void testLog(LogCollector logCollector, List<Meter> meters, boolean printDetail) {\n    Mockito.when(environment.getProperty(ENDPOINTS_CLIENT_DETAIL_ENABLED, boolean.class, true)).thenReturn(printDetail);\n    logPublisher.onPolledEvent(new PolledEvent(meters));\n\n    StringBuilder sb = new StringBuilder();\n    logCollector.getEvents().forEach(event -> sb.append(event.getMessage()).append(\"\\n\"));\n    String actual = sb.toString();\n    int idx = actual.indexOf(\"vertx:\\n\");\n    actual = actual.substring(idx);\n\n    String clientLatency;\n    String serverLatency;\n\n    String expect = \"vertx:\\n\"\n        + \"  instances:\\n\"\n        + \"    name       eventLoopContext-created\\n\"\n        + \"    transport  0\\n\"\n        + \"  transport:\\n\";\n\n    int clientLatencyIndex = actual.indexOf(\"1            0               0             1           1        \")\n        + \"1            0               0             1           1        \".length();\n    clientLatency = actual.substring(clientLatencyIndex, actual.indexOf(\" \", clientLatencyIndex));\n    int serverLatencyIndex = actual.lastIndexOf(\"1            0               0             1           1        \")\n        + \"1            0               0             1           1        \".length();\n    serverLatency = actual.substring(serverLatencyIndex, actual.indexOf(\" \", serverLatencyIndex));\n    int portSize = String.valueOf(port).length();\n    // in new vert.x version, bytes written must be higher than 4K or will be zero\n    if (printDetail) {\n      expect = expect + \"    client.endpoints:\\n\"\n          + \"      connectCount disconnectCount queue         connections requests latency send(Bps) receive(Bps) remote\\n\";\n      expect +=\n          \"      1            0               0             1           1        %-7s 4         4            http://127.0.0.1:%-\"\n              + portSize + \"s\\n\";\n    }\n    expect += \"\"\n        + \"    server.endpoints:\\n\"\n        + \"      connectCount disconnectCount rejectByLimit connections requests latency send(Bps) receive(Bps) listen\\n\"\n        + \"      1            0               0             1           1        %-7s 4         4            0.0.0.0:0\\n\\n\";\n\n    if (printDetail) {\n      expect = String\n          .format(expect, clientLatency, port, serverLatency);\n    } else {\n      expect = String.format(expect, serverLatency);\n    }\n\n    Assertions.assertEquals(expect, actual);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestNetMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os;\n\nimport static org.apache.servicecomb.metrics.core.meter.os.OsMeter.OS_TYPE;\nimport static org.apache.servicecomb.metrics.core.meter.os.OsMeter.OS_TYPE_NET;\n\nimport java.io.File;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.foundation.metrics.publish.DefaultTagFinder;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.meter.os.net.InterfaceUsage;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tags;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\n\npublic class TestNetMeter {\n  @Test\n  public void testNetRefreshUnchanged() {\n    List<String> list = new ArrayList<>();\n    list.add(\"useless\");\n    list.add(\"useless\");\n    list.add(\"eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n\n    try (MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class)) {\n      fileUtilsMockedStatic.when(() -> {\n          FileUtils.readLines(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(list);\n\n      MeterRegistry meterRegistry = new SimpleMeterRegistry();\n      NetMeter netMeter = new NetMeter(meterRegistry, \"os\", Tags.of(OS_TYPE, OS_TYPE_NET));\n      list.remove(2);\n      list.add(\"eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0\");\n      netMeter.refreshNet(1);\n\n      Map<String, InterfaceUsage> meterInterfaceInfoMap = netMeter.getInterfaceUsageMap();\n      Assertions.assertTrue(meterInterfaceInfoMap.containsKey(\"eth0\"));\n\n      InterfaceUsage eth0 = meterInterfaceInfoMap.get(\"eth0\");\n\n      Assertions.assertEquals(\"eth0\", eth0.getName());\n\n      // recv Bps\n      Assertions.assertEquals(1L, eth0.getReceive().getLastValue());\n      Assertions.assertEquals(1, eth0.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, eth0.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(1L, eth0.getSend().getLastValue());\n      Assertions.assertEquals(1, eth0.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, eth0.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(1L, eth0.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(1L, eth0.getPacketsSend().getLastValue());\n      Assertions.assertEquals(1, eth0.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, eth0.getPacketsSend().getIndex());\n\n      // measurement tree test\n      MeasurementGroupConfig group = new MeasurementGroupConfig();\n      group.addGroup(OsMeter.OS_NAME,\n            OS_TYPE,\n            new DefaultTagFinder(NetMeter.INTERFACE, true),\n            new DefaultTagFinder(NetMeter.STATISTIC, true));\n\n      MeasurementTree tree = new MeasurementTree();\n      tree.from(meterRegistry.getMeters().iterator(), group);\n      MeasurementNode osNode = tree.findChild(OsMeter.OS_NAME);\n      MeasurementNode netNode = osNode.findChild(OS_TYPE_NET);\n      Assertions.assertEquals(1, netNode.getChildren().size());\n      for (MeasurementNode interfaceNode : netNode.getChildren().values()) {\n        double sendRate = interfaceNode.findChild(NetMeter.TAG_SEND.getValue()).summary();\n        double sendPacketsRate = interfaceNode.findChild(NetMeter.TAG_PACKETS_SEND.getValue()).summary();\n        double receiveRate = interfaceNode.findChild(NetMeter.TAG_RECEIVE.getValue()).summary();\n        double receivePacketsRate = interfaceNode.findChild(NetMeter.TAG_PACKETS_RECEIVE.getValue()).summary();\n        Assertions.assertEquals(1, sendRate, 0);\n        Assertions.assertEquals(1, sendPacketsRate, 0);\n        Assertions.assertEquals(1, receiveRate, 0);\n        Assertions.assertEquals(1, receivePacketsRate, 0);\n      }\n    }\n  }\n\n\n  @Test\n  public void testNetRefreshAdd() {\n    List<String> list = new ArrayList<>();\n    list.add(\"useless\");\n    list.add(\"useless\");\n    list.add(\"eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n    try (MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class)) {\n      fileUtilsMockedStatic.when(() -> {\n          FileUtils.readLines(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(list);\n\n      MeterRegistry meterRegistry = new SimpleMeterRegistry();\n      NetMeter netMeter = new NetMeter(meterRegistry, \"net\", Tags.empty());\n      netMeter.setOsLinux(true);\n      netMeter.poll(0, 0);\n      Map<String, InterfaceUsage> netMap = netMeter.getInterfaceUsageMap();\n      Assertions.assertEquals(1, netMap.size());\n      list.remove(2);\n      list.add(\"eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0\");\n      list.add(\"lo: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n      netMeter.refreshNet(1);\n      Assertions.assertEquals(2, netMap.size());\n      InterfaceUsage eth0 = netMap.get(\"eth0\");\n      Assertions.assertEquals(\"eth0\", eth0.getName());\n\n      // recv Bps\n      Assertions.assertEquals(1L, eth0.getReceive().getLastValue());\n      Assertions.assertEquals(1, eth0.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, eth0.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(1L, eth0.getSend().getLastValue());\n      Assertions.assertEquals(1, eth0.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, eth0.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(1L, eth0.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(1L, eth0.getPacketsSend().getLastValue());\n      Assertions.assertEquals(1, eth0.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, eth0.getPacketsSend().getIndex());\n\n      InterfaceUsage lo = netMap.get(\"lo\");\n      Assertions.assertEquals(\"lo\", lo.getName());\n\n      // recv Bps\n      Assertions.assertEquals(0L, lo.getReceive().getLastValue());\n      Assertions.assertEquals(0, lo.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, lo.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(0L, lo.getSend().getLastValue());\n      Assertions.assertEquals(0, lo.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, lo.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(0L, lo.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(0, lo.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, lo.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(0L, lo.getPacketsSend().getLastValue());\n      Assertions.assertEquals(0, lo.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, lo.getPacketsSend().getIndex());\n    }\n  }\n\n\n  @Test\n  public void testNetRefreshRemove() {\n    List<String> list = new ArrayList<>();\n    list.add(\"useless\");\n    list.add(\"useless\");\n    list.add(\"eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n    list.add(\"lo: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n    try (MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class)) {\n      fileUtilsMockedStatic.when(() -> {\n          FileUtils.readLines(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(list);\n\n      MeterRegistry meterRegistry = new SimpleMeterRegistry();\n      NetMeter netMeter = new NetMeter(meterRegistry, \"net\", Tags.empty());\n      netMeter.setOsLinux(true);\n      netMeter.poll(0, 1);\n\n      Map<String, InterfaceUsage> netMap = netMeter.getInterfaceUsageMap();\n      Assertions.assertEquals(2, netMap.size());\n      InterfaceUsage lo = netMap.get(\"lo\");\n      InterfaceUsage eth0 = netMap.get(\"eth0\");\n      Assertions.assertEquals(\"lo\", lo.getName());\n      // recv Bps\n      Assertions.assertEquals(0L, lo.getReceive().getLastValue());\n      Assertions.assertEquals(0, lo.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, lo.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(0L, lo.getSend().getLastValue());\n      Assertions.assertEquals(0, lo.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, lo.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(0L, lo.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(0, lo.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, lo.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(0L, lo.getPacketsSend().getLastValue());\n      Assertions.assertEquals(0, lo.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, lo.getPacketsSend().getIndex());\n\n      Assertions.assertEquals(\"eth0\", eth0.getName());\n      // recv Bps\n      Assertions.assertEquals(0L, eth0.getReceive().getLastValue());\n      Assertions.assertEquals(0, eth0.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, eth0.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(0L, eth0.getSend().getLastValue());\n      Assertions.assertEquals(0, eth0.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, eth0.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(0L, eth0.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(0, eth0.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(0L, eth0.getPacketsSend().getLastValue());\n      Assertions.assertEquals(0, eth0.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, eth0.getPacketsSend().getIndex());\n      list.remove(2);\n      list.remove(2);\n      list.add(\"eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0\");\n      netMeter.refreshNet(1);\n\n      Assertions.assertEquals(\"eth0\", eth0.getName());\n\n      // recv Bps\n      Assertions.assertEquals(1L, eth0.getReceive().getLastValue());\n      Assertions.assertEquals(1, eth0.getReceive().getRate(), 0.0);\n      Assertions.assertEquals(0, eth0.getReceive().getIndex());\n      // send Bps\n      Assertions.assertEquals(1L, eth0.getSend().getLastValue());\n      Assertions.assertEquals(1, eth0.getSend().getRate(), 0.0);\n      Assertions.assertEquals(8, eth0.getSend().getIndex());\n\n      // recv pps\n      Assertions.assertEquals(1L, eth0.getPacketsReceive().getLastValue());\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getRate(), 0.0);\n      Assertions.assertEquals(1, eth0.getPacketsReceive().getIndex());\n\n      // send pps\n      Assertions.assertEquals(1L, eth0.getPacketsSend().getLastValue());\n      Assertions.assertEquals(1, eth0.getPacketsSend().getRate(), 0.0);\n      Assertions.assertEquals(9, eth0.getPacketsSend().getIndex());\n    }\n\n  }\n\n  @Test\n  public void testCalcMeasurements() {\n    List<String> list = new ArrayList<>();\n    list.add(\"useless\");\n    list.add(\"useless\");\n    list.add(\"eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n    MeterRegistry meterRegistry = new SimpleMeterRegistry();\n    try (MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class)) {\n      fileUtilsMockedStatic.when(() -> {\n          FileUtils.readLines(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(list);\n\n      NetMeter netMeter = new NetMeter(meterRegistry, \"net\", Tags.empty());\n      netMeter.setOsLinux(true);\n      list.remove(2);\n      list.add(\"eth0: 3 1    0    0    0     0          0          1         3 1    1      0     0     0    0    0\");\n      netMeter.poll(0, 1);\n      MeasurementTree tree = new MeasurementTree();\n      tree.from(meterRegistry.getMeters().iterator(),\n              new MeasurementGroupConfig(\"net\", \"statistic\"));\n\n      Measurement receive = tree.findChild(\"net\", \"receive\").getMeasurements().get(0);\n      Measurement send = tree.findChild(\"net\", \"send\").getMeasurements().get(0);\n      Measurement receivePackets = tree.findChild(\"net\", \"receivePackets\").getMeasurements().get(0);\n      Measurement sendPackets = tree.findChild(\"net\", \"sendPackets\").getMeasurements().get(0);\n      Assertions.assertEquals(3.0, send.getValue(), 0.0);\n      Assertions.assertEquals(1.0, sendPackets.getValue(), 0.0);\n      Assertions.assertEquals(3.0, receive.getValue(), 0.0);\n      Assertions.assertEquals(1.0, receivePackets.getValue(), 0.0);\n    }\n\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/meter/os/TestSystemMeter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.meter.os;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.io.FileUtils;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementGroupConfig;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\n\nimport com.google.common.io.CharSource;\nimport com.google.common.io.Files;\nimport com.sun.management.OperatingSystemMXBean;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\n\npublic class TestSystemMeter {\n  @Test\n  public void testCalcMeasurement() throws IOException {\n    MeterRegistry meterRegistry = new SimpleMeterRegistry();\n    CharSource charSource = Mockito.mock(CharSource.class);\n    List<String> list = new ArrayList<>();\n    list.add(\"useless\");\n    list.add(\"useless\");\n    list.add(\"eth0: 0 0    0    0    0     0          0          0         0 0    0      0     0     0    0    0\");\n\n    try (MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class);\n         MockedStatic<Files> filesMockedStatic = Mockito.mockStatic(Files.class)) {\n      fileUtilsMockedStatic.when(() -> {\n        FileUtils.readLines(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(list);\n      filesMockedStatic.when(() -> {\n        Files.asCharSource(Mockito.any(File.class), Mockito.any(Charset.class));\n      }).thenReturn(charSource);\n\n      OsMeter osMeter = new OsMeter(meterRegistry);\n      list.clear();\n      list.add(\"useless\");\n      list.add(\"useless\");\n      list.add(\"eth0: 1 1    0    0    0     0          0          1         1 1    1      0     0     0    0    0\");\n\n      SystemMeter systemMeter = osMeter.getCpuMeter();\n      OperatingSystemMXBean osBean = Mockito.mock(OperatingSystemMXBean.class);\n      Mockito.when(osBean.getSystemLoadAverage()).thenReturn(0.775);\n      Mockito.when(osBean.getCpuLoad()).thenReturn(0.875);\n      Mockito.when(osBean.getProcessCpuLoad()).thenReturn(0.5);\n      Mockito.when(osBean.getTotalMemorySize()).thenReturn(1000000000L);\n      Mockito.when(osBean.getFreeMemorySize()).thenReturn(300000000L);\n      systemMeter.setOsBean(osBean);\n      NetMeter netMeter = osMeter.getNetMeter();\n      netMeter.setOsLinux(true);\n\n      osMeter.poll(0, 1);\n\n      MeasurementTree tree = new MeasurementTree();\n      tree.from(meterRegistry.getMeters().iterator(),\n          new MeasurementGroupConfig(\"os\", \"type\"));\n\n      Assertions.assertEquals(0.875, tree.findChild(\"os\", \"cpu\").getMeasurements().get(0).getValue(), 0.0);\n      Assertions.assertEquals(0.5, tree.findChild(\"os\", \"processCpu\").getMeasurements().get(0).getValue(), 0.0);\n      Assertions.assertEquals(0.7, tree.findChild(\"os\", \"memory\").getMeasurements().get(0).getValue(), 0.0);\n      Assertions.assertEquals(0.775, tree.findChild(\"os\", \"sla\").getMeasurements().get(0).getValue(), 0.0);\n      Assertions.assertEquals(1.0, tree.findChild(\"os\", \"net\").getMeasurements().get(0).getValue(), 0.0);\n      Assertions.assertEquals(1.0, tree.findChild(\"os\", \"net\").getMeasurements().get(1).getValue(), 0.0);\n      Assertions.assertEquals(1.0, tree.findChild(\"os\", \"net\").getMeasurements().get(2).getValue(), 0.0);\n      Assertions.assertEquals(1.0, tree.findChild(\"os\", \"net\").getMeasurements().get(3).getValue(), 0.0);\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.apache.logging.log4j.core.LogEvent;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.PolledEvent;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.metrics.core.meter.os.OsMeter;\nimport org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerf;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroup;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.PerfInfo;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.FixMethodOrder;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.runners.MethodSorters;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter.Id;\nimport io.micrometer.core.instrument.Meter.Type;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Statistic;\nimport io.micrometer.core.instrument.Tags;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport io.vertx.core.impl.VertxImpl;\nimport jakarta.ws.rs.core.Response.Status;\nimport mockit.Expectations;\nimport mockit.Injectable;\nimport mockit.Mock;\nimport mockit.MockUp;\n\n@FixMethodOrder(MethodSorters.NAME_ASCENDING)\npublic class TestDefaultLogPublisher {\n  MeterRegistry meterRegistry = new SimpleMeterRegistry();\n\n  EventBus eventBus = new EventBus();\n\n  DefaultLogPublisher publisher = new DefaultLogPublisher();\n\n  LogCollector collector = new LogCollector();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setup() {\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n    publisher.setEnvironment(environment);\n  }\n\n  @After\n  public void tearDown() {\n    collector.tearDown();\n  }\n\n  @Test\n  public void init_enabled_default() {\n    Mockito.when(environment.getProperty(DefaultLogPublisher.ENABLED, boolean.class, false)).thenReturn(false);\n    Holder<Boolean> registered = new Holder<>(false);\n    new MockUp<EventBus>(eventBus) {\n      @Mock\n      void register(Object object) {\n        registered.value = true;\n      }\n    };\n\n    publisher.init(meterRegistry, eventBus, new MetricsBootstrapConfig(environment));\n    Assertions.assertFalse(registered.value);\n  }\n\n  @Test\n  public void init_enabled_true() {\n    Mockito.when(environment.getProperty(DefaultLogPublisher.ENABLED, boolean.class, false)).thenReturn(true);\n    Holder<Boolean> registered = new Holder<>();\n    new MockUp<EventBus>(eventBus) {\n      @Mock\n      void register(Object object) {\n        registered.value = true;\n      }\n    };\n\n    publisher.init(meterRegistry, eventBus, new MetricsBootstrapConfig(environment));\n    Assertions.assertTrue(registered.value);\n  }\n\n  @Test\n  public void init_enabled_false() {\n    Mockito.when(environment.getProperty(DefaultLogPublisher.ENABLED, boolean.class, false)).thenReturn(false);\n    Holder<Boolean> registered = new Holder<>();\n    new MockUp<EventBus>(eventBus) {\n      @Mock\n      void register(Object object) {\n        registered.value = true;\n      }\n    };\n\n    publisher.init(meterRegistry, eventBus, new MetricsBootstrapConfig(environment));\n    Assertions.assertNull(registered.value);\n  }\n\n  @Test\n  public void onPolledEvent_failed() {\n    publisher.onPolledEvent(null);\n\n    LogEvent event = collector.getEvents().get(0);\n    Assertions.assertEquals(\"Failed to print perf log.\", event.getMessage().getFormattedMessage());\n    Assertions.assertEquals(NullPointerException.class, event.getThrown().getClass());\n  }\n\n  @Test\n  public void onPolledEvent(@Injectable VertxImpl vertxImpl, @Injectable MeasurementTree tree,\n      @Injectable EventBus eventBus) {\n    MetricsBootstrapConfig config = Mockito.mock(MetricsBootstrapConfig.class);\n    try {\n      Mockito.when(environment.getProperty(DefaultLogPublisher.ENABLED, boolean.class, false)).thenReturn(true);\n      Mockito.when(config.getLatencyDistribution()).thenReturn(\"0,1,100\");\n      publisher.init(meterRegistry, eventBus, config);\n      new Expectations(VertxUtils.class) {\n        {\n          VertxUtils.getVertxMap();\n          result = Collections.singletonMap(\"v\", vertxImpl);\n        }\n      };\n      DefaultPublishModel model = new DefaultPublishModel();\n      PerfInfo perfTotal = new PerfInfo();\n      perfTotal.setTotalRequests(10_0000);\n      perfTotal.setMsTotalTime(30000L * 1_0000);\n      perfTotal.setMsMaxLatency(30000);\n      OperationPerf operationPerf = new OperationPerf();\n      operationPerf.setOperation(\"op\");\n      operationPerf.setLatencyDistribution(new Integer[] {12, 120, 1200});\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_TOTAL, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_PROVIDER_QUEUE, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_CONSUMER_ENCODE_REQUEST, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_CONSUMER_DECODE_RESPONSE, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_PROVIDER_DECODE_REQUEST, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_PROVIDER_ENCODE_RESPONSE, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_PROVIDER_BUSINESS, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_PREPARE, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_CONSUMER_WAIT, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_CONSUMER_SEND, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_PROVIDER_SEND, perfTotal);\n      operationPerf.getStages().put(InvocationStageTrace.STAGE_CONSUMER_CONNECTION, perfTotal);\n\n      OperationPerfGroup operationPerfGroup = new OperationPerfGroup(CoreConst.RESTFUL, Status.OK.name());\n      operationPerfGroup.addOperationPerf(operationPerf);\n\n      OperationPerfGroups operationPerfGroups = new OperationPerfGroups();\n      operationPerfGroups.getGroups().put(operationPerfGroup.getTransport(),\n          Collections.singletonMap(operationPerfGroup.getStatus(), operationPerfGroup));\n      model.getConsumer().setOperationPerfGroups(operationPerfGroups);\n      model.getProducer().setOperationPerfGroups(operationPerfGroups);\n      model.getEdge().setOperationPerfGroups(operationPerfGroups);\n\n      model.getThreadPools().put(\"test\", new ThreadPoolPublishModel());\n      Id id = new Id(\"test\", Tags.empty(), null, null, Type.OTHER);\n      Measurement measurement = new Measurement(() -> 1.0, Statistic.VALUE);\n\n      MeasurementNode measurementNodeCpuAll = new MeasurementNode(\"allProcess\", id, new HashMap<>());\n      MeasurementNode measurementNodeCpuProcess = new MeasurementNode(\"currentProcess\", id, new HashMap<>());\n      MeasurementNode measurementNodeSla = new MeasurementNode(\"sla\", id, new HashMap<>());\n      MeasurementNode measurementNodeMemory = new MeasurementNode(\"memory\", id, new HashMap<>());\n      MeasurementNode measurementNodeSend = new MeasurementNode(\"send\", id, new HashMap<>());\n      MeasurementNode measurementNodeSendPacket = new MeasurementNode(\"sendPackets\", id, new HashMap<>());\n      MeasurementNode measurementNodeRecv = new MeasurementNode(\"receive\", id, new HashMap<>());\n      MeasurementNode measurementNodeRecvPacket = new MeasurementNode(\"receivePackets\", id, new HashMap<>());\n      MeasurementNode measurementNodeEth0 = new MeasurementNode(\"eth0\", id, new HashMap<>());\n      MeasurementNode measurementNodeNet = new MeasurementNode(\"net\", id, new HashMap<>());\n      MeasurementNode measurementNodeOs = new MeasurementNode(\"os\", id, new HashMap<>());\n\n      measurementNodeSend.getMeasurements().add(measurement);\n      measurementNodeRecv.getMeasurements().add(measurement);\n      measurementNodeCpuAll.getMeasurements().add(measurement);\n      measurementNodeCpuProcess.getMeasurements().add(measurement);\n      measurementNodeSla.getMeasurements().add(measurement);\n      measurementNodeMemory.getMeasurements().add(measurement);\n      measurementNodeRecvPacket.getMeasurements().add(measurement);\n      measurementNodeSendPacket.getMeasurements().add(measurement);\n\n      measurementNodeEth0.getChildren().put(\"send\", measurementNodeSend);\n      measurementNodeEth0.getChildren().put(\"receive\", measurementNodeRecv);\n      measurementNodeEth0.getChildren().put(\"receivePackets\", measurementNodeRecvPacket);\n      measurementNodeEth0.getChildren().put(\"sendPackets\", measurementNodeSendPacket);\n\n      measurementNodeNet.getChildren().put(\"eth0\", measurementNodeEth0);\n      measurementNodeOs.getChildren().put(\"cpu\", measurementNodeCpuAll);\n      measurementNodeOs.getChildren().put(\"processCpu\", measurementNodeCpuProcess);\n      measurementNodeOs.getChildren().put(\"sla\", measurementNodeSla);\n      measurementNodeOs.getChildren().put(\"memory\", measurementNodeMemory);\n      measurementNodeOs.getChildren().put(\"net\", measurementNodeNet);\n\n      measurementNodeOs.getMeasurements().add(measurement);\n      measurementNodeNet.getMeasurements().add(measurement);\n      measurementNodeEth0.getMeasurements().add(measurement);\n\n      new MockUp<PublishModelFactory>() {\n        @Mock\n        DefaultPublishModel createDefaultPublishModel() {\n          return model;\n        }\n\n        @Mock\n        MeasurementTree getTree() {\n          return tree;\n        }\n      };\n      new Expectations() {\n        {\n          tree.findChild(OsMeter.OS_NAME);\n          result = measurementNodeOs;\n        }\n      };\n      publisher.onPolledEvent(new PolledEvent(Collections.emptyList()));\n      List<LogEvent> events = collector.getEvents().stream()\n          .filter(e -> \"scb-metrics\".equals(e.getLoggerName())).toList();\n      LogEvent event = events.get(0);\n      Assertions.assertEquals(\"\"\"\n              os:\n                cpu:\n                  all usage: 100.00%    process usage: 100.00%    sla: 1.00    memory usage: 100.00%\n                net:\n                  send(Bps)    recv(Bps)    send(pps)    recv(pps)    interface\n                  1            1            1            1            eth0\n              vertx:\n                instances:\n                  name       eventLoopContext-created\n                  v          0\n              threadPool:\n                coreSize maxThreads poolSize currentBusy rejected queueSize taskCount taskFinished name\n                0        0          0        0           NaN      0         0.0       0.0          test\n              consumer:\n               simple:\n                status      requests      latency       [0,1) [1,100) [100,) operation\n                rest.OK:  \\s\n                            100000.0 3000.000/30000.000 12    120     1200   op\n                            100000.0 3000.000/30000.000 12    120     1200   (summary)\n               details:\n                  rest.OK:\n                    op:\n                      prepare     : 3000.000/30000.000 connection : 3000.000/30000.000 encode-request: 3000.000/30000.000 send     : 3000.000/30000.000\n                      wait  : 3000.000/30000.000 decode-response    : 3000.000/30000.000\n              producer:\n               simple:\n                status      requests      latency       [0,1) [1,100) [100,) operation\n                rest.OK:  \\s\n                            100000.0 3000.000/30000.000 12    120     1200   op\n                            100000.0 3000.000/30000.000 12    120     1200   (summary)\n               details:\n                  rest.OK:\n                    op:\n                      prepare: 3000.000/30000.000 decode-request       : 3000.000/30000.000 queue : 3000.000/30000.000 business-execute: 3000.000/30000.000\n                      encode-response: 3000.000/30000.000 send: 3000.000/30000.000\n              edge:\n               simple:\n                status      requests      latency       [0,1) [1,100) [100,) operation\n                rest.OK:  \\s\n                            100000.0 3000.000/30000.000 12    120     1200   op\n                            100000.0 3000.000/30000.000 12    120     1200   (summary)\n               details:\n                  rest.OK:\n                    op:\n                      prepare     : 3000.000/30000.000 provider-decode       : 3000.000/30000.000 connection : 3000.000/30000.000 consumer-encode : 3000.000/30000.000\n                      consumer-send : 3000.000/30000.000 wait     : 3000.000/30000.000 consumer-decode  : 3000.000/30000.000 provider-encode    : 3000.000/30000.000\n                      provider-send    : 3000.000/30000.000\n              \"\"\".trim(),\n          event.getMessage().getFormattedMessage().trim());\n    } catch (Exception e) {\n      e.printStackTrace();\n      Assertions.fail(\"unexpected error happen. \" + e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.metrics.core.InvocationMetersInitializer;\nimport org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport io.vertx.core.json.Json;\n\nimport org.skyscreamer.jsonassert.JSONAssert;\n\npublic class TestInvocationPublishModelFactory {\n  EventBus eventBus = new EventBus();\n\n  // not step mode.\n  MeterRegistry meterRegistry = new SimpleMeterRegistry();\n\n  InvocationMetersInitializer invocationMetersInitializer = new InvocationMetersInitializer();\n\n  Invocation invocation = Mockito.mock(Invocation.class);\n\n  InvocationStageTrace invocationStageTrace = Mockito.mock(InvocationStageTrace.class);\n\n  Response response = Mockito.mock(Response.class);\n\n  InvocationType invocationType;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Test\n  public void createDefaultPublishModel() throws Exception {\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n    Mockito.when(environment.getProperty(CONFIG_LATENCY_DISTRIBUTION, String.class)).thenReturn(\"0,1,100\");\n\n    invocationMetersInitializer.init(meterRegistry, eventBus, new MetricsBootstrapConfig(environment));\n    prepareInvocation();\n\n    PublishModelFactory factory = new PublishModelFactory(meterRegistry.getMeters());\n    DefaultPublishModel model = factory.createDefaultPublishModel();\n\n    String expect = \"\"\"\n        {\n            \"operationPerfGroups\" : {\n              \"groups\" : {\n                \"rest\" : {\n                  \"200\" : {\n                    \"transport\" : \"rest\",\n                    \"status\" : \"200\",\n                    \"operationPerfs\" : [ {\n                      \"operation\" : \"m.s.o\",\n                      \"stages\" : {\n                        \"consumer-encode\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"prepare\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"wait\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"total\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.4E-5,\n                          \"msMaxLatency\" : 1.4E-5\n                        },\n                        \"consumer-send\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"connection\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"consumer-decode\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        }\n                      },\n                      \"latencyDistribution\" : [ 1, 1, 1 ]\n                    } ],\n                    \"summary\" : {\n                      \"operation\" : \"\",\n                      \"stages\" : {\n                        \"consumer-encode\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"prepare\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"total\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.4E-5,\n                          \"msMaxLatency\" : 1.4E-5\n                        },\n                        \"wait\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"consumer-send\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"connection\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        },\n                        \"consumer-decode\" : {\n                          \"totalRequests\" : 1.0,\n                          \"msTotalTime\" : 1.0000000000000002E-6,\n                          \"msMaxLatency\" : 1.0000000000000002E-6\n                        }\n                      },\n                      \"latencyDistribution\" : [ 1, 1, 1 ]\n                    }\n                  }\n                }\n              }\n            }\n          }\n        \"\"\";\n    JSONAssert.assertEquals(Json.encodePrettily(Json.decodeValue(expect, Object.class)),\n        Json.encodePrettily(model.getConsumer()), false);\n\n    expect = \"\"\"\n        {\n          \"operationPerfGroups\" : {\n            \"groups\" : {\n              \"rest\" : {\n                \"200\" : {\n                  \"transport\" : \"rest\",\n                  \"status\" : \"200\",\n                  \"operationPerfs\" : [ {\n                    \"operation\" : \"m.s.o\",\n                    \"stages\" : {\n                      \"consumer-encode\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"prepare\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"wait\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"total\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.4E-5,\n                        \"msMaxLatency\" : 1.4E-5\n                      },\n                      \"consumer-send\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"connection\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"consumer-decode\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      }\n                    },\n                    \"latencyDistribution\" : [ 1, 1, 1 ]\n                  } ],\n                  \"summary\" : {\n                    \"operation\" : \"\",\n                    \"stages\" : {\n                      \"consumer-encode\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"prepare\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"total\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.4E-5,\n                        \"msMaxLatency\" : 1.4E-5\n                      },\n                      \"wait\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"consumer-send\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"connection\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      },\n                      \"consumer-decode\" : {\n                        \"totalRequests\" : 1.0,\n                        \"msTotalTime\" : 1.0000000000000002E-6,\n                        \"msMaxLatency\" : 1.0000000000000002E-6\n                      }\n                    },\n                    \"latencyDistribution\" : [ 1, 1, 1 ]\n                  }\n                }\n              }\n            }\n          }\n        }\n        \"\"\";\n    JSONAssert.assertEquals(Json.encodePrettily(Json.decodeValue(expect, Object.class)),\n        Json.encodePrettily(model.getProducer()), false);\n  }\n\n  protected void prepareInvocation() {\n    Mockito.when(invocationStageTrace.calcTotal()).thenReturn(14L);\n    Mockito.when(invocationStageTrace.calcPrepare()).thenReturn(1L);\n    Mockito.when(invocationStageTrace.calcConnection()).thenReturn(1L);\n    Mockito.when(invocationStageTrace.calcConsumerEncodeRequest()).thenReturn(1L);\n    Mockito.when(invocationStageTrace.calcConsumerSendRequest()).thenReturn(1L);\n    Mockito.when(invocationStageTrace.calcWait()).thenReturn(1L);\n    Mockito.when(invocationStageTrace.calcConsumerDecodeResponse()).thenReturn(1L);\n\n    invocationType = InvocationType.CONSUMER;\n\n    Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);\n    Mockito.when(invocation.isConsumer()).thenReturn(InvocationType.CONSUMER.equals(invocationType));\n    Mockito.when(invocation.getRealTransportName()).thenReturn(CoreConst.RESTFUL);\n    Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn(\"m.s.o\");\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);\n    Mockito.when(response.getStatusCode()).thenReturn(200);\n\n    InvocationFinishEvent finishEvent = new InvocationFinishEvent(invocation, response);\n    eventBus.post(finishEvent);\n\n    invocationType = InvocationType.PROVIDER;\n    Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);\n    eventBus.post(finishEvent);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestPublishUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementTree;\nimport org.apache.servicecomb.metrics.core.meter.ThreadPoolMonitorPublishModelFactory;\nimport org.apache.servicecomb.metrics.core.publish.model.ThreadPoolPublishModel;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerf;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroup;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.OperationPerfGroups;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.PerfInfo;\nimport org.apache.servicecomb.metrics.core.publish.model.invocation.Utils;\nimport org.junit.jupiter.api.Assertions;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPublishUtils {\n  String op = \"op\";\n\n  @Test\n  public void createPerfInfo() {\n    MeasurementNode stageNode = Utils.createStageNode(InvocationStageTrace.STAGE_TOTAL, 10, 10, 100);\n\n    PerfInfo perf = PublishUtils.createPerfInfo(stageNode);\n\n    Assertions.assertEquals(10, perf.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perf.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perf.getMsMaxLatency(), 0);\n  }\n\n  @Test\n  public void createOperationPerf() {\n    OperationPerf opPerf = Utils.createOperationPerf(op);\n\n    PerfInfo perfInfo = opPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n    Integer[] latencyDistribution = opPerf.getLatencyDistribution();\n    Assertions.assertEquals(10, perfInfo.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perfInfo.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);\n    Assertions.assertEquals(2, latencyDistribution.length);\n    Assertions.assertEquals(1, latencyDistribution[0].intValue());\n    Assertions.assertEquals(2, latencyDistribution[1].intValue());\n  }\n\n  @Test\n  public void addOperationPerfGroups() {\n    OperationPerfGroups groups = new OperationPerfGroups();\n    PublishUtils.addOperationPerfGroups(groups,\n        CoreConst.RESTFUL,\n        op,\n        Utils.createStatusNode(Status.OK.name(), Utils.totalStageNode));\n\n    Map<String, OperationPerfGroup> statusMap = groups.getGroups().get(CoreConst.RESTFUL);\n    OperationPerfGroup group = statusMap.get(Status.OK.name());\n\n    PerfInfo perfInfo = group.getSummary().findStage(InvocationStageTrace.STAGE_TOTAL);\n    Integer[] latencyDistribution = group.getSummary().getLatencyDistribution();\n    Assertions.assertEquals(10, perfInfo.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perfInfo.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);\n    Assertions.assertEquals(2, latencyDistribution.length);\n    Assertions.assertEquals(1, latencyDistribution[0].intValue());\n    Assertions.assertEquals(2, latencyDistribution[1].intValue());\n  }\n\n  @Test\n  public void createThreadPoolPublishModels_empty() {\n    Map<String, ThreadPoolPublishModel> threadPools =\n        ThreadPoolMonitorPublishModelFactory.create(new MeasurementTree());\n\n    Assertions.assertTrue(threadPools.isEmpty());\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.OperationConfig;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.event.InvocationFinishEvent;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.Mockito;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport com.google.common.eventbus.EventBus;\n\n@ExtendWith(MockitoExtension.class)\npublic class TestSlowInvocationLogger {\n  @Mock\n  SCBEngine scbEngine;\n\n  @Mock\n  Invocation invocation;\n\n  @Mock\n  OperationMeta operationMeta;\n\n  @Mock\n  RestOperationMeta restOperationMeta;\n\n  @Mock\n  OperationConfig operationConfig;\n\n  @Mock\n  Response response;\n\n  @Mock\n  InvocationStageTrace stageTrace;\n\n  InvocationFinishEvent event;\n\n  SlowInvocationLogger logger;\n\n  LogCollector logCollector;\n\n  @BeforeEach\n  public void setup() {\n    EventBus eventBus = Mockito.spy(EventBus.class);\n    Mockito.doNothing().when(eventBus).register(Mockito.any());\n    Mockito.when(scbEngine.getEventBus()).thenReturn(eventBus);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(operationMeta.getConfig()).thenReturn(operationConfig);\n\n    logger = new SlowInvocationLogger(scbEngine);\n    event = new InvocationFinishEvent(invocation, response);\n    logCollector = new LogCollector();\n  }\n\n  @AfterEach\n  public void tearDown() {\n    logCollector.tearDown();\n  }\n\n  @Test\n  public void disable() {\n    logger.onInvocationFinish(event);\n\n    Assertions.assertTrue(logCollector.getEvents().isEmpty());\n  }\n\n  @Test\n  public void enableButNotSlow() {\n\n    Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);\n    Mockito.when(operationConfig.getNanoSlowInvocation()).thenReturn(2L);\n    Mockito.when(stageTrace.calcTotal()).thenReturn(1L);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);\n    logger.onInvocationFinish(event);\n\n    Assertions.assertTrue(logCollector.getEvents().isEmpty());\n  }\n\n  @Test\n  public void consumerSlow() {\n    Endpoint endpoint = Mockito.mock(Endpoint.class);\n    Mockito.when(invocation.getEndpoint()).thenReturn(endpoint);\n    Mockito.when(endpoint.getEndpoint()).thenReturn(\"rest://1.1.1.1:1234\");\n    Mockito.when(invocation.isProducer()).thenReturn(false);\n    Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);\n    Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);\n    Mockito.when(operationConfig.getNanoSlowInvocation()).thenReturn(1L);\n    Mockito.when(stageTrace.calcTotal()).thenReturn(1L);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);\n    logger.onInvocationFinish(event);\n\n    Assertions.assertEquals(\"\"\"\n            Slow Consumer invocation [null](0 ms)[null]\n              http method       :                 null\n              url               :                 null\n              endpoint          :  rest://1.1.1.1:1234\n              status code       :                    0\n                total           :      0.0ms\n                prepare         :      0.0ms\n                connection      :      0.0ms\n                consumer-encode :      0.0ms\n                consumer-send   :      0.0ms\n                wait            :      0.0ms\n                consumer-decode :      0.0ms\n            \"\"\",\n        logCollector.getEvent(0).getMessage().getFormattedMessage());\n  }\n\n  @Test\n  public void edgeSlow() {\n    Endpoint endpoint = Mockito.mock(Endpoint.class);\n    Mockito.when(invocation.getEndpoint()).thenReturn(endpoint);\n    Mockito.when(endpoint.getEndpoint()).thenReturn(\"rest://1.1.1.1:1234\");\n    Mockito.when(invocation.isEdge()).thenReturn(true);\n    Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);\n    Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);\n    Mockito.when(operationConfig.getNanoSlowInvocation()).thenReturn(1L);\n    Mockito.when(stageTrace.calcTotal()).thenReturn(1L);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);\n    logger.onInvocationFinish(event);\n\n    Assertions.assertEquals(\"\"\"\n            Slow Edge invocation [null](0 ms)[null]\n              http method       :                 null\n              url               :                 null\n              endpoint          :  rest://1.1.1.1:1234\n              status code       :                    0\n                total           :      0.0ms\n                prepare         :      0.0ms\n                provider-decode :      0.0ms\n                connection      :      0.0ms\n                consumer-encode :      0.0ms\n                consumer-send   :      0.0ms\n                wait            :      0.0ms\n                consumer-decode :      0.0ms\n                provider-encode :      0.0ms\n                provider-send   :      0.0ms\n            \"\"\",\n        logCollector.getEvent(0).getMessage().getFormattedMessage());\n  }\n\n  @Test\n  public void producerSlow() {\n\n    HttpServletRequestEx requestEx = Mockito.mock(HttpServletRequestEx.class);\n\n    Mockito.when(invocation.getRequestEx()).thenReturn(requestEx);\n    Mockito.when(requestEx.getRemoteAddr()).thenReturn(\"1.1.1.1\");\n    Mockito.when(requestEx.getRemotePort()).thenReturn(1234);\n    Mockito.when(invocation.isProducer()).thenReturn(true);\n    Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);\n    Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);\n    Mockito.when(operationConfig.getNanoSlowInvocation()).thenReturn(1L);\n    Mockito.when(stageTrace.calcTotal()).thenReturn(1L);\n    Mockito.when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);\n\n    logger.onInvocationFinish(event);\n\n    Assertions.assertEquals(\"\"\"\n            Slow Provider invocation [null](0 ms)[null]\n              http method       :                 null\n              url               :                 null\n              endpoint          :         1.1.1.1:1234\n              status code       :                    0\n                total           :      0.0ms\n                prepare         :      0.0ms\n                provider-decode :      0.0ms\n                queue           :      0.0ms\n                execute         :      0.0ms\n                provider-encode :      0.0ms\n                provider-send   :      0.0ms\n            \"\"\",\n        logCollector.getEvent(0).getMessage().getFormattedMessage());\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish;\n\nimport java.util.concurrent.BlockingQueue;\n\nimport org.apache.servicecomb.core.executor.ThreadPoolExecutorEx;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.metrics.core.ThreadPoolMetersInitializer;\nimport org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel;\nimport org.junit.jupiter.api.MethodOrderer;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.TestMethodOrder;\nimport org.junit.jupiter.api.extension.ExtendWith;\nimport org.mockito.Mock;\nimport org.mockito.Mockito;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport org.mockito.junit.jupiter.MockitoExtension;\n\nimport org.skyscreamer.jsonassert.JSONAssert;\n\n@ExtendWith(MockitoExtension.class)\n@TestMethodOrder(MethodOrderer.MethodName.class)\npublic class TestThreadPoolPublishModelFactory {\n  MeterRegistry registry = new SimpleMeterRegistry();\n\n  @Mock\n  BlockingQueue<Runnable> queue;\n\n  @Test\n  public void createDefaultPublishModel() throws Exception {\n    ThreadPoolExecutorEx threadPoolExecutor = Mockito.mock(ThreadPoolExecutorEx.class);\n    Mockito.when(threadPoolExecutor.getQueue()).thenReturn(queue);\n    Mockito.doReturn(10).when(queue).size();\n\n    MetricsBootstrapConfig metricsBootstrapConfig = Mockito.mock(MetricsBootstrapConfig.class);\n    ThreadPoolMetersInitializer threadPoolMetersInitializer = new ThreadPoolMetersInitializer() {\n      @Override\n      public void createThreadPoolMeters() {\n        createThreadPoolMeters(\"test\", threadPoolExecutor);\n      }\n    };\n    threadPoolMetersInitializer.init(registry, EventManager.getEventBus(), metricsBootstrapConfig);\n    PublishModelFactory factory = new PublishModelFactory(registry.getMeters());\n    DefaultPublishModel model = factory.createDefaultPublishModel();\n\n    JSONAssert.assertEquals(\n        \"\"\"\n            {\"test\":{\"avgTaskCount\":0.0,\"avgCompletedTaskCount\":0.0,\"currentThreadsBusy\":0,\"maxThreads\":0,\"poolSize\":0,\"corePoolSize\":0,\"queueSize\":10,\"rejected\":0.0}}\"\"\",\n        JsonUtils.writeValueAsString(model.getThreadPools()), false);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/model/invocation/TestOperationPerf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestOperationPerf {\n  String op = \"op\";\n\n  OperationPerf opPerf = new OperationPerf();\n\n  @Test\n  public void add() {\n    Assertions.assertTrue(opPerf.getStages().isEmpty());\n\n    OperationPerf otherOpPerf = Utils.createOperationPerf(op);\n    opPerf.add(otherOpPerf);\n\n    Assertions.assertEquals(op, otherOpPerf.getOperation());\n\n    PerfInfo perfInfo = opPerf.findStage(InvocationStageTrace.STAGE_TOTAL);\n    Assertions.assertEquals(10, perfInfo.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perfInfo.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);\n\n    perfInfo = opPerf.findStage(InvocationStageTrace.STAGE_PROVIDER_BUSINESS);\n    Assertions.assertEquals(10, perfInfo.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perfInfo.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/model/invocation/TestOperationPerfGroup.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.junit.jupiter.api.Assertions;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport org.junit.jupiter.api.Test;\n\npublic class TestOperationPerfGroup {\n  String op = \"op\";\n\n  OperationPerfGroup group = new OperationPerfGroup(CoreConst.RESTFUL, Status.OK.name());\n\n  @Test\n  public void construct() {\n    Assertions.assertEquals(CoreConst.RESTFUL, group.getTransport());\n    Assertions.assertEquals(Status.OK.name(), group.getStatus());\n    Assertions.assertTrue(group.getOperationPerfs().isEmpty());\n    Assertions.assertNull(group.getSummary());\n  }\n\n  @Test\n  public void addOperationPerf() {\n    OperationPerf opPerf = Utils.createOperationPerf(op);\n    group.addOperationPerf(opPerf);\n    group.addOperationPerf(opPerf);\n\n    Assertions.assertTrue(group.getOperationPerfs().contains(opPerf));\n\n    OperationPerf summary = group.getSummary();\n\n    PerfInfo perfInfo = summary.findStage(InvocationStageTrace.STAGE_TOTAL);\n    Assertions.assertEquals(20, perfInfo.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perfInfo.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);\n\n    perfInfo = summary.findStage(InvocationStageTrace.STAGE_PROVIDER_BUSINESS);\n    Assertions.assertEquals(20, perfInfo.getTotalRequests(), 0);\n    Assertions.assertEquals(1000, perfInfo.calcMsLatency(), 0);\n    Assertions.assertEquals(100000, perfInfo.getMsMaxLatency(), 0);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/model/invocation/TestPerfInfo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPerfInfo {\n  @Test\n  public void construct() {\n    PerfInfo perf = new PerfInfo();\n\n    Assertions.assertEquals(0, perf.getTotalRequests(), 0);\n    Assertions.assertEquals(0, perf.getMsTotalTime(), 0);\n    Assertions.assertEquals(0, perf.getMsMaxLatency(), 0);\n    Assertions.assertEquals(0, perf.calcMsLatency(), 0);\n  }\n\n  @Test\n  public void add_changeMax() {\n    PerfInfo sum = new PerfInfo();\n\n    PerfInfo other = new PerfInfo();\n    other.setTotalRequests(10);\n    other.setMsTotalTime(10);\n    other.setMsMaxLatency(100);\n    sum.add(other);\n\n    other = new PerfInfo();\n    other.setTotalRequests(20);\n    other.setMsTotalTime(20);\n    other.setMsMaxLatency(200);\n    sum.add(other);\n\n    Assertions.assertEquals(30, sum.getTotalRequests(), 0);\n    Assertions.assertEquals(30, sum.getMsTotalTime(), 0);\n    Assertions.assertEquals(200, sum.getMsMaxLatency(), 0);\n    Assertions.assertEquals(1.0, sum.calcMsLatency(), 0);\n  }\n\n  @Test\n  public void add_notChangeMax() {\n    PerfInfo sum = new PerfInfo();\n\n    PerfInfo other = new PerfInfo();\n    other.setTotalRequests(10);\n    other.setMsTotalTime(10);\n    other.setMsMaxLatency(100);\n    sum.add(other);\n\n    other = new PerfInfo();\n    other.setTotalRequests(20);\n    other.setMsTotalTime(20);\n    other.setMsMaxLatency(50);\n    sum.add(other);\n\n    Assertions.assertEquals(30, sum.getTotalRequests(), 0);\n    Assertions.assertEquals(1.0, sum.calcMsLatency(), 0);\n    Assertions.assertEquals(100, sum.getMsMaxLatency(), 0);\n  }\n\n  @Test\n  public void testToString() {\n    PerfInfo perf = new PerfInfo();\n    perf.setTotalRequests(10);\n    perf.setMsTotalTime(10);\n    perf.setMsMaxLatency(100);\n\n    Assertions.assertEquals(\"PerfInfo [tps=10.0, msTotalTime=10.0, msLatency=1.0, msMaxLatency=100.0]\", perf.toString());\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/model/invocation/Utils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.core.publish.model.invocation;\n\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.apache.servicecomb.core.invocation.InvocationStageTrace;\nimport org.apache.servicecomb.foundation.metrics.publish.MeasurementNode;\nimport org.apache.servicecomb.metrics.core.meter.invocation.MeterInvocationConst;\nimport org.apache.servicecomb.metrics.core.publish.PublishUtils;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter.Id;\nimport io.micrometer.core.instrument.Meter.Type;\nimport io.micrometer.core.instrument.Statistic;\nimport io.micrometer.core.instrument.Tags;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class Utils {\n  public static MeasurementNode totalStageNode = Utils.createStageNode(InvocationStageTrace.STAGE_TOTAL, 10, 10, 100);\n\n  public static MeasurementNode executeStageNode =\n      Utils.createStageNode(InvocationStageTrace.STAGE_PROVIDER_BUSINESS, 10, 10, 100);\n\n  public static Id initId = new Id(\"id\", Tags.empty(), null, null, Type.OTHER);\n\n  public static MeasurementNode createStageNode(String stage,\n      double count,\n      double totalTime,\n      double max) {\n    Id id = initId;\n    Measurement countMeasurement = new Measurement(() -> count, Statistic.COUNT);\n    Measurement totalTimeMeasurement = new Measurement(() -> totalTime, Statistic.TOTAL_TIME);\n    Measurement maxMeasurement = new Measurement(() -> max, Statistic.MAX);\n\n    MeasurementNode stageNode = new MeasurementNode(stage, id, null);\n    stageNode.addChild(Statistic.COUNT.name(), id, countMeasurement);\n    stageNode.addChild(Statistic.TOTAL_TIME.name(), id, totalTimeMeasurement);\n    stageNode.addChild(Statistic.MAX.name(), id, maxMeasurement);\n\n    return stageNode;\n  }\n\n  public static MeasurementNode createStatusNode(String status, MeasurementNode... stageNodes) {\n    Id id = initId;\n    MeasurementNode statusNode = new MeasurementNode(status, id, new HashMap<>());\n    MeasurementNode typeNode = new MeasurementNode(MeterInvocationConst.TAG_STAGE, id, new HashMap<>());\n    MeasurementNode latencyNode = new MeasurementNode(MeterInvocationConst.TAG_DISTRIBUTION, id,\n        new HashMap<>());\n    List<Measurement> measurements = latencyNode.getMeasurements();\n    measurements.add(new Measurement(() -> 1, Statistic.VALUE));\n    measurements.add(new Measurement(() -> 2, Statistic.VALUE));\n    for (MeasurementNode stageNode : stageNodes) {\n      typeNode.getChildren().put(stageNode.getName(), stageNode);\n    }\n    statusNode.getChildren().put(latencyNode.getName(), latencyNode);\n    statusNode.getChildren().put(typeNode.getName(), typeNode);\n    return statusNode;\n  }\n\n  public static OperationPerf createOperationPerf(String op) {\n    MeasurementNode statusNode = createStatusNode(Status.OK.name(), totalStageNode, executeStageNode);\n    return PublishUtils.createOperationPerf(op, statusNode);\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-core/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "metrics/metrics-integration/metrics-prometheus/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>metrics-integration</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>metrics-prometheus</artifactId>\n  <name>Java Chassis::Metrics::Integration::Prometheus</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>io.prometheus</groupId>\n      <artifactId>simpleclient</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.prometheus</groupId>\n      <artifactId>simpleclient_httpserver</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/PrometheusConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.metrics.prometheus;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class PrometheusConfiguration {\n  @Bean\n  public PrometheusPublisher prometheusPublisher() {\n    return new PrometheusPublisher();\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-integration/metrics-prometheus/src/main/java/org/apache/servicecomb/metrics/prometheus/PrometheusPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.prometheus;\n\nimport java.net.InetSocketAddress;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\nimport io.prometheus.client.Collector;\nimport io.prometheus.client.Collector.MetricFamilySamples.Sample;\nimport io.prometheus.client.CollectorRegistry;\nimport io.prometheus.client.exporter.HTTPServer;\n\npublic class PrometheusPublisher extends Collector implements Collector.Describable, MetricsInitializer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PrometheusPublisher.class);\n\n  public static final String METRICS_PROMETHEUS_ADDRESS = \"servicecomb.metrics.prometheus.address\";\n\n  private HTTPServer httpServer;\n\n  private MeterRegistry meterRegistry;\n\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    this.meterRegistry = meterRegistry;\n\n    //prometheus default port allocation is here : https://github.com/prometheus/prometheus/wiki/Default-port-allocations\n    String address = environment.getProperty(METRICS_PROMETHEUS_ADDRESS, String.class, \"0.0.0.0:9696\");\n\n    try {\n      InetSocketAddress socketAddress = getSocketAddress(address);\n      register();\n      this.httpServer = new HTTPServer(socketAddress, CollectorRegistry.defaultRegistry, true);\n\n      LOGGER.info(\"Prometheus httpServer listened : {}.\", address);\n    } catch (Exception e) {\n      throw new ServiceCombException(\"create http publish server failed,may bad address : \" + address, e);\n    }\n  }\n\n  private InetSocketAddress getSocketAddress(String address) {\n    String[] hostAndPort = address.split(\":\");\n    if (hostAndPort.length == 2) {\n      return new InetSocketAddress(hostAndPort[0], Integer.parseInt(hostAndPort[1]));\n    }\n    throw new ServiceCombException(\"create http publish server failed,bad address : \" + address);\n  }\n\n  @Override\n  public List<MetricFamilySamples> describe() {\n    List<MetricFamilySamples> familySamples = new ArrayList<>();\n\n    List<Sample> samples = new ArrayList<>();\n\n    for (Meter meter : this.meterRegistry.getMeters()) {\n      meter.measure().forEach(measurement -> {\n        Sample sample = convertMeasurementToSample(meter, measurement);\n        samples.add(sample);\n      });\n    }\n\n    familySamples.add(new MetricFamilySamples(\"ServiceComb_Metrics\", Type.UNKNOWN, \"ServiceComb Metrics\", samples));\n\n    return familySamples;\n  }\n\n  protected Sample convertMeasurementToSample(Meter meter, Measurement measurement) {\n    String prometheusName = meter.getId().getName().replace(\".\", \"_\");\n    List<String> labelNames = new ArrayList<>();\n    List<String> labelValues = new ArrayList<>();\n\n    labelNames.add(\"appId\");\n    labelValues.add(BootStrapProperties.readApplication(environment));\n\n    for (Tag tag : meter.getId().getTags()) {\n      labelNames.add(tag.getKey());\n      labelValues.add(tag.getValue());\n    }\n\n    return new Sample(prometheusName, labelNames, labelValues, measurement.getValue());\n  }\n\n  @Override\n  public List<MetricFamilySamples> collect() {\n    return describe();\n  }\n\n  @Override\n  public void destroy() {\n    if (httpServer == null) {\n      return;\n    }\n\n    httpServer.close();\n    httpServer = null;\n    LOGGER.info(\"Prometheus httpServer stopped.\");\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-integration/metrics-prometheus/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.metrics.prometheus.PrometheusConfiguration\n"
  },
  {
    "path": "metrics/metrics-integration/metrics-prometheus/src/test/java/org/apache/servicecomb/metrics/prometheus/TestPrometheusPublisher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.metrics.prometheus;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.metrics.prometheus.PrometheusPublisher.METRICS_PROMETHEUS_ADDRESS;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.reflect.FieldUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.sun.net.httpserver.HttpServer;\n\nimport io.micrometer.core.instrument.Counter;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\nimport io.prometheus.client.exporter.HTTPServer;\n\npublic class TestPrometheusPublisher {\n  MeterRegistry meterRegistry = new SimpleMeterRegistry();\n\n  PrometheusPublisher publisher = new PrometheusPublisher();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    publisher.setEnvironment(environment);\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n  }\n\n  @AfterAll\n  public static void teardown() {\n  }\n\n  @Test\n  public void testBadPublishAddress() {\n    Mockito.when(environment.getProperty(METRICS_PROMETHEUS_ADDRESS, String.class, \"0.0.0.0:9696\"))\n        .thenReturn(\"a:b:c\");\n    Assertions.assertThrows(ServiceCombException.class, () -> {\n      publisher.init(meterRegistry, null, null);\n    });\n  }\n\n  @Test\n  public void testBadPublishAddress_BadPort() {\n    Mockito.when(environment.getProperty(METRICS_PROMETHEUS_ADDRESS, String.class, \"0.0.0.0:9696\"))\n        .thenReturn(\"localhost:xxxx\");\n    Assertions.assertThrows(ServiceCombException.class, () -> {\n      publisher.init(meterRegistry, null, null);\n    });\n  }\n\n  @Test\n  public void testBadPublishAddress_TooLargePort() {\n    Mockito.when(environment.getProperty(METRICS_PROMETHEUS_ADDRESS, String.class, \"0.0.0.0:9696\"))\n        .thenReturn(\"localhost:9999999\");\n    Assertions.assertThrows(ServiceCombException.class, () -> {\n      publisher.init(meterRegistry, null, null);\n    });\n  }\n\n  @Test\n  public void collect() throws IllegalAccessException, IOException {\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_APPLICATION)).thenReturn(\"testAppId\");\n    Mockito.when(environment.getProperty(METRICS_PROMETHEUS_ADDRESS, String.class, \"0.0.0.0:9696\"))\n        .thenReturn(\"localhost:0\");\n    publisher.setEnvironment(environment);\n    publisher.init(meterRegistry, null, new MetricsBootstrapConfig(environment));\n\n    Counter counter = meterRegistry.counter(\"count.name\", \"tag1\", \"tag1v\", \"tag2\", \"tag2v\");\n    counter.increment();\n\n    HTTPServer httpServer = (HTTPServer) FieldUtils.readField(publisher, \"httpServer\", true);\n    com.sun.net.httpserver.HttpServer server = (HttpServer) FieldUtils.readField(httpServer, \"server\", true);\n\n    URL url = new URL(\"http://localhost:\" + server.getAddress().getPort() + \"/metrics\");\n    HttpURLConnection conn = (HttpURLConnection) url.openConnection();\n    try (InputStream is = conn.getInputStream()) {\n      Assertions.assertEquals(\"\"\"\n              # HELP ServiceComb_Metrics ServiceComb Metrics\n              # TYPE ServiceComb_Metrics untyped\n              count_name{appId=\"testAppId\",tag1=\"tag1v\",tag2=\"tag2v\",} 1.0\n              \"\"\",\n          IOUtils.toString(is, StandardCharsets.UTF_8));\n    }\n\n    publisher.destroy();\n  }\n}\n"
  },
  {
    "path": "metrics/metrics-integration/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>metrics</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>metrics-integration</artifactId>\n  <name>Java Chassis::Metrics::Integration</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>metrics-prometheus</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "metrics/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <packaging>pom</packaging>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n\n  <artifactId>metrics</artifactId>\n  <name>Java Chassis::Metrics</name>\n\n  <modules>\n    <module>metrics-core</module>\n    <module>metrics-integration</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "parents/default/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-dependencies</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../../dependencies/default</relativePath>\n  </parent>\n\n  <artifactId>java-chassis-parent</artifactId>\n  <packaging>pom</packaging>\n\n  <name>Java Chassis::Parent::Default</name>\n  <description>Java Chassis Parent</description>\n  <url>https://github.com/apache/servicecomb-java-chassis</url>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.awaitility</groupId>\n      <artifactId>awaitility</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.hamcrest</groupId>\n      <artifactId>hamcrest-all</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.hamcrest</groupId>\n      <artifactId>hamcrest-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>net.bytebuddy</groupId>\n      <artifactId>byte-buddy</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>com.github.seanyinx</groupId>\n      <artifactId>unit-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.platform</groupId>\n      <artifactId>junit-platform-launcher</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.vintage</groupId>\n      <artifactId>junit-vintage-engine</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.assertj</groupId>\n      <artifactId>assertj-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-starter-test</artifactId>\n      <exclusions>\n        <exclusion>\n          <groupId>org.springframework.boot</groupId>\n          <artifactId>spring-boot-starter-logging</artifactId>\n        </exclusion>\n      </exclusions>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-api</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "parents/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>java-chassis-parents</artifactId>\n  <name>Java Chassis::Parents</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>default</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.apache</groupId>\n    <artifactId>apache</artifactId>\n    <version>35</version>\n  </parent>\n\n\n  <groupId>org.apache.servicecomb</groupId>\n  <artifactId>java-chassis</artifactId>\n  <version>3.4.0-SNAPSHOT</version>\n  <packaging>pom</packaging>\n\n  <name>ServiceComb Java Chassis</name>\n  <description>Software Development Kit (SDK) for rapid development of microservices</description>\n  <url>https://github.com/apache/servicecomb-java-chassis</url>\n\n  <properties>\n    <maven.compiler.source>17</maven.compiler.source>\n    <maven.compiler.target>17</maven.compiler.target>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    <java.version>17</java.version>\n    <skip-remote-resource>true</skip-remote-resource>\n    <!-- plugin version start -->\n    <!-- sort by alpha -->\n    <checkstyle-maven-plugin.version>3.6.0</checkstyle-maven-plugin.version>\n    <coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>\n    <dependency-check-maven-plugin.version>12.2.0</dependency-check-maven-plugin.version>\n    <docker-maven-plugin.version>0.48.0</docker-maven-plugin.version>\n    <exec-maven-plugin.version>3.6.3</exec-maven-plugin.version>\n    <gpg-maven-plugin.version>3.2.8</gpg-maven-plugin.version>\n    <jacoco-maven-plugin.version>0.8.14</jacoco-maven-plugin.version>\n    <javadoc-maven-plugin.version>3.12.0</javadoc-maven-plugin.version>\n    <jxr-maven-plugin.version>2.5</jxr-maven-plugin.version>\n    <maven-compiler-plugin.version>3.15.0</maven-compiler-plugin.version>\n    <maven-failsafe-plugin.version>3.5.4</maven-failsafe-plugin.version>\n    <maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>\n    <maven-project-info-reports-plugin.version>3.9.0</maven-project-info-reports-plugin.version>\n    <maven-remote-resources-plugin.version>3.2.0</maven-remote-resources-plugin.version>\n    <os-maven-plugin.version>1.7.1</os-maven-plugin.version>\n    <protobuf-maven-plugin.version>0.6.1</protobuf-maven-plugin.version>\n    <protoc3-maven-plugin.version>3.19.2</protoc3-maven-plugin.version>\n    <protoc-gen-grpc-java-plugin.version>1.47.0</protoc-gen-grpc-java-plugin.version>\n    <puppycrawl-checkstyle.version>12.3.1</puppycrawl-checkstyle.version>\n    <release-maven-plugin.version>3.1.1</release-maven-plugin.version>\n    <site-maven-plugin.version>3.21.0</site-maven-plugin.version>\n    <source-maven-plugin.version>3.3.0</source-maven-plugin.version>\n    <spotbug-maven-plugin.version>4.9.8.2</spotbug-maven-plugin.version>\n    <spring-boot.version>3.5.4</spring-boot.version>\n    <surefire-maven-plugin.version>3.5.4</surefire-maven-plugin.version>\n    <!-- plugin version end -->\n  </properties>\n\n  <licenses>\n    <license>\n      <name>Apache License, Version 2.0</name>\n      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n      <distribution>repo</distribution>\n    </license>\n  </licenses>\n\n  <mailingLists>\n    <mailingList>\n      <name>Development List</name>\n      <subscribe>dev-subscribe@servicecomb.apache.org</subscribe>\n      <unsubscribe>dev-unsubscribe@servicecomb.apache.org</unsubscribe>\n      <post>dev@servicecomb.apache.org</post>\n    </mailingList>\n    <mailingList>\n      <name>Commits List</name>\n      <subscribe>commits-subscribe@servicecomb.apache.org</subscribe>\n      <unsubscribe>commits-unsubscribe@servicecomb.apache.org</unsubscribe>\n      <post>commits@servicecomb.apache.org</post>\n    </mailingList>\n  </mailingLists>\n\n  <developers>\n    <developer>\n      <name>The ServiceComb Developer Team</name>\n      <email>dev@servicecomb.apache.org</email>\n    </developer>\n  </developers>\n\n  <issueManagement>\n    <system>jira</system>\n    <url>https://issues.apache.org/jira/browse/SCB</url>\n  </issueManagement>\n\n  <organization>\n    <name>The Apache Software Foundation</name>\n    <url>http://www.apache.org/</url>\n  </organization>\n\n  <inceptionYear>2017</inceptionYear>\n\n  <scm>\n    <url>https://github.com/apache/servicecomb-java-chassis</url>\n    <connection>scm:git:https://github.com/apache/servicecomb-java-chassis.git</connection>\n    <developerConnection>scm:git:https://github.com/apache/servicecomb-java-chassis.git</developerConnection>\n    <tag>v${project.version}</tag>\n  </scm>\n\n  <distributionManagement>\n    <repository>\n      <id>apache.releases.https</id>\n      <name>Apache Release Distribution Repository</name>\n      <url>https://repository.apache.org/service/local/staging/deploy/maven2</url>\n    </repository>\n    <snapshotRepository>\n      <id>apache.snapshots.https</id>\n      <name>Apache Development Snapshot Repository</name>\n      <url>https://repository.apache.org/content/repositories/snapshots</url>\n    </snapshotRepository>\n  </distributionManagement>\n\n  <modules>\n    <module>dependencies</module>\n    <module>parents</module>\n    <module>common</module>\n    <module>foundations</module>\n    <module>handlers</module>\n    <module>providers</module>\n    <module>transports</module>\n    <module>swagger</module>\n    <module>core</module>\n    <module>service-registry</module>\n    <module>tracing</module>\n    <module>edge</module>\n    <module>metrics</module>\n    <module>dynamic-config</module>\n    <module>spring-boot</module>\n    <module>solutions</module>\n    <module>clients</module>\n    <module>governance</module>\n    <module>huawei-cloud</module>\n  </modules>\n\n  <build>\n    <extensions>\n      <extension>\n        <groupId>kr.motd.maven</groupId>\n        <artifactId>os-maven-plugin</artifactId>\n        <version>${os-maven-plugin.version}</version>\n      </extension>\n    </extensions>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-checkstyle-plugin</artifactId>\n        <configuration>\n          <configLocation>ci/checkstyle/checkstyle.xml</configLocation>\n          <suppressionsLocation>ci/checkstyle/suppressions.xml</suppressionsLocation>\n          <includeTestSourceDirectory>true</includeTestSourceDirectory>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-remote-resources-plugin</artifactId>\n        <executions>\n          <execution>\n            <id>process-resource-bundles</id>\n            <goals>\n              <goal>process</goal>\n            </goals>\n            <configuration>\n              <skip>${skip-remote-resource}</skip>\n              <resourceBundles>\n                <resourceBundle>org.apache:apache-jar-resource-bundle:1.4</resourceBundle>\n                <resourceBundle>org.apache:apache-incubator-disclaimer-resource-bundle:1.1</resourceBundle>\n              </resourceBundles>\n              <properties>\n                <projectName>Apache ServiceComb</projectName>\n              </properties>\n            </configuration>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.codehaus.mojo</groupId>\n        <artifactId>license-maven-plugin</artifactId>\n        <version>2.7.1</version>\n        <executions>\n          <execution>\n            <id>default-cli</id>\n            <configuration>\n              <!-- Accept the pom module -->\n              <acceptPomPackaging>true</acceptPomPackaging>\n              <!-- Using the template which is grouped by License file -->\n              <fileTemplate>/org/codehaus/mojo/license/third-party-file-groupByMultiLicense.ftl</fileTemplate>\n              <licenseMerges>\n                <licenseMerge>The Apache Software License, Version 2.0|The Apache License, Version 2.0</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache License, Version 2.0</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache Public License 2.0</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache 2</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache 2.0</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache-2.0</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache License 2.0</licenseMerge>\n                <licenseMerge>The Apache Software License, Version 2.0|Apache License, version 2.0</licenseMerge>\n                <licenseMerge>3-Clause BSD License|BSD 3-clause</licenseMerge>\n                <licenseMerge>3-Clause BSD License|BSD 3-Clause</licenseMerge>\n                <licenseMerge>Eclipse Public License v1.0|Eclipse Public License 1.0</licenseMerge>\n                <licenseMerge>Eclipse Public License v1.0|Eclipse Public License - v 1.0</licenseMerge>\n                <licenseMerge>The MIT License|MIT License</licenseMerge>\n              </licenseMerges>\n              <excludedGroups>org.apache.servicecomb*</excludedGroups>\n            </configuration>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.rat</groupId>\n        <artifactId>apache-rat-plugin</artifactId>\n        <configuration>\n          <excludes>\n            <exclude>DISCLAIMER</exclude>\n            <exclude>.travis.yml</exclude>\n            <exclude>**/*.md</exclude>\n            <excldue>**/*.MD</excldue>\n            <excldue>**/*.iml</excldue>\n            <excldue>.github/**</excldue>\n            <!-- Skip the code style configuration file -->\n            <exclude>**/etc/eclipse-java-google-style.xml</exclude>\n            <exclude>**/etc/intellij-java-google-style.xml</exclude>\n            <!-- Skip the ssl configuration files -->\n            <exclude>**/resources/ssl/**</exclude>\n            <!-- SKip the licenses files -->\n            <exclude>**/src/release/licenses/**</exclude>\n            <!-- Skip the demo log files -->\n            <exclude>**/logs/**.log</exclude>\n            <exclude>**/**.log</exclude>\n            <!-- Skip the target files -->\n            <exclude>**/target/**</exclude>\n            <!-- Skip web resource files -->\n            <exclude>**/resources/webroot/images/*.png</exclude>\n            <exclude>**/resources/webroot/images/*.jpg</exclude>\n            <!-- Skip the source files which are forked from vertx -->\n            <exclude>**/org/apache/servicecomb/foundation/common/utils/MimeTypesUtils.java</exclude>\n            <exclude>**/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java</exclude>\n            <!--Skip protobuf generated file-->\n            <exclude>**/java/org/apache/servicecomb/foundation/protobuf/internal/model/ProtobufRoot.java</exclude>\n            <!-- Skip the sources files forked from protobuffers -->\n            <exclude>**/resources/google/protobuf/**.proto</exclude>\n          </excludes>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.codehaus.mojo</groupId>\n        <artifactId>exec-maven-plugin</artifactId>\n        <version>${exec-maven-plugin.version}</version>\n        <executions>\n          <execution>\n            <goals>\n              <goal>java</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <version>${surefire-maven-plugin.version}</version>\n        <configuration>\n          <argLine>\n            -Djdk.attach.allowAttachSelf\n            --add-opens java.base/java.io=ALL-UNNAMED\n            --add-opens java.base/java.lang=ALL-UNNAMED\n            --add-opens java.base/java.lang.reflect=ALL-UNNAMED\n            --add-opens java.base/java.net=ALL-UNNAMED\n            --add-opens java.base/java.nio=ALL-UNNAMED\n            --add-opens java.base/java.nio.channels.spi=ALL-UNNAMED\n            --add-opens java.base/java.nio.file=ALL-UNNAMED\n            --add-opens java.base/java.util=ALL-UNNAMED\n            --add-opens java.base/java.util.concurrent=ALL-UNNAMED\n            --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED\n            --add-opens java.base/java.util.jar=ALL-UNNAMED\n            --add-opens java.base/java.util.stream=ALL-UNNAMED\n            --add-opens java.base/java.time=ALL-UNNAMED\n            --add-opens java.base/jdk.internal.loader=ALL-UNNAMED\n            --add-opens java.base/sun.net.dns=ALL-UNNAMED\n            --add-opens java.base/sun.nio.ch=ALL-UNNAMED\n            --add-opens java.base/sun.security.jca=ALL-UNNAMED\n            --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED\n            --add-reads java.base=java.desktop\n          </argLine>\n          <skip>${maven.test.skip}</skip>\n          <testFailureIgnore>${maven.test.failure.ignore}</testFailureIgnore>\n          <excludes>\n            <exclude>${excludesFile}</exclude>\n          </excludes>\n          <forkedProcessExitTimeoutInSeconds>5</forkedProcessExitTimeoutInSeconds>\n          <forkCount>2</forkCount>\n          <reuseForks>true</reuseForks>\n          <runOrder>alphabetical</runOrder>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>${maven-jar-plugin.version}</version>\n        <configuration>\n          <archive>\n            <manifest>\n              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>\n              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>\n            </manifest>\n          </archive>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>com.github.spotbugs</groupId>\n        <artifactId>spotbugs-maven-plugin</artifactId>\n        <configuration>\n          <xmlOutput>true</xmlOutput>\n          <failOnError>true</failOnError>\n          <threshold>Medium</threshold>\n          <excludeFilterFile>${session.executionRootDirectory}/ci/spotbugs/exclude.xml</excludeFilterFile>\n        </configuration>\n        <executions>\n          <execution>\n            <goals>\n              <goal>check</goal>\n            </goals>\n          </execution>\n        </executions>\n      </plugin>\n    </plugins>\n    <pluginManagement>\n      <plugins>\n        <plugin>\n          <groupId>org.eluder.coveralls</groupId>\n          <artifactId>coveralls-maven-plugin</artifactId>\n          <version>${coveralls-maven-plugin.version}</version>\n          <configuration>\n            <jacocoReports>\n              <jacocoReport>${project.basedir}/coverage-reports/target/site/jacoco-aggregate/jacoco.xml</jacocoReport>\n            </jacocoReports>\n          </configuration>\n        </plugin>\n        <plugin>\n          <artifactId>maven-remote-resources-plugin</artifactId>\n          <version>${maven-remote-resources-plugin.version}</version>\n        </plugin>\n        <plugin>\n          <groupId>io.fabric8</groupId>\n          <artifactId>docker-maven-plugin</artifactId>\n          <version>${docker-maven-plugin.version}</version>\n        </plugin>\n        <plugin>\n          <groupId>org.jacoco</groupId>\n          <artifactId>jacoco-maven-plugin</artifactId>\n          <version>${jacoco-maven-plugin.version}</version>\n          <configuration>\n            <excludes>\n              <exclude>*$Impl_*</exclude>\n            </excludes>\n          </configuration>\n          <executions>\n            <execution>\n              <id>default-prepare-agent</id>\n              <goals>\n                <goal>prepare-agent</goal>\n              </goals>\n              <configuration>\n                <destFile>${project.build.directory}/jacoco.exec</destFile>\n              </configuration>\n            </execution>\n            <execution>\n              <id>default-prepare-agent-integration</id>\n              <phase>pre-integration-test</phase>\n              <goals>\n                <goal>prepare-agent-integration</goal>\n              </goals>\n              <configuration>\n                <destFile>${project.build.directory}/jacoco-it.exec</destFile>\n                <propertyName>jacoco.failsafe.argLine</propertyName>\n              </configuration>\n            </execution>\n            <execution>\n              <id>default-report</id>\n              <goals>\n                <goal>report</goal>\n              </goals>\n            </execution>\n            <execution>\n              <id>default-report-integration</id>\n              <goals>\n                <goal>report-integration</goal>\n              </goals>\n            </execution>\n          </executions>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-compiler-plugin</artifactId>\n          <version>${maven-compiler-plugin.version}</version>\n          <configuration>\n            <compilerArgument>-parameters</compilerArgument>\n            <showDeprecation>true</showDeprecation>\n            <showWarnings>true</showWarnings>\n            <!--<failOnWarning>true</failOnWarning>-->\n            <compilerArgs>\n              <arg>-Xlint:all</arg>\n            </compilerArgs>\n          </configuration>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-project-info-reports-plugin</artifactId>\n          <version>${maven-project-info-reports-plugin.version}</version>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-site-plugin</artifactId>\n          <version>${site-maven-plugin.version}</version>\n        </plugin>\n        <plugin>\n          <groupId>org.apache.maven.plugins</groupId>\n          <artifactId>maven-checkstyle-plugin</artifactId>\n          <version>${checkstyle-maven-plugin.version}</version>\n          <inherited>true</inherited>\n          <dependencies>\n            <dependency>\n              <groupId>com.puppycrawl.tools</groupId>\n              <artifactId>checkstyle</artifactId>\n              <version>${puppycrawl-checkstyle.version}</version>\n            </dependency>\n          </dependencies>\n        </plugin>\n        <plugin>\n          <groupId>org.springframework.boot</groupId>\n          <artifactId>spring-boot-maven-plugin</artifactId>\n          <version>${spring-boot.version}</version>\n          <executions>\n            <execution>\n              <goals>\n                <goal>repackage</goal>\n              </goals>\n              <configuration>\n                <mainClass>${main.class}</mainClass>\n              </configuration>\n            </execution>\n          </executions>\n        </plugin>\n        <plugin>\n          <groupId>com.github.spotbugs</groupId>\n          <artifactId>spotbugs-maven-plugin</artifactId>\n          <version>${spotbug-maven-plugin.version}</version>\n        </plugin>\n      </plugins>\n    </pluginManagement>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>release</id>\n      <modules>\n        <module>distribution</module>\n      </modules>\n      <properties>\n        <skip-remote-resource>false</skip-remote-resource>\n      </properties>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-deploy-plugin</artifactId>\n          </plugin>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-gpg-plugin</artifactId>\n            <version>${gpg-maven-plugin.version}</version>\n            <executions>\n              <execution>\n                <id>sign-artifacts</id>\n                <phase>verify</phase>\n                <goals>\n                  <goal>sign</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-source-plugin</artifactId>\n            <version>${source-maven-plugin.version}</version>\n            <executions>\n              <execution>\n                <id>attach-sources</id>\n                <goals>\n                  <goal>jar-no-fork</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-javadoc-plugin</artifactId>\n            <version>${javadoc-maven-plugin.version}</version>\n            <executions>\n              <execution>\n                <id>attach-javadocs</id>\n                <goals>\n                  <goal>jar</goal>\n                </goals>\n              </execution>\n            </executions>\n            <configuration>\n              <source>17</source>\n              <tags>\n                <tag>\n                  <!-- to avoid protostuff javadoc problem. -->\n                  <name>created</name>\n                  <placement>t</placement>\n                  <head>Date created:</head>\n                </tag>\n              </tags>\n            </configuration>\n          </plugin>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-release-plugin</artifactId>\n            <version>${release-maven-plugin.version}</version>\n            <configuration>\n              <autoVersionSubmodules>true</autoVersionSubmodules>\n              <useReleaseProfile>false</useReleaseProfile>\n              <releaseProfiles>release</releaseProfiles>\n              <goals>deploy</goals>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n    <profile>\n      <id>it</id>\n      <modules>\n        <module>demo</module>\n      </modules>\n    </profile>\n    <profile>\n      <id>coverage</id>\n      <modules>\n        <module>coverage-reports</module>\n      </modules>\n    </profile>\n    <profile>\n      <id>docker-machine</id>\n      <build>\n        <pluginManagement>\n          <plugins>\n            <plugin>\n              <groupId>io.fabric8</groupId>\n              <artifactId>docker-maven-plugin</artifactId>\n              <configuration>\n                <machine>\n                  <name>default</name>\n                  <autoCreate>true</autoCreate>\n                </machine>\n              </configuration>\n            </plugin>\n          </plugins>\n        </pluginManagement>\n      </build>\n    </profile>\n    <profile>\n      <id>jacoco</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.jacoco</groupId>\n            <artifactId>jacoco-maven-plugin</artifactId>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n    <profile>\n      <id>owasp-dependency-check</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.owasp</groupId>\n            <artifactId>dependency-check-maven</artifactId>\n            <version>${dependency-check-maven-plugin.version}</version>\n            <configuration>\n              <suppressionFiles>\n                <suppressionFile>src/owasp-dependency-check-suppressions.xml</suppressionFile>\n              </suppressionFiles>\n              <failBuildOnCVSS>7</failBuildOnCVSS>\n              <msbuildAnalyzerEnabled>false</msbuildAnalyzerEnabled>\n              <nodeAnalyzerEnabled>false</nodeAnalyzerEnabled>\n              <yarnAuditAnalyzerEnabled>false</yarnAuditAnalyzerEnabled>\n              <pyDistributionAnalyzerEnabled>false</pyDistributionAnalyzerEnabled>\n              <pyPackageAnalyzerEnabled>false</pyPackageAnalyzerEnabled>\n              <pipAnalyzerEnabled>false</pipAnalyzerEnabled>\n              <pipfileAnalyzerEnabled>false</pipfileAnalyzerEnabled>\n              <retireJsAnalyzerEnabled>false</retireJsAnalyzerEnabled>\n              <msbuildAnalyzerEnabled>false</msbuildAnalyzerEnabled>\n              <mixAuditAnalyzerEnabled>false</mixAuditAnalyzerEnabled>\n              <nugetconfAnalyzerEnabled>false</nugetconfAnalyzerEnabled>\n              <assemblyAnalyzerEnabled>false</assemblyAnalyzerEnabled>\n            </configuration>\n            <executions>\n              <execution>\n                <goals>\n                  <goal>aggregate</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n      <reporting>\n        <plugins>\n          <plugin>\n            <groupId>org.owasp</groupId>\n            <artifactId>dependency-check-maven</artifactId>\n            <version>${dependency-check-maven-plugin.version}</version>\n            <reportSets>\n              <reportSet>\n                <reports>\n                  <report>aggregate</report>\n                </reports>\n              </reportSet>\n            </reportSets>\n          </plugin>\n        </plugins>\n      </reporting>\n    </profile>\n  </profiles>\n\n</project>\n"
  },
  {
    "path": "providers/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>providers</artifactId>\n  <name>Java Chassis::Providers</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>provider-jaxrs</module>\n    <module>provider-pojo</module>\n    <module>provider-rest-common</module>\n    <module>provider-springmvc</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "providers/provider-jaxrs/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>providers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>provider-jaxrs</artifactId>\n  <name>Java Chassis::Providers::JAXRS</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-rest-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-jaxrs</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "providers/provider-pojo/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>providers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>provider-pojo</artifactId>\n  <name>Java Chassis::Providers::POJO</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/DefaultMethodMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport java.lang.invoke.MethodHandle;\nimport java.lang.invoke.MethodHandles;\nimport java.lang.invoke.MethodHandles.Lookup;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Method;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.springframework.util.ReflectionUtils;\n\npublic class DefaultMethodMeta {\n  private final Map<Method, MethodHandle> defaultMethodHandles = new ConcurrentHashMapEx<>();\n\n  // java11\n  private final Method privateLookupIn = ReflectionUtils.findMethod(MethodHandles.class,\n      \"privateLookupIn\", Class.class, Lookup.class);\n\n  // only for java8\n  private Constructor<Lookup> lookupConstructor;\n\n  public MethodHandle getOrCreateMethodHandle(Object proxy, Method method) {\n    return defaultMethodHandles.computeIfAbsent(method, key -> createMethodHandle(proxy, method));\n  }\n\n  protected MethodHandle createMethodHandle(Object proxy, Method method) {\n    try {\n      if (privateLookupIn != null) {\n        return createForJava11(proxy, method);\n      }\n\n      return createForJava8(proxy, method);\n    } catch (Exception e) {\n      throw AsyncUtils.rethrow(e);\n    }\n  }\n\n  protected MethodHandle createForJava11(Object proxy, Method method) throws Exception {\n    Lookup lookup = MethodHandles.lookup();\n    Lookup privateLookup = (Lookup) privateLookupIn.invoke(null, method.getDeclaringClass(), lookup);\n    return privateLookup\n        .unreflectSpecial(method, method.getDeclaringClass())\n        .bindTo(proxy);\n  }\n\n  protected MethodHandle createForJava8(Object proxy, Method method) throws Exception {\n    if (lookupConstructor == null) {\n      lookupConstructor = ReflectionUtils.accessibleConstructor(Lookup.class, Class.class);\n    }\n    return lookupConstructor.newInstance(method.getDeclaringClass())\n        .unreflectSpecial(method, method.getDeclaringClass())\n        .bindTo(proxy);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/FilterInvocationCaller.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport static org.apache.servicecomb.core.provider.consumer.InvokerUtils.isAsyncMethod;\n\nimport java.lang.reflect.Method;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\n\npublic class FilterInvocationCaller implements InvocationCaller {\n  // if not a sync method, should never throw exception directly\n  @Override\n  public Object call(Method method, PojoConsumerMetaRefresher metaRefresher, PojoInvocationCreator invocationCreator,\n      Object[] args) {\n    if (isAsyncMethod(method)) {\n      CompletableFuture<PojoInvocation> invocationFuture = invocationCreator.createAsync(method, metaRefresher, args);\n      return invocationFuture.thenCompose(this::doCall);\n    }\n    PojoInvocation invocation = invocationCreator.create(method, metaRefresher, args);\n    CompletableFuture<Object> future = CompletableFuture.completedFuture(invocation)\n        .thenCompose(this::doCall);\n    return InvokerUtils.toSync(future, invocation.getWaitTime());\n  }\n\n  protected CompletableFuture<Object> doCall(PojoInvocation invocation) {\n    return InvokerUtils.invoke(invocation)\n        .thenApply(response -> {\n          if (response.isSucceed()) {\n            return invocation.convertResponse(response);\n          }\n          throw ExceptionFactory.convertConsumerException(response.getResult());\n        });\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/InstanceFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\npublic interface InstanceFactory {\n  String getImplName();\n\n  Object create(String implValue);\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/InvocationCaller.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport java.lang.reflect.Method;\n\npublic interface InvocationCaller {\n  Object call(Method method, PojoConsumerMetaRefresher metaRefresher, PojoInvocationCreator invocationCreator,\n      Object[] args);\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/Invoker.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\n\nimport org.apache.servicecomb.core.SCBEngine;\n\npublic class Invoker implements InvocationHandler {\n  public static final Method METHOD_HASH_CODE;\n\n  public static final Method METHOD_EQUALS;\n\n  public static final Method METHOD_TO_STRING;\n\n  static {\n    try {\n      METHOD_HASH_CODE = Object.class.getDeclaredMethod(\"hashCode\");\n      METHOD_EQUALS = Object.class.getDeclaredMethod(\"equals\", Object.class);\n      METHOD_TO_STRING = Object.class.getDeclaredMethod(\"toString\");\n    } catch (NoSuchMethodException e) {\n      throw new Error(e);\n    }\n  }\n\n  protected final PojoConsumerMetaRefresher metaRefresher;\n\n  protected final PojoInvocationCreator invocationCreator;\n\n  protected final DefaultMethodMeta defaultMethodMeta = new DefaultMethodMeta();\n\n  protected InvocationCaller invocationCaller;\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T createProxy(String microserviceName, String schemaId, Class<?> consumerIntf) {\n    Invoker invoker = new Invoker(microserviceName, schemaId, consumerIntf);\n    return (T) Proxy.newProxyInstance(consumerIntf.getClassLoader(), new Class<?>[] {consumerIntf}, invoker);\n  }\n\n  public Invoker(String microserviceName, String schemaId, Class<?> consumerIntf) {\n    this.metaRefresher = createInvokerMeta(microserviceName, schemaId, consumerIntf);\n    this.invocationCreator = createInvocationCreator();\n  }\n\n  protected PojoConsumerMetaRefresher createInvokerMeta(String microserviceName, String schemaId,\n      Class<?> consumerIntf) {\n    return new PojoConsumerMetaRefresher(microserviceName, schemaId, consumerIntf);\n  }\n\n  public PojoInvocationCreator createInvocationCreator() {\n    return new PojoInvocationCreator();\n  }\n\n  protected InvocationCaller createInvocationCaller() {\n    return new FilterInvocationCaller();\n  }\n\n  @Override\n  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {\n    if (method.isDefault()) {\n      return defaultMethodMeta.getOrCreateMethodHandle(proxy, method)\n          .invokeWithArguments(args);\n    }\n    if (METHOD_HASH_CODE.equals(method)) {\n      return objectHashCode(proxy);\n    }\n    if (METHOD_EQUALS.equals(method)) {\n      return objectEquals(proxy, args[0]);\n    }\n    if (METHOD_TO_STRING.equals(method)) {\n      return objectToString(proxy);\n    }\n\n    SCBEngine.getInstance().ensureStatusUp();\n    prepareInvocationCaller();\n    return invocationCaller.call(method, metaRefresher, invocationCreator, args);\n  }\n\n  protected void prepareInvocationCaller() {\n    if (invocationCaller != null) {\n      return;\n    }\n\n    this.invocationCaller = createInvocationCaller();\n  }\n\n  private String objectClassName(Object obj) {\n    return obj.getClass().getName();\n  }\n\n  private int objectHashCode(Object obj) {\n    return System.identityHashCode(obj);\n  }\n\n  private boolean objectEquals(Object obj, Object other) {\n    return obj == other;\n  }\n\n  private String objectToString(Object obj) {\n    return objectClassName(obj) + '@' + Integer.toHexString(objectHashCode(obj));\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\npublic final class PojoConst {\n  private PojoConst() {\n  }\n\n  public static final String FIELD_SCHEMA_ID = \"schemaId\";\n\n  public static final String SCHEMA_ID = \"schema-id\";\n\n  public static final String FIELD_SCHEMA_INTERFACE = \"schemaInterfaceName\";\n\n  public static final String SCHEMA_INTERFACE = \"schema-interface\";\n\n  public static final String IMPL = \"implementation\";\n\n  public static final String FIELD_MICROSERVICE_NAME = \"microserviceName\";\n\n  public static final String MICROSERVICE_NAME = \"microservice-name\";\n\n  public static final String FIELD_INTERFACE = \"consumerIntf\";\n\n  public static final String INTERFACE = \"interface\";\n\n  public static final String POJO = \"pojo\";\n\n  public static final String SPRING = \"spring\";\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoConsumerMetaRefresher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;\nimport org.apache.servicecomb.provider.pojo.definition.PojoConsumerMeta;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class PojoConsumerMetaRefresher {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PojoConsumerMetaRefresher.class);\n\n  protected final String microserviceName;\n\n  // can be null, should find SchemaMeta by consumerIntf in this time\n  protected final String schemaId;\n\n  protected final Class<?> consumerIntf;\n\n  protected SCBEngine scbEngine;\n\n  // not always equals codec meta\n  // for highway, codec meta is relate to target instance\n  //  to avoid limit producer to only allow append parameter\n  protected PojoConsumerMeta consumerMeta;\n\n  public PojoConsumerMetaRefresher(String microserviceName, String schemaId, Class<?> consumerIntf) {\n    this.microserviceName = microserviceName;\n    this.schemaId = schemaId;\n    this.consumerIntf = consumerIntf;\n  }\n\n  public PojoConsumerMeta getLatestMeta() {\n    ensureStatusUp();\n    ensureMetaAvailable();\n    return consumerMeta;\n  }\n\n  public CompletableFuture<PojoConsumerMeta> getLatestMetaAsync() {\n    ensureStatusUp();\n    return ensureMetaAvailableAsync().thenCompose(v -> CompletableFuture.completedFuture(consumerMeta));\n  }\n\n  private void ensureStatusUp() {\n    if (scbEngine == null) {\n      if (SCBEngine.getInstance() == null) {\n        String message =\n            \"The request is rejected. Cannot process the request due to SCBEngine not ready.\";\n        LOGGER.warn(message);\n        throw new InvocationException(Status.SERVICE_UNAVAILABLE, new CommonExceptionData(message));\n      }\n\n      this.scbEngine = SCBEngine.getInstance();\n    }\n\n    scbEngine.ensureStatusUp();\n  }\n\n  private void ensureMetaAvailable() {\n    if (isNeedRefresh()) {\n      synchronized (this) {\n        if (isNeedRefresh()) {\n          this.consumerMeta = refreshMeta();\n        }\n      }\n    }\n  }\n\n  private CompletableFuture<Void> ensureMetaAvailableAsync() {\n    if (isNeedRefresh()) {\n      return refreshMetaAsync();\n    }\n    return CompletableFuture.completedFuture(null);\n  }\n\n  private boolean isNeedRefresh() {\n    return consumerMeta == null;\n  }\n\n  protected PojoConsumerMeta refreshMeta() {\n    MicroserviceReferenceConfig microserviceReferenceConfig = scbEngine\n        .getOrCreateReferenceConfig(microserviceName);\n    if (microserviceReferenceConfig == null) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          new CommonExceptionData(String.format(\"Failed to invoke service %s. Maybe service\"\n              + \" not registered or no active instance.\", microserviceName)));\n    }\n    MicroserviceMeta microserviceMeta = microserviceReferenceConfig.getMicroserviceMeta();\n\n    SchemaMeta schemaMeta = findSchemaMeta(microserviceMeta);\n    if (schemaMeta == null) {\n      throw new IllegalStateException(\n          String.format(\n              \"Schema not exist, microserviceName=%s, schemaId=%s, consumer interface=%s; \"\n                  + \"new producer not running or not deployed.\",\n              microserviceName,\n              schemaId,\n              consumerIntf.getName()));\n    }\n\n    SwaggerConsumer swaggerConsumer = scbEngine.getSwaggerEnvironment()\n        .createConsumer(consumerIntf, schemaMeta.getSwagger());\n    return new PojoConsumerMeta(microserviceReferenceConfig, swaggerConsumer, schemaMeta);\n  }\n\n  protected CompletableFuture<Void> refreshMetaAsync() {\n    CompletableFuture<MicroserviceReferenceConfig> microserviceReferenceConfigFuture = scbEngine\n        .getOrCreateReferenceConfigAsync(microserviceName);\n    return microserviceReferenceConfigFuture.thenCompose((microserviceReferenceConfig) -> {\n      if (microserviceReferenceConfig == null) {\n        return CompletableFuture.failedFuture(new InvocationException(Status.INTERNAL_SERVER_ERROR,\n            new CommonExceptionData(String.format(\"Failed to invoke service %s. Maybe service\"\n                + \" not registered or no active instance.\", microserviceName))));\n      }\n      synchronized (this) {\n        if (isNeedRefresh()) {\n          MicroserviceMeta microserviceMeta = microserviceReferenceConfig.getMicroserviceMeta();\n\n          SchemaMeta schemaMeta = findSchemaMeta(microserviceMeta);\n          if (schemaMeta == null) {\n            return CompletableFuture.failedFuture(new IllegalStateException(\n                String.format(\n                    \"Schema not exist, microserviceName=%s, schemaId=%s, consumer interface=%s; \"\n                        + \"new producer not running or not deployed.\",\n                    microserviceName,\n                    schemaId,\n                    consumerIntf.getName())));\n          }\n\n          SwaggerConsumer swaggerConsumer = scbEngine.getSwaggerEnvironment()\n              .createConsumer(consumerIntf, schemaMeta.getSwagger());\n          consumerMeta = new PojoConsumerMeta(microserviceReferenceConfig, swaggerConsumer, schemaMeta);\n        }\n        return CompletableFuture.completedFuture(null);\n      }\n    });\n  }\n\n  private SchemaMeta findSchemaMeta(MicroserviceMeta microserviceMeta) {\n    // if present schemaId, just use it\n    if (StringUtils.isNotEmpty(schemaId)) {\n      return microserviceMeta.findSchemaMeta(schemaId);\n    }\n\n    // try interface name second\n    return microserviceMeta.findSchemaMeta(consumerIntf.getName());\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoInvocation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.provider.pojo.definition.PojoConsumerOperationMeta;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class PojoInvocation extends Invocation {\n  protected final PojoConsumerOperationMeta consumerOperationMeta;\n\n  public PojoInvocation(PojoConsumerOperationMeta consumerOperationMeta) {\n    super(consumerOperationMeta.createReferenceConfig(),\n        consumerOperationMeta.getOperationMeta(),\n        consumerOperationMeta.getInvocationRuntimeType(),\n        null);\n    this.consumerOperationMeta = consumerOperationMeta;\n    InvocationFactory.setSrcMicroservice(this);\n  }\n\n  public ReferenceConfig getReferenceConfig() {\n    return referenceConfig;\n  }\n\n  public Object convertResponse(Response response) {\n    return consumerOperationMeta.getSwaggerConsumerOperation().getResponseMapper().mapResponse(response);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport java.lang.reflect.Method;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.provider.pojo.definition.PojoConsumerMeta;\nimport org.apache.servicecomb.provider.pojo.definition.PojoConsumerOperationMeta;\n\npublic class PojoInvocationCreator {\n  public PojoInvocation create(Method method, PojoConsumerMetaRefresher metaRefresher, Object[] args) {\n    long startCreateInvocation = System.nanoTime();\n    PojoConsumerMeta pojoConsumerMeta = metaRefresher.getLatestMeta();\n    PojoConsumerOperationMeta consumerOperationMeta = pojoConsumerMeta.ensureFindOperationMeta(method);\n\n    PojoInvocation invocation = new PojoInvocation(consumerOperationMeta);\n    invocation.setSuccessResponseType(consumerOperationMeta.getResponsesType());\n    invocation.setInvocationArguments(consumerOperationMeta.getSwaggerConsumerOperation().toInvocationArguments(args));\n    invocation.setSync(consumerOperationMeta.isSync());\n    invocation.getInvocationStageTrace().startCreateInvocation(startCreateInvocation);\n    invocation.getInvocationStageTrace().finishCreateInvocation();\n    return invocation;\n  }\n\n  public CompletableFuture<PojoInvocation> createAsync(Method method, PojoConsumerMetaRefresher metaRefresher,\n      Object[] args) {\n    CompletableFuture<PojoConsumerMeta> pojoConsumerMetaFuture = metaRefresher.getLatestMetaAsync();\n    return pojoConsumerMetaFuture.thenCompose(pojoConsumerMeta -> {\n      PojoConsumerOperationMeta consumerOperationMeta = pojoConsumerMeta.ensureFindOperationMeta(method);\n\n      PojoInvocation invocation = new PojoInvocation(consumerOperationMeta);\n      invocation.setSuccessResponseType(consumerOperationMeta.getResponsesType());\n      invocation.setInvocationArguments(\n          consumerOperationMeta.getSwaggerConsumerOperation().toInvocationArguments(args));\n      invocation.setSync(consumerOperationMeta.isSync());\n\n      return CompletableFuture.completedFuture(invocation);\n    });\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/PojoProducerProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.provider.producer.AbstractProducerProvider;\nimport org.apache.servicecomb.core.provider.producer.ProducerMeta;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.provider.pojo.instance.PojoInstanceFactory;\nimport org.apache.servicecomb.provider.pojo.instance.SpringInstanceFactory;\nimport org.apache.servicecomb.provider.pojo.schema.PojoProducerMeta;\nimport org.apache.servicecomb.provider.pojo.schema.PojoProducers;\n\npublic class PojoProducerProvider extends AbstractProducerProvider {\n  private final Map<String, InstanceFactory> instanceFactoryMgr = new HashMap<>();\n\n  private void registerInstanceFactory(InstanceFactory instanceFactory) {\n    instanceFactoryMgr.put(instanceFactory.getImplName(), instanceFactory);\n  }\n\n  public PojoProducerProvider() {\n    registerInstanceFactory(new PojoInstanceFactory());\n    registerInstanceFactory(new SpringInstanceFactory());\n  }\n\n  @Override\n  public List<ProducerMeta> init() {\n    // for some test cases, there is no spring context\n    if (BeanUtils.getContext() == null) {\n      return Collections.emptyList();\n    }\n\n    PojoProducers pojoProducers = BeanUtils.getContext().getBean(PojoProducers.class);\n    for (ProducerMeta producerMeta : pojoProducers.getProducerMetas()) {\n      PojoProducerMeta pojoProducerMeta = (PojoProducerMeta) producerMeta;\n      initPojoProducerMeta(pojoProducerMeta);\n    }\n\n    return pojoProducers.getProducerMetas();\n  }\n\n  @Override\n  public String getName() {\n    return PojoConst.POJO;\n  }\n\n  private void initPojoProducerMeta(PojoProducerMeta pojoProducerMeta) {\n    parseSchemaInterface(pojoProducerMeta);\n    parseImplementation(pojoProducerMeta);\n  }\n\n  private void parseImplementation(PojoProducerMeta pojoProducerMeta) {\n    if (pojoProducerMeta.getInstance() != null) {\n      return;\n    }\n\n    String implementation = pojoProducerMeta.getImplementation();\n    String implName = PojoConst.POJO;\n    String implValue = pojoProducerMeta.getImplementation();\n    int idx = implementation.indexOf(':');\n    if (idx != -1) {\n      implName = implementation.substring(0, idx);\n      implValue = implementation.substring(idx + 1);\n    }\n\n    InstanceFactory factory = instanceFactoryMgr.get(implName);\n    if (factory == null) {\n      throw new IllegalStateException(\"failed to find instance factory, name=\" + implName);\n    }\n\n    Object instance = factory.create(implValue);\n    pojoProducerMeta.setInstance(instance);\n  }\n\n  private void parseSchemaInterface(PojoProducerMeta pojoProducerMeta) {\n    if (pojoProducerMeta.getSchemaInterface() != null || StringUtils\n        .isEmpty(pojoProducerMeta.getSchemaInterfaceName())) {\n      return;\n    }\n\n    try {\n      Class<?> si = Class.forName(pojoProducerMeta.getSchemaInterfaceName());\n      pojoProducerMeta.setSchemaInterface(si);\n    } catch (Exception e) {\n      throw new Error(\"can not find schema interface \" + pojoProducerMeta.getSchemaInterfaceName(), e);\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/ProviderPojoConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo;\n\nimport org.apache.servicecomb.provider.pojo.schema.PojoProducers;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ProviderPojoConfiguration {\n  @Bean\n  public static RpcReferenceBeanDefinitionRegistry rpcReferenceBeanDefinitionRegistry() {\n    return new RpcReferenceBeanDefinitionRegistry();\n  }\n\n  @Bean\n  public static PojoProducers pojoProducers() {\n    return new PojoProducers();\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcReference.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\nimport static java.lang.annotation.ElementType.ANNOTATION_TYPE;\nimport static java.lang.annotation.ElementType.FIELD;\nimport static java.lang.annotation.ElementType.METHOD;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\n@Documented\n@Retention(RUNTIME)\n@Target({FIELD, METHOD, ANNOTATION_TYPE})\npublic @interface RpcReference {\n  String microserviceName();\n\n  String schemaId() default \"\";\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcReferenceBeanDefinitionRegistry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\nimport org.apache.servicecomb.provider.pojo.reference.RpcReferenceProcessor;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.config.ConfigurableListableBeanFactory;\nimport org.springframework.beans.factory.support.BeanDefinitionRegistry;\nimport org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;\n\n/**\n * In order to support FactoryBean eager inject @RpcReference, add RpcReferenceProcessor\n * before FactoryBean is initialized.\n */\npublic class RpcReferenceBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor {\n  @Override\n  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {\n\n  }\n\n  @Override\n  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {\n    beanFactory.addBeanPostProcessor(new RpcReferenceProcessor(beanFactory));\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\nimport static java.lang.annotation.ElementType.ANNOTATION_TYPE;\nimport static java.lang.annotation.ElementType.TYPE;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport org.springframework.stereotype.Component;\n\n@Inherited\n@Documented\n@Retention(RUNTIME)\n@Target({TYPE, ANNOTATION_TYPE})\n@Component\npublic @interface RpcSchema {\n  String schemaId() default \"\";\n\n  Class<?> schemaInterface() default Object.class;\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo.definition;\n\nimport java.lang.reflect.Method;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class PojoConsumerMeta {\n  private final MicroserviceReferenceConfig microserviceReferenceConfig;\n\n  private final SchemaMeta schemaMeta;\n\n  private final Map<Method, PojoConsumerOperationMeta> operationMetas = new HashMap<>();\n\n  public PojoConsumerMeta(MicroserviceReferenceConfig microserviceReferenceConfig, SwaggerConsumer swaggerConsumer,\n      SchemaMeta schemaMeta) {\n    this.microserviceReferenceConfig = microserviceReferenceConfig;\n    this.schemaMeta = schemaMeta;\n\n    for (SwaggerConsumerOperation swaggerConsumerOperation : swaggerConsumer.getOperations().values()) {\n      String operationId = swaggerConsumerOperation.getSwaggerOperation().getOperationId();\n      // SwaggerConsumer has make sure can find operationMeta\n      OperationMeta operationMeta = schemaMeta.ensureFindOperation(operationId);\n      PojoConsumerOperationMeta pojoConsumerOperationMeta = new PojoConsumerOperationMeta(this, operationMeta,\n          swaggerConsumerOperation);\n\n      operationMetas.put(swaggerConsumerOperation.getConsumerMethod(), pojoConsumerOperationMeta);\n    }\n  }\n\n  public MicroserviceReferenceConfig getMicroserviceReferenceConfig() {\n    return microserviceReferenceConfig;\n  }\n\n  public MicroserviceMeta getMicroserviceMeta() {\n    return schemaMeta.getMicroserviceMeta();\n  }\n\n  public SchemaMeta getSchemaMeta() {\n    return schemaMeta;\n  }\n\n  public PojoConsumerOperationMeta ensureFindOperationMeta(Method method) {\n    PojoConsumerOperationMeta pojoConsumerOperationMeta = operationMetas.get(method);\n    if (pojoConsumerOperationMeta == null) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          String.format(\n              \"Consumer method %s:%s not exist in contract, microserviceName=%s, schemaId=%s.\",\n              method.getDeclaringClass().getName(),\n              method.getName(),\n              schemaMeta.getMicroserviceName(),\n              schemaMeta.getSchemaId()));\n    }\n    return pojoConsumerOperationMeta;\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo.definition;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findResponseTypeProcessor;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.core.definition.InvocationRuntimeType;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.google.common.reflect.TypeToken;\n\npublic class PojoConsumerOperationMeta {\n  private final PojoConsumerMeta pojoConsumerMeta;\n\n  private final OperationMeta operationMeta;\n\n  private final SwaggerConsumerOperation swaggerConsumerOperation;\n\n  private JavaType responseType;\n\n  private InvocationRuntimeType invocationRuntimeType;\n\n  private final boolean sync;\n\n  public PojoConsumerOperationMeta(PojoConsumerMeta pojoConsumerMeta, OperationMeta operationMeta,\n      SwaggerConsumerOperation swaggerConsumerOperation) {\n    this.pojoConsumerMeta = pojoConsumerMeta;\n    this.operationMeta = operationMeta;\n    this.swaggerConsumerOperation = swaggerConsumerOperation;\n    this.sync = InvokerUtils.isSyncMethod(swaggerConsumerOperation.getConsumerMethod());\n    initResponseType();\n    initRuntimeType();\n  }\n\n  private void initRuntimeType() {\n    invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();\n    invocationRuntimeType.setArgumentsMapper(swaggerConsumerOperation.getArgumentsMapper());\n    invocationRuntimeType.setAssociatedClass(swaggerConsumerOperation.getConsumerClass());\n    invocationRuntimeType.setAssociatedMethod(swaggerConsumerOperation.getConsumerMethod());\n  }\n\n  public PojoConsumerMeta getPojoConsumerMeta() {\n    return pojoConsumerMeta;\n  }\n\n  public OperationMeta getOperationMeta() {\n    return operationMeta;\n  }\n\n  public SwaggerConsumerOperation getSwaggerConsumerOperation() {\n    return swaggerConsumerOperation;\n  }\n\n  public JavaType getResponsesType() {\n    return responseType;\n  }\n\n  public InvocationRuntimeType getInvocationRuntimeType() {\n    return invocationRuntimeType;\n  }\n\n  public ReferenceConfig createReferenceConfig() {\n    return pojoConsumerMeta.getMicroserviceReferenceConfig()\n        .createReferenceConfig(operationMeta);\n  }\n\n  private void initResponseType() {\n    Type intfResponseType =\n        TypeToken.of(swaggerConsumerOperation.getConsumerClass())\n            .resolveType(swaggerConsumerOperation.getConsumerMethod().getGenericReturnType())\n            .getType();\n    if (intfResponseType instanceof Class && Part.class.isAssignableFrom((Class<?>) intfResponseType)) {\n      responseType = TypeFactory.defaultInstance().constructType(Part.class);\n      return;\n    }\n\n    intfResponseType = findResponseTypeProcessor(intfResponseType).extractResponseType(intfResponseType);\n    if (intfResponseType != null) {\n      responseType = TypeFactory.defaultInstance().constructType(intfResponseType);\n    }\n  }\n\n  public boolean isSync() {\n    return sync;\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/instance/PojoInstanceFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.instance;\n\nimport org.apache.servicecomb.provider.pojo.InstanceFactory;\nimport org.apache.servicecomb.provider.pojo.PojoConst;\n\npublic class PojoInstanceFactory implements InstanceFactory {\n  @Override\n  public String getImplName() {\n    return PojoConst.POJO;\n  }\n\n  @Override\n  public Object create(String className) {\n    try {\n      Class<?> clazz = Class.forName(className);\n      return clazz.getDeclaredConstructor().newInstance();\n    } catch (Exception e) {\n      throw new Error(\"Fail to create instance of class:\" + className, e);\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/instance/SpringInstanceFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.instance;\n\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.provider.pojo.InstanceFactory;\nimport org.apache.servicecomb.provider.pojo.PojoConst;\n\npublic class SpringInstanceFactory implements InstanceFactory {\n  @Override\n  public String getImplName() {\n    return PojoConst.SPRING;\n  }\n\n  @Override\n  public Object create(String beanId) {\n    Object instance = BeanUtils.getBean(beanId);\n    if (instance == null) {\n      throw new Error(\"Fail to find bean:\" + beanId);\n    }\n\n    return instance;\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/PojoReferenceMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.reference;\n\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.springframework.beans.factory.FactoryBean;\nimport org.springframework.beans.factory.InitializingBean;\n\npublic class PojoReferenceMeta implements FactoryBean<Object>, InitializingBean {\n  // 原始数据\n  private String microserviceName;\n\n  private String schemaId;\n\n  private Class<?> consumerIntf;\n\n  // 根据intf创建出来的动态代理\n  // TODO:未实现本地优先(本地场景下，应该跳过handler机制)\n  private Object proxy;\n\n  public Object getProxy() {\n    return getObject();\n  }\n\n  @Override\n  public Object getObject() {\n    return proxy;\n  }\n\n  @Override\n  public Class<?> getObjectType() {\n    return consumerIntf;\n  }\n\n  @Override\n  public boolean isSingleton() {\n    return true;\n  }\n\n  public void setConsumerIntf(Class<?> intf) {\n    this.consumerIntf = intf;\n  }\n\n  public void setMicroserviceName(String microserviceName) {\n    this.microserviceName = microserviceName;\n  }\n\n  public void setSchemaId(String schemaId) {\n    this.schemaId = schemaId;\n  }\n\n  @Override\n  public void afterPropertiesSet() {\n    if (consumerIntf == null) {\n      throw new ServiceCombException(\n          String.format(\n              \"microserviceName=%s, schemaid=%s, \\n\"\n                  + \"do not support implicit interface anymore, \\n\"\n                  + \"because that caused problems:\\n\"\n                  + \"  1.the startup process relies on other microservices\\n\"\n                  + \"  2.cyclic dependent microservices can not be deployed\\n\"\n                  + \"suggest to use @RpcReference or \"\n                  + \"<cse:rpc-reference id=\\\"...\\\" microservice-name=\\\"...\\\" schema-id=\\\"...\\\" interface=\\\"...\\\"></cse:rpc-reference>.\",\n              microserviceName,\n              schemaId));\n    }\n\n    proxy = Invoker.createProxy(microserviceName, schemaId, consumerIntf);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/ReferenceDefParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.reference;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.provider.pojo.PojoConst;\nimport org.springframework.beans.factory.support.BeanDefinitionBuilder;\nimport org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;\nimport org.springframework.beans.factory.xml.ParserContext;\nimport org.w3c.dom.Element;\n\npublic class ReferenceDefParser extends AbstractSingleBeanDefinitionParser {\n  @Override\n  protected Class<?> getBeanClass(Element element) {\n    return PojoReferenceMeta.class;\n  }\n\n  @Override\n  protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {\n    builder.addPropertyValue(PojoConst.FIELD_MICROSERVICE_NAME,\n        element.getAttribute(PojoConst.MICROSERVICE_NAME));\n\n    String schemaId = element.getAttribute(PojoConst.SCHEMA_ID);\n    String intf = element.getAttribute(PojoConst.INTERFACE);\n\n    if (StringUtils.isEmpty(intf) && StringUtils.isNotEmpty(schemaId)) {\n      //  尝试将schemaId当作接口名使用\n      Class<?> consumerIntf = ReflectUtils.getClassByName(schemaId);\n      if (consumerIntf != null) {\n        intf = schemaId;\n      }\n    }\n\n    builder.addPropertyValue(PojoConst.FIELD_SCHEMA_ID, schemaId);\n    builder.addPropertyValue(PojoConst.FIELD_INTERFACE, intf);\n\n    if (StringUtils.isEmpty(schemaId) && StringUtils.isEmpty(intf)) {\n      throw new Error(\"schema-id and interface can not both be empty.\");\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/RpcReferenceProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo.reference;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\n\nimport org.apache.servicecomb.provider.pojo.RpcReference;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.BeanCreationException;\nimport org.springframework.beans.factory.config.BeanPostProcessor;\nimport org.springframework.beans.factory.config.ConfigurableBeanFactory;\nimport org.springframework.util.ReflectionUtils;\n\npublic class RpcReferenceProcessor implements BeanPostProcessor {\n  private final ConfigurableBeanFactory beanFactory;\n\n  public RpcReferenceProcessor(ConfigurableBeanFactory beanFactory) {\n    this.beanFactory = beanFactory;\n  }\n\n  @Override\n  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {\n    // 扫描所有field，处理扩展的field标注\n    ReflectionUtils.doWithFields(bean.getClass(), field -> processConsumerField(bean, field));\n    ReflectionUtils.doWithMethods(bean.getClass(), method -> processConsumerMethod(bean, beanName, method));\n    return bean;\n  }\n\n  @Override\n  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {\n    return bean;\n  }\n\n  protected void processConsumerMethod(Object bean, String beanName, Method method) throws BeansException {\n    RpcReference reference = method.getAnnotation(RpcReference.class);\n    if (reference == null) {\n      return;\n    }\n    handleReferenceMethod(bean, beanName, method, reference);\n  }\n\n  protected void processConsumerField(Object bean, Field field) {\n    RpcReference reference = field.getAnnotation(RpcReference.class);\n    if (reference == null) {\n      return;\n    }\n\n    handleReferenceField(bean, field, reference);\n  }\n\n  private void handleReferenceMethod(Object bean, String beanName, Method method, RpcReference reference)\n      throws BeansException {\n    try {\n      PojoReferenceMeta pojoReference = createPojoReferenceMeta(reference, method.getParameterTypes()[0]);\n      method.invoke(bean, pojoReference.getProxy());\n    } catch (Exception e) {\n      throw new BeanCreationException(beanName, \"\", e);\n    }\n  }\n\n  private void handleReferenceField(Object obj, Field field,\n      RpcReference reference) {\n    PojoReferenceMeta pojoReference = createPojoReferenceMeta(reference, field.getType());\n    ReflectionUtils.makeAccessible(field);\n    ReflectionUtils.setField(field, obj, pojoReference.getProxy());\n  }\n\n  private PojoReferenceMeta createPojoReferenceMeta(RpcReference reference, Class<?> consumerInterface) {\n    String microserviceName = reference.microserviceName();\n    microserviceName = beanFactory.resolveEmbeddedValue(microserviceName);\n\n    PojoReferenceMeta pojoReference = new PojoReferenceMeta();\n    pojoReference.setMicroserviceName(microserviceName);\n    pojoReference.setSchemaId(reference.schemaId());\n    pojoReference.setConsumerIntf(consumerInterface);\n    pojoReference.afterPropertiesSet();\n    return pojoReference;\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/schema/PojoProducerMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.schema;\n\nimport org.apache.servicecomb.core.provider.producer.ProducerMeta;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class PojoProducerMeta extends ProducerMeta implements InitializingBean {\n  @Autowired\n  protected PojoProducers pojoProducers;\n\n  private String implementation;\n\n  private String schemaInterfaceName;\n\n  @VisibleForTesting\n  void setPojoProducers(PojoProducers pojoProducers) {\n    this.pojoProducers = pojoProducers;\n  }\n\n  public String getImplementation() {\n    return implementation;\n  }\n\n  public void setImplementation(String implementation) {\n    this.implementation = implementation;\n  }\n\n  public String getSchemaInterfaceName() {\n    return schemaInterfaceName;\n  }\n\n  public PojoProducerMeta setSchemaInterfaceName(String schemaInterfaceName) {\n    this.schemaInterfaceName = schemaInterfaceName;\n    return this;\n  }\n\n  @Override\n  public void afterPropertiesSet() {\n    pojoProducers.registerPojoProducer(this);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/schema/PojoProducers.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.pojo.schema;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.provider.producer.ProducerMeta;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.config.BeanPostProcessor;\n\npublic class PojoProducers implements BeanPostProcessor {\n  private final List<ProducerMeta> producerMetas = new ArrayList<>();\n\n  public synchronized void registerPojoProducer(PojoProducerMeta pojoProducer) {\n    producerMetas.add(pojoProducer);\n  }\n\n  public List<ProducerMeta> getProducerMetas() {\n    return producerMetas;\n  }\n\n  @Override\n  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {\n    return bean;\n  }\n\n  @Override\n  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {\n    processProvider(beanName, bean);\n\n    return bean;\n  }\n\n  protected void processProvider(String beanName, Object bean) {\n    // aop后，新的实例的父类可能是原class，也可能只是个proxy，父类不是原class\n    // 所以，需要先取出原class，再取标注\n    Class<?> beanCls = BeanUtils.getImplClassFromBean(bean);\n    if (beanCls == null) {\n      return;\n    }\n    RpcSchema rpcSchema = beanCls.getAnnotation(RpcSchema.class);\n    if (rpcSchema == null) {\n      return;\n    }\n\n    String schemaId = rpcSchema.schemaId();\n    if (StringUtils.isEmpty(schemaId)) {\n      Class<?>[] intfs = beanCls.getInterfaces();\n      if (intfs.length == 1) {\n        schemaId = intfs[0].getName();\n      } else {\n        throw new Error(\"Must be schemaId or implements only one interface\");\n      }\n    }\n\n    PojoProducerMeta pojoProducerMeta = new PojoProducerMeta();\n    pojoProducerMeta.setSchemaId(schemaId);\n    pojoProducerMeta.setSchemaInterface(rpcSchema.schemaInterface());\n    pojoProducerMeta.setInstance(bean);\n\n    registerPojoProducer(pojoProducerMeta);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/schema/SchemaDefParser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.schema;\n\nimport org.apache.servicecomb.provider.pojo.PojoConst;\nimport org.springframework.beans.factory.support.BeanDefinitionBuilder;\nimport org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;\nimport org.springframework.beans.factory.xml.ParserContext;\nimport org.w3c.dom.Element;\n\npublic class SchemaDefParser extends AbstractSingleBeanDefinitionParser {\n  @Override\n  protected boolean shouldGenerateId() {\n    return true;\n  }\n\n  @Override\n  protected boolean shouldParseNameAsAliases() {\n    return false;\n  }\n\n  @Override\n  protected Class<?> getBeanClass(Element element) {\n    return PojoProducerMeta.class;\n  }\n\n  @Override\n  protected void doParse(Element element, ParserContext parserContext,\n      BeanDefinitionBuilder builder) {\n    builder.addPropertyValue(PojoConst.FIELD_SCHEMA_ID, element.getAttribute(PojoConst.SCHEMA_ID));\n    builder.addPropertyValue(PojoConst.IMPL, element.getAttribute(PojoConst.IMPL));\n    builder.addPropertyValue(PojoConst.FIELD_SCHEMA_INTERFACE, element.getAttribute(PojoConst.SCHEMA_INTERFACE));\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/services/org.apache.servicecomb.core.ProducerProvider",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.provider.pojo.PojoProducerProvider\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/spring/namespace.properties",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nrpc-reference=org.apache.servicecomb.provider.pojo.reference.ReferenceDefParser\nrpc-schema=org.apache.servicecomb.provider.pojo.schema.SchemaDefParser\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.provider.pojo.ProviderPojoConfiguration\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/spring/spring-paas-cse-rpc-1.0.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<xsd:schema xmlns=\"http://www.huawei.com/schema/paas/cse/rpc\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://www.huawei.com/schema/paas/cse/rpc\"\n  elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n  <xsd:element name=\"rpc-schema\">\n    <xsd:complexType>\n      <xsd:attribute name=\"schema-id\" type=\"xsd:string\" use=\"required\"/>\n      <xsd:attribute name=\"implementation\" type=\"xsd:string\" use=\"required\"/>\n      <xsd:attribute name=\"schema-interface\" type=\"xsd:string\" use=\"optional\"/>\n    </xsd:complexType>\n  </xsd:element>\n\n  <xsd:element name=\"rpc-reference\">\n    <xsd:complexType>\n      <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\"/>\n      <xsd:attribute name=\"microservice-name\" type=\"xsd:string\" use=\"required\"/>\n      <xsd:attribute name=\"schema-id\" type=\"xsd:string\" use=\"optional\"/>\n      <xsd:attribute name=\"interface\" type=\"xsd:string\" use=\"optional\"/>\n    </xsd:complexType>\n  </xsd:element>\n</xsd:schema>\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/spring/spring-paas-cse-rpc.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<xsd:schema xmlns=\"http://www.huawei.com/schema/paas/cse/rpc\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://www.huawei.com/schema/paas/cse/rpc\"\n\telementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n\n\t<xsd:include schemaLocation=\"classpath:META-INF/spring/spring-paas-cse-rpc-1.0.xsd\"></xsd:include>\n\n</xsd:schema>\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/spring.handlers",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nhttp\\://www.huawei.com/schema/paas/cse/rpc=org.apache.servicecomb.foundation.common.spring.PaasNamespaceHandler\n"
  },
  {
    "path": "providers/provider-pojo/src/main/resources/META-INF/spring.schemas",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nhttp\\://www.huawei.com/schema/paas/cse/rpc/spring-paas-cse-rpc-1.0.xsd=META-INF/spring/spring-paas-cse-rpc-1.0.xsd\nhttp\\://www.huawei.com/schema/paas/cse/rpc/spring-paas-cse-rpc.xsd=META-INF/spring/spring-paas-cse-rpc-1.0.xsd\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/IPerson.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\npublic interface IPerson {\n\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/Person.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\n@RpcSchema(schemaId = \"test\")\npublic class Person implements IPerson {\n  public String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/PersonReference.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo;\n\npublic class PersonReference {\n  @RpcReference(microserviceName = \"test\", schemaId = \"test\")\n  public IPerson person;\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/instance/TestPojoInstanceFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.instance;\n\nimport org.apache.servicecomb.provider.pojo.PojoConst;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPojoInstanceFactory {\n\n  @Test\n  public void testInitException() {\n    PojoInstanceFactory lPojoInstanceFactory = new PojoInstanceFactory();\n    try {\n      lPojoInstanceFactory.create(\"TestPojoInstanceFactory\");\n    } catch (Error e) {\n      Assertions.assertEquals(\"Fail to create instance of class:TestPojoInstanceFactory\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testInit() {\n    PojoInstanceFactory lPojoInstanceFactory = new PojoInstanceFactory();\n    lPojoInstanceFactory.create(\"org.apache.servicecomb.provider.pojo.instance.TestPojoInstanceFactory\");\n    Assertions.assertEquals(PojoConst.POJO, lPojoInstanceFactory.getImplName());\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/instance/TestSpringInstanceFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.instance;\n\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.provider.pojo.PojoConst;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.springframework.context.ApplicationContext;\n\npublic class TestSpringInstanceFactory {\n\n  @Test\n  public void testInitException() {\n\n    SpringInstanceFactory lSpringInstanceFactory = new SpringInstanceFactory();\n    try (MockedStatic<BeanUtils> beanUtilsMockedStatic = Mockito.mockStatic(BeanUtils.class)) {\n      beanUtilsMockedStatic.when(BeanUtils::getContext).thenReturn(Mockito.mock(ApplicationContext.class));\n      beanUtilsMockedStatic.when(() -> BeanUtils.getBean(Mockito.anyString())).thenReturn(null);\n      try {\n        lSpringInstanceFactory.create(\"TestSpringInstanceFactory\");\n      } catch (Error e) {\n        Assertions.assertEquals(\"Fail to find bean:TestSpringInstanceFactory\", e.getMessage());\n      }\n    }\n  }\n\n  @Test\n  public void testInit() {\n\n    SpringInstanceFactory lSpringInstanceFactory = new SpringInstanceFactory();\n    try (MockedStatic<BeanUtils> beanUtilsMockedStatic = Mockito.mockStatic(BeanUtils.class)) {\n      beanUtilsMockedStatic.when(BeanUtils::getContext).thenReturn(Mockito.mock(ApplicationContext.class));\n      beanUtilsMockedStatic.when(() -> BeanUtils.getBean(Mockito.anyString())).thenReturn(new Object());\n\n      lSpringInstanceFactory.create(\"org.apache.servicecomb.provider.pojo.instance.TestPojoInstanceFactory\");\n      Assertions.assertEquals(PojoConst.SPRING, lSpringInstanceFactory.getImplName());\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/reference/PojoReferenceMetaTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.reference;\n\nimport static org.hamcrest.core.IsInstanceOf.instanceOf;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.provider.pojo.IPerson;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class PojoReferenceMetaTest {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n  }\n\n  @AfterEach\n  public void teardown() {\n  }\n\n  @Test\n  public void testHasConsumerInterface() {\n    SCBEngine scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n\n    PojoReferenceMeta pojoReferenceMeta = new PojoReferenceMeta();\n    pojoReferenceMeta.setMicroserviceName(\"test\");\n    pojoReferenceMeta.setSchemaId(\"schemaId\");\n    pojoReferenceMeta.setConsumerIntf(IPerson.class);\n    pojoReferenceMeta.afterPropertiesSet();\n\n    Assertions.assertEquals(IPerson.class, pojoReferenceMeta.getObjectType());\n    MatcherAssert.assertThat(pojoReferenceMeta.getProxy(), instanceOf(IPerson.class));\n    Assertions.assertTrue(pojoReferenceMeta.isSingleton());\n\n    scbEngine.destroy();\n  }\n\n  @Test\n  public void testNoConsumerInterface() {\n    PojoReferenceMeta pojoReferenceMeta = new PojoReferenceMeta();\n    pojoReferenceMeta.setMicroserviceName(\"test\");\n    pojoReferenceMeta.setSchemaId(\"schemaId\");\n\n    try {\n      pojoReferenceMeta.afterPropertiesSet();\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\n          \"microserviceName=test, schemaid=schemaId, \\n\"\n              + \"do not support implicit interface anymore, \\n\"\n              + \"because that caused problems:\\n\"\n              + \"  1.the startup process relies on other microservices\\n\"\n              + \"  2.cyclic dependent microservices can not be deployed\\n\"\n              + \"suggest to use @RpcReference or \"\n              + \"<cse:rpc-reference id=\\\"...\\\" microservice-name=\\\"...\\\" schema-id=\\\"...\\\" interface=\\\"...\\\"></cse:rpc-reference>.\",\n          e.getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/reference/TestRpcReferenceProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.reference;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.foundation.test.scaffolding.spring.SpringUtils;\nimport org.apache.servicecomb.provider.pojo.Person;\nimport org.apache.servicecomb.provider.pojo.PersonReference;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.beans.factory.config.ConfigurableBeanFactory;\nimport org.springframework.core.env.Environment;\n\npublic class TestRpcReferenceProcessor {\n  static Environment environment = Mockito.mock(Environment.class);\n\n  static ConfigurableBeanFactory beanFactory = Mockito.mock(ConfigurableBeanFactory.class);\n\n  RpcReferenceProcessor consumers = new RpcReferenceProcessor(beanFactory);\n\n  @BeforeEach\n  public void setUp() {\n  }\n\n  @AfterEach\n  public void teardown() {\n  }\n\n  @Test\n  public void postProcessAfterInitialization() {\n    Object bean = new Object();\n    Assertions.assertSame(bean, consumers.postProcessAfterInitialization(bean, \"test\"));\n  }\n\n  @Test\n  public void testReference() {\n    SCBEngine scbEngine = SCBBootstrap.createSCBEngineForTest(environment);\n\n    PersonReference bean = new PersonReference();\n\n    Assertions.assertNull(bean.person);\n\n    Mockito.when(beanFactory.resolveEmbeddedValue(\"test\")).thenReturn(\"test\");\n    Assertions.assertSame(bean, consumers.postProcessBeforeInitialization(bean, \"id\"));\n\n    Assertions.assertNotNull(bean.person);\n\n    scbEngine.destroy();\n  }\n\n  @Test\n  public void testNoReference() {\n    Person bean = new Person();\n\n    Assertions.assertNull(bean.name);\n\n    Assertions.assertSame(bean, consumers.postProcessBeforeInitialization(bean, \"id\"));\n\n    Assertions.assertNull(bean.name);\n  }\n\n  @Test\n  public void ensureNoInject() {\n    SpringUtils.ensureNoInject(RpcReferenceProcessor.class);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/schema/TestPojoProducers.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.schema;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.spring.SpringUtils;\nimport org.apache.servicecomb.provider.pojo.IPerson;\nimport org.apache.servicecomb.provider.pojo.Person;\nimport org.apache.servicecomb.provider.pojo.RpcSchema;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPojoProducers {\n  PojoProducers producer = new PojoProducers();\n\n  @Test\n  public void postProcessBeforeInitialization() {\n    Object bean = new Object();\n    Assertions.assertSame(bean, producer.postProcessBeforeInitialization(bean, \"test\"));\n  }\n\n  @Test\n  public void testPojoProducers() {\n    Person bean = new Person();\n    Assertions.assertSame(bean, producer.postProcessAfterInitialization(bean, \"test\"));\n    Assertions.assertEquals(producer.getProducerMetas().size(), 1);\n  }\n\n  @Test\n  public void testPojoProducersSchemaNull() {\n    IPerson bean = new IPerson() {\n    };\n    Assertions.assertSame(bean, producer.postProcessAfterInitialization(bean, \"test\"));\n    Assertions.assertEquals(producer.getProducerMetas().size(), 0);\n  }\n\n  @RpcSchema\n  static class PersonEmptySchema implements IPerson {\n\n  }\n\n  @Test\n  public void testPojoProducersSchemaIdNull() {\n    IPerson bean = new PersonEmptySchema();\n    Assertions.assertSame(bean, producer.postProcessAfterInitialization(bean, \"test\"));\n    Assertions.assertEquals(producer.getProducerMetas().size(), 1);\n  }\n\n  @Test\n  public void ensureNoInject() {\n    SpringUtils.ensureNoInject(PojoProducers.class);\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/schema/TestPojoSchemaMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.pojo.schema;\n\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestPojoSchemaMeta {\n\n  PojoProducerMeta lPojoSchemaMeta = null;\n\n  @BeforeEach\n  public void setUp()\n      throws Exception {\n    lPojoSchemaMeta = new PojoProducerMeta();\n  }\n\n  @AfterEach\n  public void tearDown()\n      throws Exception {\n    lPojoSchemaMeta = null;\n  }\n\n  @Test\n  public void testGetImplementation() {\n    PojoProducers producers = Mockito.mock(PojoProducers.class);\n    lPojoSchemaMeta.setImplementation(\"implementation\");\n    lPojoSchemaMeta.setPojoProducers(producers);\n    lPojoSchemaMeta.afterPropertiesSet();\n    Assertions.assertEquals(\"implementation\", lPojoSchemaMeta.getImplementation());\n  }\n\n  @Test\n  public void testGetInstance()\n      throws Exception {\n    Object lObject = new Object();\n    lPojoSchemaMeta.setInstance(lObject);\n    Assertions.assertEquals(lObject, lPojoSchemaMeta.getInstance());\n  }\n\n  @Test\n  public void testGetSchemaId()\n      throws Exception {\n    lPojoSchemaMeta.setSchemaId(\"schemaId\");\n    Assertions.assertEquals(\"schemaId\", lPojoSchemaMeta.getSchemaId());\n  }\n}\n"
  },
  {
    "path": "providers/provider-pojo/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  filter-chains:\n    consumer:\n      default: empty\n    producer:\n      default: empty\n"
  },
  {
    "path": "providers/provider-rest-common/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>providers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>provider-rest-common</artifactId>\n  <name>Java Chassis::Providers::Rest Common</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/InvocationToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.vertx.http.AbstractHttpServletRequest;\n\nimport io.vertx.core.net.SocketAddress;\n\n/**\n * when transport is not over http, mock an HttpServletRequest from Invocation\n */\npublic class InvocationToHttpServletRequest extends AbstractHttpServletRequest {\n  private final RestOperationMeta swaggerOperation;\n\n  private final Invocation invocation;\n\n  public InvocationToHttpServletRequest(Invocation invocation) {\n    this.swaggerOperation = invocation.getOperationMeta().getExtData(RestConst.SWAGGER_REST_OPERATION);\n    this.invocation = invocation;\n  }\n\n  private SocketAddress getSockerAddress() {\n    return (SocketAddress) invocation.getHandlerContext().get(CoreConst.REMOTE_ADDRESS);\n  }\n\n  @Override\n  public String getParameter(String name) {\n    RestParam param = swaggerOperation.getParamByName(name);\n    if (param == null) {\n      return null;\n    }\n\n    Object value = param.getValue(invocation.getSwaggerArguments());\n    if (value == null) {\n      return null;\n    }\n\n    return String.valueOf(value);\n  }\n\n  @Override\n  public String[] getParameterValues(String name) {\n    RestParam param = swaggerOperation.getParamByName(name);\n    if (param == null) {\n      return null;\n    }\n\n    return param.getValueAsStrings(invocation.getSwaggerArguments());\n  }\n\n  @Override\n  public Map<String, String[]> getParameterMap() {\n    Map<String, String[]> paramMap = new HashMap<>();\n    for (RestParam param : swaggerOperation.getParamList()) {\n      String[] value = param.getValueAsStrings(invocation.getSwaggerArguments());\n      paramMap.put(param.getParamName(), value);\n    }\n    return paramMap;\n  }\n\n  @Override\n  public String getHeader(String name) {\n    return getParameter(name);\n  }\n\n  @Override\n  public int getIntHeader(String name) {\n    String header = getHeader(name);\n    if (header == null) {\n      return -1;\n    }\n\n    return Integer.parseInt(header);\n  }\n\n  @Override\n  public String getMethod() {\n    return this.swaggerOperation.getHttpMethod();\n  }\n\n  @Override\n  public String getPathInfo() {\n    try {\n      return this.swaggerOperation.getPathBuilder().createPathString(invocation.getSwaggerArguments());\n    } catch (Exception e) {\n      throw new ServiceCombException(\"Failed to get path info.\", e);\n    }\n  }\n\n  @Override\n  public String getRemoteAddr() {\n    return this.getSockerAddress() == null ? \"\" : this.getSockerAddress().host();\n  }\n\n  @Override\n  public String getRemoteHost() {\n    return this.getSockerAddress() == null ? \"\" : this.getSockerAddress().host();\n  }\n\n  @Override\n  public int getRemotePort() {\n    return this.getSockerAddress() == null ? 0 : this.getSockerAddress().port();\n  }\n\n  @Override\n  public String getContextPath() {\n    return \"\";\n  }\n\n  /**\n   * it's a mock httpServletRequest, contentType is unknown\n   * @return contentType\n   */\n  @Override\n  public String getContentType() {\n    return null;\n  }\n\n  /**\n   * it's a mock httpServletRequest, characterEncoding is unknown\n   * @return characterEncoding\n   */\n  @Override\n  public String getCharacterEncoding() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/ProducerHttpRequestArgMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.AbstractProducerContextArgMapper;\n\npublic class ProducerHttpRequestArgMapper extends AbstractProducerContextArgMapper {\n  public ProducerHttpRequestArgMapper(String invocationArgumentName, String swaggerArgumentName) {\n    super(invocationArgumentName, swaggerArgumentName);\n  }\n\n  @Override\n  public Object createContextArg(SwaggerInvocation swaggerInvocation) {\n    Invocation invocation = (Invocation) swaggerInvocation;\n    // 从rest transport来\n    HttpServletRequest request = (HttpServletRequest) invocation.getHandlerContext().get(RestConst.REST_REQUEST);\n    if (request != null) {\n      return request;\n    }\n\n    // 通过args模拟request\n    return new InvocationToHttpServletRequest(invocation);\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/ProducerHttpRequestArgMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory;\n\npublic class ProducerHttpRequestArgMapperFactory implements ProducerContextArgumentMapperFactory {\n\n  @Override\n  public Class<?> getContextClass() {\n    return HttpServletRequest.class;\n  }\n\n  @Override\n  public ArgumentMapper create(String invocationArgumentName, String swaggerArgumentName) {\n    return new ProducerHttpRequestArgMapper(invocationArgumentName, swaggerArgumentName);\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/ProducerServerWebSocketArgMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory;\n\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class ProducerServerWebSocketArgMapperFactory implements ProducerContextArgumentMapperFactory {\n\n  @Override\n  public Class<?> getContextClass() {\n    return ServerWebSocket.class;\n  }\n\n  @Override\n  public ArgumentMapper create(String invocationArgumentName, String swaggerArgumentName) {\n    return new ProducerServerWebSocketMapper(invocationArgumentName, swaggerArgumentName);\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/ProducerServerWebSocketMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport org.apache.servicecomb.common.rest.WebSocketTransportContext;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.AbstractProducerContextArgMapper;\n\n\npublic class ProducerServerWebSocketMapper extends AbstractProducerContextArgMapper {\n  public ProducerServerWebSocketMapper(String invocationArgumentName, String swaggerArgumentName) {\n    super(invocationArgumentName, swaggerArgumentName);\n  }\n\n  @Override\n  public Object createContextArg(SwaggerInvocation invocation) {\n    WebSocketTransportContext context = invocation.getTransportContext();\n    return context.getServerWebSocket();\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/ProviderRestCommonConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.rest.common;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ProviderRestCommonConfiguration {\n  @Bean\n  public static RestProducers restProducers() {\n    return new RestProducers();\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/RestProducerProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.provider.producer.AbstractProducerProvider;\nimport org.apache.servicecomb.core.provider.producer.ProducerMeta;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\n\npublic class RestProducerProvider extends AbstractProducerProvider {\n  @Override\n  public String getName() {\n    return RestConst.REST;\n  }\n\n  @Override\n  public List<ProducerMeta> init() {\n    // for some UT case, there is no spring context\n    if (BeanUtils.getContext() == null) {\n      return null;\n    }\n\n    RestProducers restProducers = BeanUtils.getContext().getBean(RestProducers.class);\n    return restProducers.getProducerMetaList();\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/RestProducers.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.rest.common;\n\nimport java.lang.annotation.Annotation;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.provider.producer.ProducerMeta;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.springframework.beans.BeansException;\nimport org.springframework.beans.factory.config.BeanPostProcessor;\nimport org.springframework.context.EnvironmentAware;\nimport org.springframework.core.env.Environment;\n\npublic class RestProducers implements BeanPostProcessor, EnvironmentAware {\n  private final List<ProducerMeta> producerMetaList = new ArrayList<>();\n\n  @SuppressWarnings(\"unchecked\")\n  private final Class<? extends Annotation> restControllerCls = (Class<? extends Annotation>) ReflectUtils\n      .getClassByName(\"org.springframework.web.bind.annotation.RestController\");\n\n  public List<ProducerMeta> getProducerMetaList() {\n    return producerMetaList;\n  }\n\n  private Environment environment;\n\n  @Override\n  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {\n    return bean;\n  }\n\n  @Override\n  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {\n    processProvider(beanName, bean);\n\n    return bean;\n  }\n\n  protected void processProvider(String beanName, Object bean) {\n    // aop后，新的实例的父类可能是原class，也可能只是个proxy，父类不是原class\n    // 所以，需要先取出原class，再取标注\n    Class<?> beanCls = BeanUtils.getImplClassFromBean(bean);\n    if (beanCls == null) {\n      return;\n    }\n    RestSchema restSchema = beanCls.getAnnotation(RestSchema.class);\n    if (restSchema != null) {\n      ProducerMeta producerMeta = new ProducerMeta(restSchema.schemaId(), bean);\n      producerMeta.setSchemaInterface(restSchema.schemaInterface());\n      producerMetaList.add(producerMeta);\n      return;\n    }\n\n    if (restControllerCls != null &&\n        environment.getProperty(RestConst.PROVIDER_SCAN_REST_CONTROLLER, boolean.class, true)\n        && beanCls.getAnnotation(restControllerCls) != null) {\n      ProducerMeta producerMeta = new ProducerMeta(beanCls.getName(), bean);\n      producerMetaList.add(producerMeta);\n    }\n  }\n\n  @Override\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/java/org/apache/servicecomb/provider/rest/common/RestSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport static java.lang.annotation.ElementType.ANNOTATION_TYPE;\nimport static java.lang.annotation.ElementType.TYPE;\nimport static java.lang.annotation.RetentionPolicy.RUNTIME;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Inherited;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport org.springframework.stereotype.Component;\n\n@Inherited\n@Documented\n@Retention(RUNTIME)\n@Target({TYPE, ANNOTATION_TYPE})\n@Component\npublic @interface RestSchema {\n  String schemaId();\n\n  Class<?> schemaInterface() default Object.class;\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/resources/META-INF/services/org.apache.servicecomb.core.ProducerProvider",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.provider.rest.common.RestProducerProvider\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.provider.rest.common.ProducerHttpRequestArgMapperFactory\norg.apache.servicecomb.provider.rest.common.ProducerServerWebSocketArgMapperFactory\n"
  },
  {
    "path": "providers/provider-rest-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.provider.rest.common.ProviderRestCommonConfiguration\n"
  },
  {
    "path": "providers/provider-rest-common/src/test/java/org/apache/servicecomb/provider/rest/common/TestInvocationToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.definition.RestParam;\nimport org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport io.vertx.core.net.SocketAddress;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestInvocationToHttpServletRequest {\n  Invocation invocation = Mockito.mock(Invocation.class);\n\n  OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n\n  RestOperationMeta swaggerOperation = Mockito.mock(RestOperationMeta.class);\n\n  Map<String, Object> args;\n\n  SocketAddress socketAddress = Mockito.mock(SocketAddress.class);\n\n  Map<String, Object> handlerContext = new HashMap<>();\n\n  HttpServletRequest request;\n\n  @BeforeEach\n  public void setup() {\n    handlerContext.put(CoreConst.REMOTE_ADDRESS, socketAddress);\n    args = new HashMap<>();\n\n   Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n   Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerOperation);\n\n    request = new InvocationToHttpServletRequest(invocation);\n  }\n\n  @AfterEach\n  public void tearDown() {\n\n  }\n\n  @Test\n  public void testGetParameterNotFound() {\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(null);\n\n    Assertions.assertNull(request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterNull() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValue(args)).thenReturn(null);\n\n    Assertions.assertNull(request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterNormal() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValue(args)).thenReturn(\"value\");\n\n    Assertions.assertEquals(\"value\", request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterValuesNotFound() {\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(null);\n\n    Assertions.assertNull(request.getParameterValues(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterValuesNormal() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValueAsStrings(args)).thenReturn(new String[] {\"value\"});\n\n    MatcherAssert.assertThat(request.getParameterValues(\"name\"), Matchers.arrayContaining(\"value\"));\n  }\n\n  @Test\n  public void testGetParameterMap() {\n    RestParam p1 = Mockito.mock(RestParam.class);\n    RestParam p2 = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamList()).thenReturn(Arrays.asList(p1, p2));\n    Mockito.when(p1.getValueAsStrings(args)).thenReturn(new String[] {\"v1\"});\n    Mockito.when(p1.getParamName()).thenReturn(\"p1\");\n    Mockito.when(p2.getValueAsStrings(args)).thenReturn(new String[] {\"v2\"});\n    Mockito.when(p2.getParamName()).thenReturn(\"p2\");\n\n    Map<String, String[]> params = request.getParameterMap();\n    MatcherAssert.assertThat(params.size(), Matchers.is(2));\n    MatcherAssert.assertThat(params, Matchers.hasEntry(\"p1\", new String[] {\"v1\"}));\n    MatcherAssert.assertThat(params, Matchers.hasEntry(\"p2\", new String[] {\"v2\"}));\n  }\n\n  @Test\n  public void testGetHeader() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValue(args)).thenReturn(\"value\");\n\n    Assertions.assertEquals(\"value\", request.getHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetIntHeaderNotFound() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValue(args)).thenReturn(null);\n\n    Assertions.assertEquals(-1, request.getIntHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetIntHeaderNotNumber() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValue(args)).thenReturn(\"value\");\n\n    try {\n      request.getIntHeader(\"name\");\n      Assertions.fail(\"must throw exception\");\n    } catch (NumberFormatException e) {\n      Assertions.assertEquals(\"For input string: \\\"value\\\"\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testGetIntHeaderNormal() {\n    RestParam restParam = Mockito.mock(RestParam.class);\n    Mockito.when(swaggerOperation.getParamByName(\"name\")).thenReturn(restParam);\n    Mockito.when(restParam.getValue(args)).thenReturn(\"1\");\n\n    Assertions.assertEquals(1, request.getIntHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetMethod() {\n    Mockito.when(swaggerOperation.getHttpMethod()).thenReturn(\"GET\");\n\n    Assertions.assertEquals(\"GET\", request.getMethod());\n  }\n\n  @Test\n  public void testGetPathInfoNormal() throws Exception {\n    URLPathBuilder builder = Mockito.mock(URLPathBuilder.class);\n    Mockito.when(swaggerOperation.getPathBuilder()).thenReturn(builder);\n    Mockito.when(builder.createPathString(args)).thenReturn(\"/path\");\n\n    Assertions.assertEquals(\"/path\", request.getPathInfo());\n  }\n\n  @Test\n  public void testGetPathInfoException() throws Exception {\n    URLPathBuilder builder = Mockito.mock(URLPathBuilder.class);\n    Mockito.when(swaggerOperation.getPathBuilder()).thenReturn(builder);\n    Mockito.when(builder.createPathString(args)).thenThrow(new Exception(\"error\"));\n\n    try {\n      request.getPathInfo();\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\"Failed to get path info.\", e.getMessage());\n      Assertions.assertEquals(\"error\", e.getCause().getMessage());\n    }\n  }\n\n  @Test\n  public void testGetRemoteAddress() throws Exception {\n    Mockito.when(socketAddress.host()).thenReturn(\"127.0.0.2\");\n    Mockito.when(socketAddress.port()).thenReturn(8088);\n    Mockito.when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    String addr = request.getRemoteAddr();\n    String host = request.getRemoteHost();\n    int port = request.getRemotePort();\n    Assertions.assertEquals(addr, \"127.0.0.2\");\n    Assertions.assertEquals(host, \"127.0.0.2\");\n    Assertions.assertEquals(port, 8088);\n  }\n\n  @Test\n  public void testGetRemoteAddressEmpty() throws Exception {\n    Invocation invocation = Mockito.mock(Invocation.class);\n\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerOperation);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    handlerContext.remove(CoreConst.REMOTE_ADDRESS);\n    Mockito.when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    InvocationToHttpServletRequest request = new InvocationToHttpServletRequest(invocation);\n    String addr = request.getRemoteAddr();\n    String host = request.getRemoteHost();\n    int port = request.getRemotePort();\n    Assertions.assertEquals(addr, \"\");\n    Assertions.assertEquals(host, \"\");\n    Assertions.assertEquals(port, 0);\n  }\n\n  @Test\n  public void testGetContextPath() {\n    InvocationToHttpServletRequest request = new InvocationToHttpServletRequest(invocation);\n    Assertions.assertEquals(\"\", request.getContextPath());\n  }\n\n  @Test\n  public void getContentType() {\n    Assertions.assertNull(request.getContentType());\n  }\n\n  @Test\n  public void getCharacterEncoding() {\n    Assertions.assertNull(request.getCharacterEncoding());\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/test/java/org/apache/servicecomb/provider/rest/common/TestProducerHttpRequestArgMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestProducerHttpRequestArgMapper {\n  Invocation invocation = Mockito.mock(Invocation.class);\n\n  ProducerHttpRequestArgMapper mapper = new ProducerHttpRequestArgMapper(\"test\", \"test\");\n\n  @Test\n  public void testGetFromContext() {\n    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n    Map<String, Object> context = new HashMap<>();\n    context.put(RestConst.REST_REQUEST, request);\n\n    Mockito.when(invocation.getHandlerContext()).thenReturn(context);\n\n    Assertions.assertSame(request, mapper.createContextArg(invocation));\n  }\n\n  @Test\n  public void testCreateFromInvocation() {\n    HttpServletRequest request = Mockito.mock(HttpServletRequest.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    RestOperationMeta swaggerOperation = Mockito.mock(RestOperationMeta.class);\n    Map<String, Object> context = new HashMap<>();\n\n    Mockito.when(invocation.getHandlerContext()).thenReturn(context);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerOperation);\n\n    Assertions.assertEquals(InvocationToHttpServletRequest.class, mapper.createContextArg(invocation).getClass());\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/test/java/org/apache/servicecomb/provider/rest/common/TestRestProducers.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.test.scaffolding.spring.SpringUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestRestProducers {\n  @RestSchema(schemaId = \"test\")\n  public static class RestSchemaForTest {\n  }\n\n  static Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeAll\n  public static void setUpClass() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(RestConst.PROVIDER_SCAN_REST_CONTROLLER, boolean.class, true))\n        .thenReturn(true);\n  }\n\n  RestProducers producer = new RestProducers();\n\n  @Test\n  public void postProcessBeforeInitialization() {\n    Object bean = new Object();\n    Assertions.assertSame(bean, producer.postProcessBeforeInitialization(bean, \"test\"));\n  }\n\n  @Test\n  public void postProcessAfterInitializationNormal() {\n    RestSchemaForTest bean = new RestSchemaForTest();\n    Assertions.assertSame(bean, producer.postProcessAfterInitialization(bean, \"\"));\n    Assertions.assertEquals(1, producer.getProducerMetaList().size());\n  }\n\n  @Test\n  public void postProcessAfterInitializationNoAnnotation() {\n    Object bean = new Object();\n    Assertions.assertSame(bean, producer.postProcessAfterInitialization(bean, \"\"));\n    Assertions.assertEquals(0, producer.getProducerMetaList().size());\n  }\n\n  @Test\n  public void ensureNoInject() {\n    SpringUtils.ensureNoInject(RestProducers.class);\n  }\n}\n"
  },
  {
    "path": "providers/provider-rest-common/src/test/java/org/apache/servicecomb/provider/rest/common/TestRestServiceProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.rest.common;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.springframework.context.ApplicationContext;\n\npublic class TestRestServiceProvider {\n  @Test\n  public void testInit() {\n    ApplicationContext context = Mockito.mock(ApplicationContext.class);\n    Mockito.when(context.getBean(RestProducers.class)).thenReturn(new RestProducers());\n    try (MockedStatic<BeanUtils> beanUtilsMockedStatic = Mockito.mockStatic(BeanUtils.class)) {\n      beanUtilsMockedStatic.when(BeanUtils::getContext).thenReturn(context);\n      RestProducerProvider restProducerProvider = new RestProducerProvider();\n      restProducerProvider.init();\n      Assertions.assertEquals(RestConst.REST, restProducerProvider.getName());\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project\n        xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n        xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>providers</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>provider-springmvc</artifactId>\n  <name>Java Chassis::Providers::Spring MVC</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-rest-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-springmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-springmvc</artifactId>\n    </dependency>\n    <!-- compile CseHttpMessageConverter need this one .-->\n    <dependency>\n      <groupId>com.google.code.findbugs</groupId>\n      <artifactId>jsr305</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/AcceptableRestTemplate.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.net.URI;\n\nimport org.springframework.web.client.RestTemplate;\n\npublic abstract class AcceptableRestTemplate extends RestTemplate {\n  public abstract boolean isAcceptable(String uri);\n\n  public abstract boolean isAcceptable(URI uri);\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CommonToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport static org.apache.servicecomb.foundation.common.utils.PartUtils.getSinglePart;\n\nimport java.io.IOException;\nimport java.net.HttpCookie;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.vertx.http.AbstractHttpServletRequest;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport jakarta.servlet.ServletInputStream;\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\n\n// restTemplate convert parameters to invocation args.\npublic class CommonToHttpServletRequest extends AbstractHttpServletRequest {\n  private final Map<String, List<String>> queryParams;\n\n  private final Map<String, List<String>> httpHeaders;\n\n  //contains all the file key in the parts\n  private List<String> fileKeys = new ArrayList<>();\n\n  // gen by httpHeaders\n  private Cookie[] cookies;\n\n  @SuppressWarnings(\"unchecked\")\n  public CommonToHttpServletRequest(Map<String, String> pathParams, Map<String, List<String>> queryParams,\n      Map<String, List<String>> httpHeaders, Object bodyObject, List<String> fileKeys) {\n    setAttribute(RestConst.PATH_PARAMETERS, pathParams);\n    this.fileKeys = fileKeys;\n    setAttribute(RestConst.BODY_PARAMETER, bodyObject);\n\n    this.queryParams = queryParams;\n    this.httpHeaders = httpHeaders;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public CommonToHttpServletRequest(Map<String, String> pathParams, Map<String, List<String>> queryParams,\n      Map<String, List<String>> httpHeaders, Object bodyObject) {\n    this(pathParams, queryParams, httpHeaders, bodyObject, null);\n  }\n\n  @Override\n  public String getContentType() {\n    return getHeader(HttpHeaders.CONTENT_TYPE);\n  }\n\n  // not include form data, only for query\n  @Override\n  public String getParameter(String name) {\n    List<String> queryValues = queryParams.get(name);\n    if (queryValues == null || queryValues.isEmpty()) {\n      return null;\n    }\n\n    return queryValues.get(0);\n  }\n\n  // not include form data, only for query\n  @Override\n  public String[] getParameterValues(String name) {\n    List<String> queryValues = queryParams.get(name);\n    if (queryValues == null || queryValues.isEmpty()) {\n      return new String[0];\n    }\n\n    return queryValues.toArray(new String[0]);\n  }\n\n  @Override\n  public String getHeader(String name) {\n    List<String> headerValues = httpHeaders.get(name);\n    if (headerValues == null || headerValues.isEmpty()) {\n      return null;\n    }\n\n    return headerValues.get(0);\n  }\n\n  @Override\n  public Enumeration<String> getHeaders(String name) {\n    List<String> headerValues = httpHeaders.get(name);\n    if (headerValues == null || headerValues.isEmpty()) {\n      return Collections.emptyEnumeration();\n    }\n\n    return Collections.enumeration(headerValues);\n  }\n\n  @Override\n  public Enumeration<String> getHeaderNames() {\n    return Collections.enumeration(httpHeaders.keySet());\n  }\n\n  @Override\n  public Cookie[] getCookies() {\n    if (cookies == null) {\n      cookies = createCookies();\n    }\n\n    return cookies;\n  }\n\n  private Cookie[] createCookies() {\n    List<String> strCookies = httpHeaders.get(HttpHeaders.COOKIE);\n    if (strCookies == null) {\n      return new Cookie[] {};\n    }\n\n    List<Cookie> result = new ArrayList<>();\n    for (String strCookie : strCookies) {\n      List<HttpCookie> httpCookies = HttpCookie.parse(strCookie);\n      for (HttpCookie httpCookie : httpCookies) {\n        Cookie cookie = new Cookie(httpCookie.getName(), httpCookie.getValue());\n        result.add(cookie);\n      }\n    }\n\n    return result.toArray(new Cookie[0]);\n  }\n\n  @Override\n  public ServletInputStream getInputStream() throws IOException {\n    return null;\n  }\n\n  @Override\n  public void setHeader(String name, String value) {\n    httpHeaders.put(name, Arrays.asList(value));\n  }\n\n  @Override\n  public void addHeader(String name, String value) {\n    List<String> list = httpHeaders.computeIfAbsent(name, key -> new ArrayList<>());\n    list.add(value);\n  }\n\n  @Override\n  public Part getPart(String name) {\n    Object value = findPartInputValue(name);\n    return getSinglePart(name, value);\n  }\n\n  @Override\n  public Collection<Part> getParts() {\n    @SuppressWarnings(\"unchecked\")\n    Map<String, Object> form = (Map<String, Object>) getAttribute(RestConst.BODY_PARAMETER);\n    List<Part> partList = new ArrayList<>();\n    filePartListWithForm(partList, form);\n    return partList;\n  }\n\n  private void filePartListWithForm(List<Part> partList, Map<String, Object> form) {\n    for (String key : fileKeys) {\n      Object value = form.get(key);\n      if (value == null) {\n        continue;\n      }\n      if (Collection.class.isInstance(value)) {\n        Collection<?> collection = (Collection<?>) value;\n        for (Object part : collection) {\n          partList.add(getSinglePart(key, part));\n        }\n        continue;\n      }\n      if (value.getClass().isArray()) {\n        Object[] params = (Object[]) value;\n        for (Object param : params) {\n          partList.add(getSinglePart(key, param));\n        }\n        continue;\n      }\n      partList.add(getSinglePart(key, value));\n    }\n  }\n\n  protected Object findPartInputValue(String name) {\n    @SuppressWarnings(\"unchecked\")\n    Map<String, Object> form = (Map<String, Object>) getAttribute(RestConst.BODY_PARAMETER);\n    Object value = form.get(name);\n    if (value == null) {\n      return null;\n    }\n\n    if (Collection.class.isInstance(value)) {\n      Collection<?> collection = (Collection<?>) value;\n      if (collection.isEmpty()) {\n        return null;\n      }\n\n      value = collection.iterator().next();\n    }\n    return value;\n  }\n\n  @VisibleForTesting\n  public List<String> getFileKeys() {\n    return fileKeys;\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.OutputStream;\nimport java.lang.reflect.Type;\nimport java.net.URI;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.codec.RestCodec;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.common.rest.locator.OperationLocator;\nimport org.apache.servicecomb.common.rest.locator.ServicePathManager;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.core.provider.consumer.MicroserviceReferenceConfig;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.client.ClientHttpRequest;\nimport org.springframework.http.client.ClientHttpResponse;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.netty.handler.codec.http.QueryStringDecoder;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class CseClientHttpRequest implements ClientHttpRequest {\n\n  // URL format：cse://microserviceName/business url\n  private URI uri;\n\n  // business url\n  private String path;\n\n  private HttpMethod method;\n\n  private HttpHeaders httpHeaders = new HttpHeaders();\n\n  private InvocationContext context;\n\n  private Object requestBody;\n\n  private Map<String, List<String>> queryParams;\n\n  private RequestMeta requestMeta;\n\n  private Type responseType;\n\n  public CseClientHttpRequest() {\n  }\n\n  public CseClientHttpRequest(URI uri, HttpMethod method) {\n    this.uri = uri;\n    this.method = method;\n  }\n\n  public String getPath() {\n    return path;\n  }\n\n  public void setPath(String path) {\n    this.path = path;\n  }\n\n  protected RequestMeta getRequestMeta() {\n    return requestMeta;\n  }\n\n  @VisibleForTesting\n  public void setRequestMeta(RequestMeta requestMeta) {\n    this.requestMeta = requestMeta;\n  }\n\n  public void setUri(URI uri) {\n    this.uri = uri;\n  }\n\n  public void setMethod(HttpMethod method) {\n    this.method = method;\n  }\n\n  protected void setQueryParams(Map<String, List<String>> queryParams) {\n    this.queryParams = queryParams;\n  }\n\n  public InvocationContext getContext() {\n    return context;\n  }\n\n  public void setContext(InvocationContext context) {\n    this.context = context;\n  }\n\n  public Type getResponseType() {\n    return responseType;\n  }\n\n  public void setResponseType(Type responseType) {\n    this.responseType = responseType;\n  }\n\n  public void setRequestBody(Object requestBody) {\n    this.requestBody = requestBody;\n  }\n\n  public void setHttpHeaders(HttpHeaders headers) {\n    if (headers != null) {\n      this.httpHeaders = headers;\n    }\n  }\n\n  @Override\n  public HttpMethod getMethod() {\n    return method;\n  }\n\n  @Override\n  public URI getURI() {\n    return uri;\n  }\n\n  @Override\n  public Map<String, Object> getAttributes() {\n    return Collections.emptyMap();\n  }\n\n  @Override\n  public HttpHeaders getHeaders() {\n    return httpHeaders;\n  }\n\n  @Override\n  public OutputStream getBody() {\n    return null;\n  }\n\n  @Override\n  public ClientHttpResponse execute() {\n    path = findUriPath(uri);\n    requestMeta = createRequestMeta(method.name(), uri);\n\n    QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri.getRawSchemeSpecificPart());\n    queryParams = queryStringDecoder.parameters();\n\n    Map<String, Object> swaggerArguments = this.collectArguments();\n\n    // 异常流程，直接抛异常出去\n    return this.invoke(swaggerArguments);\n  }\n\n  protected RequestMeta createRequestMeta(String httpMethod, URI uri) {\n    String microserviceName = parseMicroserviceName(uri);\n\n    MicroserviceReferenceConfig microserviceReferenceConfig = SCBEngine.getInstance()\n        .getOrCreateReferenceConfig(microserviceName);\n    if (microserviceReferenceConfig == null) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR,\n          new CommonExceptionData(String.format(\"Failed to invoke service %s. Maybe service\"\n              + \" not registered or no active instance.\", microserviceName)));\n    }\n    MicroserviceMeta microserviceMeta = microserviceReferenceConfig.getMicroserviceMeta();\n\n    ServicePathManager servicePathManager = ServicePathManager.getServicePathManager(microserviceMeta);\n    if (servicePathManager == null) {\n      throw new Error(String.format(\"no schema defined for %s:%s\",\n          microserviceMeta.getAppId(),\n          microserviceMeta.getMicroserviceName()));\n    }\n\n    OperationLocator locator = servicePathManager.consumerLocateOperation(path, httpMethod);\n    RestOperationMeta swaggerRestOperation = locator.getOperation();\n\n    OperationMeta operationMeta = locator.getOperation().getOperationMeta();\n    ReferenceConfig referenceConfig = microserviceReferenceConfig.createReferenceConfig(operationMeta);\n\n    Map<String, String> pathParams = locator.getPathVarMap();\n    return new RequestMeta(referenceConfig, swaggerRestOperation, pathParams);\n  }\n\n  private String parseMicroserviceName(URI uri) {\n    String microserviceName = uri.getAuthority();\n    return microserviceName.replace(CseUriTemplateHandler.APP_SERVICE_SEPARATOR_INTERNAL,\n        DefinitionConst.APP_SERVICE_SEPARATOR);\n  }\n\n  protected String findUriPath(URI uri) {\n    return uri.getRawPath();\n  }\n\n  protected Invocation prepareInvocation(Map<String, Object> swaggerArguments) {\n    Invocation invocation =\n        InvocationFactory.forConsumer(requestMeta.getReferenceConfig(),\n            requestMeta.getOperationMeta(),\n            requestMeta.getOperationMeta().buildBaseConsumerRuntimeType(),\n            swaggerArguments);\n\n    invocation.getHandlerContext().put(RestConst.REST_CLIENT_REQUEST_PATH,\n        path + (this.uri.getRawQuery() == null ? \"\" : \"?\" + this.uri.getRawQuery()));\n\n    if (context != null) {\n      invocation.addContext(context.getContext());\n      invocation.addLocalContext(context.getLocalContext());\n    }\n\n    if (responseType != null &&\n        !(responseType instanceof Class && Part.class.isAssignableFrom((Class<?>) responseType))) {\n      invocation.setSuccessResponseType(TypeFactory.defaultInstance().constructType(responseType));\n    }\n\n    invocation.getHandlerContext().put(RestConst.CONSUMER_HEADER, httpHeaders.toSingleValueMap());\n    return invocation;\n  }\n\n  @VisibleForTesting\n  CseClientHttpResponse invoke(Map<String, Object> swaggerArguments) {\n    Invocation invocation = prepareInvocation(swaggerArguments);\n    Response response = doInvoke(invocation);\n\n    if (response.isSucceed()) {\n      return new CseClientHttpResponse(response);\n    }\n\n    throw ExceptionFactory.convertConsumerException(response.getResult());\n  }\n\n  protected Response doInvoke(Invocation invocation) {\n    return InvokerUtils.innerSyncInvoke(invocation);\n  }\n\n  protected Map<String, Object> collectArguments() {\n    HttpServletRequest mockRequest = new CommonToHttpServletRequest(requestMeta.getPathParams(), queryParams,\n        httpHeaders, requestBody,\n        requestMeta.getSwaggerRestOperation().getFileKeys());\n    // no types info, so will not convert any parameters\n    return RestCodec.restToArgs(mockRequest, requestMeta.getSwaggerRestOperation());\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.net.URI;\n\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.client.ClientHttpRequest;\nimport org.springframework.http.client.ClientHttpRequestFactory;\n\npublic class CseClientHttpRequestFactory implements ClientHttpRequestFactory {\n  @Override\n  public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {\n    return new CseClientHttpRequest(uri, httpMethod);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.client.ClientHttpResponse;\n\nimport io.vertx.core.MultiMap;\n\n/**\n * cse应答在transport层已经完成了码流到对象的转换\n * 这里是适配springmvc的机制，让调用者能拿到已经转换好的对象\n */\npublic class CseClientHttpResponse implements ClientHttpResponse {\n  // 让springmvc client以为应答有body\n  // mark、reset都是有锁的，这里通过重写取消了锁\n  private static final InputStream BODY_INPUT_STREAM = new InputStream() {\n    @Override\n    public boolean markSupported() {\n      return true;\n    }\n\n    @Override\n    public void mark(int readlimit) {\n    }\n\n    @Override\n    public int read() throws IOException {\n      return 0;\n    }\n\n    @Override\n    public void reset() throws IOException {\n    }\n  };\n\n  private final Response response;\n\n  private HttpHeaders httpHeaders;\n\n  public CseClientHttpResponse(Response response) {\n    this.response = response;\n  }\n\n  public Object getResult() {\n    return response.getResult();\n  }\n\n  @Override\n  public InputStream getBody() throws IOException {\n    return BODY_INPUT_STREAM;\n  }\n\n  @Override\n  public HttpHeaders getHeaders() {\n    if (httpHeaders == null) {\n      HttpHeaders tmpHeaders = new HttpHeaders();\n      MultiMap headers = response.getHeaders();\n      if (headers != null) {\n        for (Entry<String, String> entry : headers.entries()) {\n          tmpHeaders.add(entry.getKey(), entry.getValue());\n        }\n      }\n\n      httpHeaders = tmpHeaders;\n    }\n    return httpHeaders;\n  }\n\n  @Override\n  public HttpStatus getStatusCode() throws IOException {\n    return HttpStatus.valueOf(response.getStatusCode());\n  }\n\n  @Override\n  @Deprecated(since = \"6.0\")\n  @SuppressWarnings(\"deprecations\")\n  public int getRawStatusCode() throws IOException {\n    return response.getStatusCode();\n  }\n\n  @Override\n  public String getStatusText() throws IOException {\n    return response.getReasonPhrase();\n  }\n\n  @Override\n  public void close() {\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpEntity.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.util.MultiValueMap;\n\npublic class CseHttpEntity<T> extends HttpEntity<T> {\n\n  private InvocationContext context;\n\n  public CseHttpEntity(T body) {\n    super(body);\n  }\n\n  public CseHttpEntity(MultiValueMap<String, String> headers) {\n    super(headers);\n  }\n\n  public CseHttpEntity(T body, MultiValueMap<String, String> headers) {\n    super(body, headers);\n  }\n\n  /**\n   * 获取context的值\n   * @return 返回 context\n   */\n  public InvocationContext getContext() {\n    return context;\n  }\n\n  /**\n   * 对context进行赋值\n   * @param context context的新值\n   */\n  public void setContext(InvocationContext context) {\n    this.context = context;\n  }\n\n  public void addContext(String key, String value) {\n    if (context == null) {\n      context = new InvocationContext();\n    }\n\n    context.addContext(key, value);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.springframework.http.HttpInputMessage;\nimport org.springframework.http.HttpOutputMessage;\nimport org.springframework.http.MediaType;\nimport org.springframework.http.converter.GenericHttpMessageConverter;\nimport org.springframework.http.converter.HttpMessageNotReadableException;\nimport org.springframework.http.converter.HttpMessageNotWritableException;\nimport org.springframework.lang.Nullable;\n\npublic class CseHttpMessageConverter implements GenericHttpMessageConverter<Object> {\n\n  private static final List<MediaType> ALL_MEDIA_TYPE = Arrays.asList(MediaType.ALL);\n\n  @Override\n  public boolean canRead(Class<?> clazz, MediaType mediaType) {\n    return true;\n  }\n\n  @Override\n  public boolean canWrite(Class<?> clazz, MediaType mediaType) {\n    return true;\n  }\n\n  @Override\n  public List<MediaType> getSupportedMediaTypes() {\n    return ALL_MEDIA_TYPE;\n  }\n\n  @Override\n  public Object read(Class<?> clazz, HttpInputMessage inputMessage) throws HttpMessageNotReadableException {\n    throw new IllegalStateException(\"not supported\");\n  }\n\n  private Object read(HttpInputMessage inputMessage) {\n    throw new IllegalStateException(\"not supported\");\n  }\n\n  @Override\n  public void write(Object o, MediaType contentType,\n      HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {\n    write(o, outputMessage);\n  }\n\n  private void write(Object o, HttpOutputMessage outputMessage) {\n    CseClientHttpRequest request = (CseClientHttpRequest) outputMessage;\n    request.setRequestBody(o);\n  }\n\n  @Override\n  public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {\n    return true;\n  }\n\n  @Override\n  public Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)\n      throws IOException, HttpMessageNotReadableException {\n    throw new IllegalStateException(\"not supported\");\n  }\n\n  @Override\n  public boolean canWrite(@Nullable Type type, Class<?> clazz, @Nullable MediaType mediaType) {\n    return true;\n  }\n\n  @Override\n  public void write(Object o, @Nullable Type type, @Nullable MediaType contentType, HttpOutputMessage outputMessage)\n      throws IOException, HttpMessageNotWritableException {\n    write(o, outputMessage);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseHttpMessageConverterExtractor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\n\nimport org.springframework.http.client.ClientHttpResponse;\nimport org.springframework.web.client.ResponseExtractor;\n\npublic class CseHttpMessageConverterExtractor<T> implements ResponseExtractor<T> {\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public T extractData(ClientHttpResponse response) throws IOException {\n    return (T) ((CseClientHttpResponse) response).getResult();\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseRequestCallback.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.foundation.common.utils.GenericsUtils;\nimport org.springframework.http.client.ClientHttpRequest;\nimport org.springframework.web.client.RequestCallback;\n\npublic class CseRequestCallback implements RequestCallback {\n  private final Object requestBody;\n\n  private final RequestCallback targetCallback;\n\n  private final Type responseType;\n\n  public CseRequestCallback(Object requestBody, RequestCallback targetCallback, Type responseType) {\n    this.requestBody = requestBody;\n    this.targetCallback = targetCallback;\n    this.responseType = responseType;\n  }\n\n  /**\n   * {@inheritDoc}\n   */\n  @Override\n  public void doWithRequest(ClientHttpRequest request) throws IOException {\n    targetCallback.doWithRequest(request);\n    CseClientHttpRequest req = (CseClientHttpRequest) request;\n    req.setResponseType(overrideResponseType());\n\n    if (!CseHttpEntity.class.isInstance(requestBody)) {\n      return;\n    }\n\n    CseHttpEntity<?> entity = (CseHttpEntity<?>) requestBody;\n    req.setContext(entity.getContext());\n  }\n\n  private Type overrideResponseType() {\n    if (GenericsUtils.isGenericResponseType(responseType)) {\n      // code: List<GenericObjectParam> response = restTemplate\n      //    .postForObject(\"/testListObjectParam\", request, List.class);\n      // will using server schema type to deserialize\n      return null;\n    }\n    // code: MyObject response = .postForObject(\"/testListObjectParam\", request, MyObject.class);\n    return responseType;\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseResponseEntityResponseExtractor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\n\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.http.client.ClientHttpResponse;\nimport org.springframework.lang.Nullable;\nimport org.springframework.web.client.ResponseExtractor;\n\npublic class CseResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {\n  @Nullable\n  private final CseHttpMessageConverterExtractor<T> delegate;\n\n  public CseResponseEntityResponseExtractor(@Nullable Type responseType) {\n    if (responseType != null && Void.class != responseType) {\n      this.delegate = new CseHttpMessageConverterExtractor<>();\n    } else {\n      this.delegate = null;\n    }\n  }\n\n  @Override\n  public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {\n    if (this.delegate != null) {\n      T body = this.delegate.extractData(response);\n      return ResponseEntity.status(response.getStatusCode().value()).headers(response.getHeaders()).body(body);\n    } else {\n      return ResponseEntity.status(response.getStatusCode().value()).headers(response.getHeaders()).build();\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseRestTemplate.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.lang.reflect.Type;\nimport java.net.URI;\nimport java.util.Arrays;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.lang.Nullable;\nimport org.springframework.web.client.RequestCallback;\nimport org.springframework.web.client.ResponseExtractor;\nimport org.springframework.web.client.RestClientException;\n\npublic class CseRestTemplate extends AcceptableRestTemplate {\n  public CseRestTemplate() {\n    setMessageConverters(Arrays.asList(new CseHttpMessageConverter()));\n    setRequestFactory(new CseClientHttpRequestFactory());\n    setUriTemplateHandler(new CseUriTemplateHandler());\n  }\n\n  // GET\n\n  @Override\n  @Nullable\n  public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {\n    RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);\n  }\n\n  @Override\n  @Nullable\n  public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {\n    RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);\n  }\n\n  @Override\n  @Nullable\n  public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException {\n    RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.GET, requestCallback, responseExtractor);\n  }\n\n  // HEAD\n  // no override\n\n  // POST\n\n  @Override\n  @Nullable\n  public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,\n      Object... uriVariables) throws RestClientException {\n\n    RequestCallback requestCallback = httpEntityCallback(request, responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);\n  }\n\n  @Override\n  @Nullable\n  public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,\n      Map<String, ?> uriVariables) throws RestClientException {\n\n    RequestCallback requestCallback = httpEntityCallback(request, responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);\n  }\n\n  @Override\n  @Nullable\n  public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType)\n      throws RestClientException {\n\n    RequestCallback requestCallback = httpEntityCallback(request, responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.POST, requestCallback, responseExtractor);\n  }\n\n  // PUT\n  // no override\n\n  // PATCH\n\n  @Override\n  @Nullable\n  public <T> T patchForObject(String url, @Nullable Object request, Class<T> responseType,\n      Object... uriVariables) throws RestClientException {\n\n    RequestCallback requestCallback = httpEntityCallback(request, responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);\n  }\n\n  @Override\n  @Nullable\n  public <T> T patchForObject(String url, @Nullable Object request, Class<T> responseType,\n      Map<String, ?> uriVariables) throws RestClientException {\n\n    RequestCallback requestCallback = httpEntityCallback(request, responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);\n  }\n\n  @Override\n  @Nullable\n  public <T> T patchForObject(URI url, @Nullable Object request, Class<T> responseType)\n      throws RestClientException {\n\n    RequestCallback requestCallback = httpEntityCallback(request, responseType);\n    CseHttpMessageConverterExtractor<T> responseExtractor =\n        new CseHttpMessageConverterExtractor<>();\n    return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor);\n  }\n\n  // DELETE\n  // no override\n\n  // OPTIONS\n  // no override\n\n  // exchange\n  // no override\n\n  @Override\n  public <T> ResponseExtractor<ResponseEntity<T>> responseEntityExtractor(Type responseType) {\n    return new CseResponseEntityResponseExtractor<>(responseType);\n  }\n\n  @Override\n  public <T> RequestCallback httpEntityCallback(Object requestBody) {\n    RequestCallback callback = super.httpEntityCallback(requestBody);\n    CseRequestCallback cseCallback = new CseRequestCallback(requestBody, callback, null);\n    return cseCallback;\n  }\n\n  @Override\n  public <T> RequestCallback httpEntityCallback(Object requestBody, Type responseType) {\n    RequestCallback callback = super.httpEntityCallback(requestBody, responseType);\n    CseRequestCallback cseCallback = new CseRequestCallback(requestBody, callback, responseType);\n    return cseCallback;\n  }\n\n  @Override\n  public <T> RequestCallback acceptHeaderRequestCallback(Class<T> responseType) {\n    RequestCallback callback = super.acceptHeaderRequestCallback(responseType);\n    CseRequestCallback cseCallback = new CseRequestCallback(null, callback, responseType);\n    return cseCallback;\n  }\n\n  @Override\n  public boolean isAcceptable(String uri) {\n    return uri.startsWith(RestConst.URI_PREFIX) || uri.startsWith(RestConst.URI_PREFIX_NEW);\n  }\n\n  @Override\n  public boolean isAcceptable(URI uri) {\n    return RestConst.SCHEME.equals(uri.getScheme()) || RestConst.SCHEME_NEW.equals(uri.getScheme());\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseUriTemplateHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.net.URI;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.springframework.web.util.DefaultUriBuilderFactory;\n\npublic class CseUriTemplateHandler extends DefaultUriBuilderFactory {\n  // Must be one of URI unreserved  `ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"`\n  public static final String APP_SERVICE_SEPARATOR_INTERNAL = \"~\";\n\n  public CseUriTemplateHandler() {\n  }\n\n  @Override\n  public URI expand(String uriTemplate, Map<String, ?> uriVars) {\n    return super.expand(parseUrl(uriTemplate), uriVars);\n  }\n\n  @Override\n  public URI expand(String uriTemplate, Object... uriVars) {\n    return super.expand(parseUrl(uriTemplate), uriVars);\n  }\n\n  private static String parseUrl(String uriTemplate) {\n    int indexSchema = -1;\n    if (uriTemplate.startsWith(RestConst.URI_PREFIX)) {\n      indexSchema = RestConst.URI_PREFIX.length();\n    }\n    if (uriTemplate.startsWith(RestConst.URI_PREFIX_NEW)) {\n      indexSchema = RestConst.URI_PREFIX_NEW.length();\n    }\n    if (indexSchema != -1) {\n      int indexPath = uriTemplate.indexOf(\"/\", indexSchema);\n      String host = uriTemplate.substring(indexSchema, indexPath);\n      host = host.replace(DefinitionConst.APP_SERVICE_SEPARATOR, APP_SERVICE_SEPARATOR_INTERNAL);\n      return uriTemplate.substring(0, indexSchema) + host + uriTemplate.substring(indexPath);\n    }\n    return uriTemplate;\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/RequestMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\n\n/**\n * 封装每一次调用的元数据\n */\npublic class RequestMeta {\n  private final ReferenceConfig referenceConfig;\n\n  private final OperationMeta operationMeta;\n\n  private final RestOperationMeta swaggerRestOperation;\n\n  private final Map<String, String> pathParams;\n\n  public RequestMeta(ReferenceConfig referenceConfig, RestOperationMeta swaggerRestOperation,\n      Map<String, String> pathParams) {\n    this.referenceConfig = referenceConfig;\n    this.operationMeta = swaggerRestOperation.getOperationMeta();\n    this.swaggerRestOperation = swaggerRestOperation;\n    this.pathParams = pathParams;\n  }\n\n  public ReferenceConfig getReferenceConfig() {\n    return referenceConfig;\n  }\n\n  public Map<String, String> getPathParams() {\n    return pathParams;\n  }\n\n  public RestOperationMeta getSwaggerRestOperation() {\n    return swaggerRestOperation;\n  }\n\n  public OperationMeta getOperationMeta() {\n    return operationMeta;\n  }\n\n  public String getOperationQualifiedName() {\n    return operationMeta.getSchemaQualifiedName();\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/RestTemplateBuilder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport org.springframework.web.client.RestOperations;\n\npublic final class RestTemplateBuilder {\n  private static final RestTemplateWrapper wrapper = new RestTemplateWrapper();\n\n  private RestTemplateBuilder() {\n  }\n\n  public static RestOperations create() {\n    return wrapper;\n  }\n\n  public static void addAcceptableRestTemplate(int index, AcceptableRestTemplate restTemplate) {\n    wrapper.addAcceptableRestTemplate(index, restTemplate);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/RestTemplateWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.springframework.core.ParameterizedTypeReference;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.RequestEntity;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.http.client.ClientHttpRequestFactory;\nimport org.springframework.http.client.ClientHttpRequestInterceptor;\nimport org.springframework.http.converter.HttpMessageConverter;\nimport org.springframework.web.client.RequestCallback;\nimport org.springframework.web.client.ResponseErrorHandler;\nimport org.springframework.web.client.ResponseExtractor;\nimport org.springframework.web.client.RestClientException;\nimport org.springframework.web.client.RestTemplate;\nimport org.springframework.web.util.UriTemplateHandler;\n\n/**\n * Wrapper class to support java chassis invocation and non java chassis invocation.\n */\nclass RestTemplateWrapper extends RestTemplate {\n  private final List<AcceptableRestTemplate> acceptableRestTemplates = new ArrayList<>();\n\n  final RestTemplate defaultRestTemplate = new RestTemplate();\n\n  RestTemplateWrapper() {\n    acceptableRestTemplates.add(new CseRestTemplate());\n  }\n\n  void addAcceptableRestTemplate(int index, AcceptableRestTemplate restTemplate) {\n    acceptableRestTemplates.add(index, restTemplate);\n  }\n\n  RestTemplate getRestTemplate(String url) {\n    for (AcceptableRestTemplate template : acceptableRestTemplates) {\n      if (template.isAcceptable(url)) {\n        return template;\n      }\n    }\n    return defaultRestTemplate;\n  }\n\n  RestTemplate getRestTemplate(URI uri) {\n    for (AcceptableRestTemplate template : acceptableRestTemplates) {\n      if (template.isAcceptable(uri)) {\n        return template;\n      }\n    }\n    return defaultRestTemplate;\n  }\n\n  @Override\n  public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException {\n    return getRestTemplate(url).getForObject(url, responseType, urlVariables);\n  }\n\n  @Override\n  public <T> T getForObject(String url, Class<T> responseType,\n      Map<String, ?> urlVariables) throws RestClientException {\n    return getRestTemplate(url).getForObject(url, responseType, urlVariables);\n  }\n\n  @Override\n  public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException {\n    return getRestTemplate(url).getForObject(url, responseType);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType,\n      Object... urlVariables) throws RestClientException {\n    return getRestTemplate(url).getForEntity(url, responseType, urlVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType,\n      Map<String, ?> urlVariables) throws RestClientException {\n    return getRestTemplate(url).getForEntity(url, responseType, urlVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException {\n    return getRestTemplate(url).getForEntity(url, responseType);\n  }\n\n  @Override\n  public <T> T postForObject(String url, Object request, Class<T> responseType,\n      Object... uriVariables) throws RestClientException {\n    return getRestTemplate(url).postForObject(url, request, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> T postForObject(String url, Object request, Class<T> responseType,\n      Map<String, ?> uriVariables) throws RestClientException {\n    return getRestTemplate(url).postForObject(url, request, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException {\n    return getRestTemplate(url).postForObject(url, request, responseType);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType,\n      Object... uriVariables) throws RestClientException {\n    return getRestTemplate(url).postForEntity(url, request, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType,\n      Map<String, ?> uriVariables) throws RestClientException {\n    return getRestTemplate(url).postForEntity(url, request, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> postForEntity(URI url, Object request,\n      Class<T> responseType) throws RestClientException {\n    return getRestTemplate(url).postForEntity(url, request, responseType);\n  }\n\n  @Override\n  public void put(String url, Object request, Object... urlVariables) throws RestClientException {\n    getRestTemplate(url).put(url, request, urlVariables);\n  }\n\n  @Override\n  public void put(String url, Object request, Map<String, ?> urlVariables) throws RestClientException {\n    getRestTemplate(url).put(url, request, urlVariables);\n  }\n\n  @Override\n  public void put(URI url, Object request) throws RestClientException {\n    getRestTemplate(url).put(url, request);\n  }\n\n  @Override\n  public void delete(String url, Object... urlVariables) throws RestClientException {\n    getRestTemplate(url).delete(url, urlVariables);\n  }\n\n  @Override\n  public void delete(String url, Map<String, ?> urlVariables) throws RestClientException {\n    getRestTemplate(url).delete(url, urlVariables);\n  }\n\n  @Override\n  public void delete(URI url) throws RestClientException {\n    getRestTemplate(url).delete(url);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,\n      Class<T> responseType, Object... uriVariables) throws RestClientException {\n    return getRestTemplate(url).exchange(url, method, requestEntity, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,\n      ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables) throws RestClientException {\n    return getRestTemplate(url).exchange(url, method, requestEntity, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,\n      Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {\n    return getRestTemplate(url).exchange(url, method, requestEntity, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,\n      ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException {\n    return getRestTemplate(url).exchange(url, method, requestEntity, responseType, uriVariables);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity,\n      Class<T> responseType) throws RestClientException {\n    return getRestTemplate(requestEntity.getUrl()).exchange(requestEntity, responseType);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity,\n      ParameterizedTypeReference<T> responseType) throws RestClientException {\n    return getRestTemplate(requestEntity.getUrl()).exchange(requestEntity, responseType);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,\n      Class<T> responseType) throws RestClientException {\n    return getRestTemplate(url).exchange(url, method, requestEntity, responseType);\n  }\n\n  @Override\n  public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,\n      ParameterizedTypeReference<T> responseType) throws RestClientException {\n    return getRestTemplate(url).exchange(url, method, requestEntity, responseType);\n  }\n\n  @Override\n  public HttpHeaders headForHeaders(String url, Object... urlVariables) throws RestClientException {\n    return getRestTemplate(url).headForHeaders(url, urlVariables);\n  }\n\n  @Override\n  public HttpHeaders headForHeaders(String url, Map<String, ?> urlVariables) throws RestClientException {\n    return getRestTemplate(url).headForHeaders(url, urlVariables);\n  }\n\n  @Override\n  public HttpHeaders headForHeaders(URI url) throws RestClientException {\n    return getRestTemplate(url).headForHeaders(url);\n  }\n\n  @Override\n  public URI postForLocation(String url, Object request, Object... urlVariables) throws RestClientException {\n    return getRestTemplate(url).postForLocation(url, request, urlVariables);\n  }\n\n  @Override\n  public URI postForLocation(String url, Object request, Map<String, ?> urlVariables) throws RestClientException {\n    return getRestTemplate(url).postForLocation(url, request, urlVariables);\n  }\n\n  @Override\n  public URI postForLocation(URI url, Object request) throws RestClientException {\n    return getRestTemplate(url).postForLocation(url, request);\n  }\n\n  @Override\n  public Set<HttpMethod> optionsForAllow(String url, Object... urlVariables) throws RestClientException {\n    return getRestTemplate(url).optionsForAllow(url, urlVariables);\n  }\n\n  @Override\n  public Set<HttpMethod> optionsForAllow(String url, Map<String, ?> urlVariables) throws RestClientException {\n    return getRestTemplate(url).optionsForAllow(url, urlVariables);\n  }\n\n  @Override\n  public Set<HttpMethod> optionsForAllow(URI url) throws RestClientException {\n    return getRestTemplate(url).optionsForAllow(url);\n  }\n\n  @Override\n  public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,\n      ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {\n    return getRestTemplate(url).execute(url, method, requestCallback, responseExtractor, urlVariables);\n  }\n\n  @Override\n  public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,\n      ResponseExtractor<T> responseExtractor, Map<String, ?> urlVariables) throws RestClientException {\n    return getRestTemplate(url).execute(url, method, requestCallback, responseExtractor, urlVariables);\n  }\n\n  @Override\n  public <T> T execute(URI url, HttpMethod method, RequestCallback requestCallback,\n      ResponseExtractor<T> responseExtractor) throws RestClientException {\n    return getRestTemplate(url).execute(url, method, requestCallback, responseExtractor);\n  }\n\n  @Override\n  public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) {\n    super.setInterceptors(interceptors);\n    defaultRestTemplate.setInterceptors(interceptors);\n  }\n\n  @Override\n  public void setRequestFactory(ClientHttpRequestFactory requestFactory) {\n    super.setRequestFactory(requestFactory);\n    defaultRestTemplate.setRequestFactory(requestFactory);\n  }\n\n  @Override\n  public void setErrorHandler(ResponseErrorHandler errorHandler) {\n    super.setErrorHandler(errorHandler);\n    acceptableRestTemplates.forEach(template -> template.setErrorHandler(errorHandler));\n    defaultRestTemplate.setErrorHandler(errorHandler);\n  }\n\n  @Override\n  public void setDefaultUriVariables(Map<String, ?> defaultUriVariables) {\n    super.setDefaultUriVariables(defaultUriVariables);\n    acceptableRestTemplates.forEach(template -> template.setDefaultUriVariables(defaultUriVariables));\n    defaultRestTemplate.setDefaultUriVariables(defaultUriVariables);\n  }\n\n  @Override\n  public void setUriTemplateHandler(UriTemplateHandler handler) {\n    super.setUriTemplateHandler(handler);\n    defaultRestTemplate.setUriTemplateHandler(handler);\n  }\n\n  @Override\n  public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {\n    super.setMessageConverters(messageConverters);\n    defaultRestTemplate.setMessageConverters(messageConverters);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/ServiceCombRestTemplateConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.web.client.RestOperations;\n\n@Configuration\nclass ServiceCombRestTemplateConfig {\n  @Bean\n  RestOperations restTemplate() {\n    return RestTemplateBuilder.create();\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/UrlWithProviderPrefixClientHttpRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.net.URI;\n\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.client.ClientHttpRequest;\nimport org.springframework.http.client.ClientHttpRequestFactory;\n\n/**\n * When deploying in a container, like tomcat, users want to invoke service with full path, including container context\n * root and servlet path.\n */\npublic class UrlWithProviderPrefixClientHttpRequestFactory implements ClientHttpRequestFactory {\n  static class UrlWithProviderPrefixClientHttpRequest extends CseClientHttpRequest {\n    private final String prefix;\n\n    public UrlWithProviderPrefixClientHttpRequest(URI uri, HttpMethod httpMethod, String prefix) {\n      super(uri, httpMethod);\n      this.prefix = prefix;\n    }\n\n    @Override\n    protected String findUriPath(URI uri) {\n      return uri.getRawPath().substring(prefix.length());\n    }\n  }\n\n  private final String prefix;\n\n  public UrlWithProviderPrefixClientHttpRequestFactory(String prefix) {\n    this.prefix = prefix;\n  }\n\n  @Override\n  public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {\n    return new UrlWithProviderPrefixClientHttpRequest(uri, httpMethod, prefix);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/UrlWithServiceNameClientHttpRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.net.URI;\n\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.client.ClientHttpRequest;\nimport org.springframework.http.client.ClientHttpRequestFactory;\n\n// URL format：cse://business url\n// business url first part is microserviceName\npublic class UrlWithServiceNameClientHttpRequestFactory implements ClientHttpRequestFactory {\n  static class UrlWithServiceNameClientHttpRequest extends CseClientHttpRequest {\n    public UrlWithServiceNameClientHttpRequest(URI uri, HttpMethod httpMethod) {\n      super(uri, httpMethod);\n    }\n\n    @Override\n    protected String findUriPath(URI uri) {\n      return \"/\" + uri.getAuthority() + uri.getRawPath();\n    }\n  }\n\n  @Override\n  public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {\n    return new UrlWithServiceNameClientHttpRequest(uri, httpMethod);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/ServiceCombRestTemplateConfigTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport static org.hamcrest.core.IsInstanceOf.instanceOf;\n\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.web.client.RestOperations;\n\npublic class ServiceCombRestTemplateConfigTest {\n\n  private final ServiceCombRestTemplateConfig config = new ServiceCombRestTemplateConfig();\n\n  @Test\n  public void exposesServiceCombRestTemplate() {\n    RestOperations restTemplate = config.restTemplate();\n\n    MatcherAssert.assertThat(restTemplate, instanceOf(RestTemplateWrapper.class));\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCommonToHttpServletRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\n\npublic class TestCommonToHttpServletRequest {\n  @Test\n  public void testConstructFormTrue() {\n    Map<String, Object> forms = new HashMap<>();\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, null, forms);\n\n    Assertions.assertEquals(forms, request.getAttribute(RestConst.BODY_PARAMETER));\n  }\n\n  @Test\n  public void testConstructFormFalse() {\n    Object body = new Object();\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, null, body);\n\n    Assertions.assertEquals(body, request.getAttribute(RestConst.BODY_PARAMETER));\n  }\n\n  @Test\n  public void testConstructNormal() {\n    List<String> fileKeys = new ArrayList<>();\n    fileKeys.add(\"test1\");\n    fileKeys.add(\"test2\");\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, null, null, fileKeys);\n    Assertions.assertEquals(2, ((CommonToHttpServletRequest) request).getFileKeys().size());\n    Assertions.assertEquals(\"test1\", ((CommonToHttpServletRequest) request).getFileKeys().get(0));\n    Assertions.assertEquals(\"test2\", ((CommonToHttpServletRequest) request).getFileKeys().get(1));\n  }\n\n  @Test\n  public void testConstructPath() {\n    Map<String, String> pathParams = new HashMap<>();\n    HttpServletRequest request = new CommonToHttpServletRequest(pathParams, null, null, null);\n\n    Assertions.assertEquals(pathParams, request.getAttribute(RestConst.PATH_PARAMETERS));\n  }\n\n  @Test\n  public void testGetContentType() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(HttpHeaders.CONTENT_TYPE, Arrays.asList(\"json\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertEquals(\"json\", request.getContentType());\n  }\n\n  @Test\n  public void testGetParameterNormal() {\n    Map<String, List<String>> queryParams = new HashMap<>();\n    queryParams.put(\"name\", Arrays.asList(\"value\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, queryParams, null, null);\n    Assertions.assertEquals(\"value\", request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterEmpty() {\n    Map<String, List<String>> queryParams = new HashMap<>();\n    queryParams.put(\"name\", Arrays.asList());\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, queryParams, null, null);\n    Assertions.assertNull(request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterNull() {\n    Map<String, List<String>> queryParams = new HashMap<>();\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, queryParams, null, null);\n    Assertions.assertNull(request.getParameter(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterValuesNormal() {\n    Map<String, List<String>> queryParams = new HashMap<>();\n    queryParams.put(\"name\", Arrays.asList(\"value\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, queryParams, null, null);\n    MatcherAssert.assertThat(request.getParameterValues(\"name\"), Matchers.arrayContaining(\"value\"));\n  }\n\n  @Test\n  public void testGetParameterValuesEmpty() {\n    Map<String, List<String>> queryParams = new HashMap<>();\n    queryParams.put(\"name\", Arrays.asList());\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, queryParams, null, null);\n    Assertions.assertArrayEquals(new String[0], request.getParameterValues(\"name\"));\n  }\n\n  @Test\n  public void testGetParameterValuesNull() {\n    Map<String, List<String>> queryParams = new HashMap<>();\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, queryParams, null, null);\n    Assertions.assertArrayEquals(new String[0], request.getParameterValues(\"name\"));\n  }\n\n  @Test\n  public void testGetHeaderNormal() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(\"name\", Arrays.asList(\"value\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertEquals(\"value\", request.getHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetHeaderEmpty() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(\"name\", Arrays.asList());\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertNull(request.getHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetHeaderNamesNormal() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(\"name\", Arrays.asList(\"value\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    MatcherAssert.assertThat(Collections.list(request.getHeaderNames()), Matchers.contains(\"name\"));\n  }\n\n  @Test\n  public void testGetHeaderNamesEmpty() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertFalse(request.getHeaderNames().hasMoreElements());\n  }\n\n  @Test\n  public void testGetHeaderNull() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertNull(request.getHeader(\"name\"));\n  }\n\n  @Test\n  public void testGetHeadersNormal() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(\"name\", Arrays.asList(\"value\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    MatcherAssert.assertThat(Collections.list(request.getHeaders(\"name\")), Matchers.contains(\"value\"));\n  }\n\n  @Test\n  public void testGetHeadersEmpty() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(\"name\", Arrays.asList());\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertFalse(request.getHeaders(\"name\").hasMoreElements());\n  }\n\n  @Test\n  public void testGetHeadersNull() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertFalse(request.getHeaders(\"name\").hasMoreElements());\n  }\n\n  @Test\n  public void testGetCookiesNull() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Assertions.assertEquals(0, request.getCookies().length);\n  }\n\n  @Test\n  public void testGetCookiesNormal() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    httpHeaders.put(HttpHeaders.COOKIE, Arrays.asList(\"k1=v1;k2=v2;\"));\n\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    Cookie[] cookies = request.getCookies();\n    Assertions.assertSame(cookies, request.getCookies());\n    Assertions.assertEquals(1, cookies.length);\n    Assertions.assertEquals(\"k1\", cookies[0].getName());\n    Assertions.assertEquals(\"v1\", cookies[0].getValue());\n  }\n\n  @Test\n  public void testGetInputStream() throws IOException {\n    HttpServletRequest request = new CommonToHttpServletRequest(null, null, null, null);\n    Assertions.assertNull(request.getInputStream());\n  }\n\n  @Test\n  public void testSetHeader() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    HttpServletRequestEx request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    request.setHeader(\"name\", \"v1\");\n    request.setHeader(\"name\", \"v2\");\n    Assertions.assertEquals(\"v2\", request.getHeader(\"name\"));\n  }\n\n  @Test\n  public void testAddHeader() {\n    Map<String, List<String>> httpHeaders = new HashMap<>();\n    HttpServletRequestEx request = new CommonToHttpServletRequest(null, null, httpHeaders, null);\n    request.addHeader(\"name\", \"v1\");\n    request.addHeader(\"name\", \"v2\");\n    MatcherAssert.assertThat(Collections.list(request.getHeaders(\"name\")), Matchers.contains(\"v1\", \"v2\"));\n  }\n\n  @Test\n  public void testGetParts() {\n    List<String> restParams = new ArrayList<>();\n    restParams.add(\"test1\");\n    restParams.add(\"test2\");\n    File file1 = new File(\"file1.txt\");\n    File file2 = new File(\"file2.txt\");\n    File[] files = {file1, file2};\n    List<File> list = Arrays.asList(files);\n    Map<String, Object> objectMap = new HashMap<>();\n    objectMap.put(\"test1\", list);\n    objectMap.put(\"test2\", files);\n    objectMap.put(\"test3\", list);\n    objectMap.put(\"test4\", \"haha\");\n\n    Map<String, String> pathParams = new HashMap<>();\n    HttpServletRequest request = new CommonToHttpServletRequest(pathParams, null, null, objectMap, restParams);\n    try {\n      Collection<Part> tmpParts = request.getParts();\n      ArrayList<Part> parts = new ArrayList<>(tmpParts);\n      Assertions.assertEquals(4, parts.size());\n      Assertions.assertEquals(\"test1\", parts.get(0).getName());\n      Assertions.assertEquals(\"test1\", parts.get(1).getName());\n      Assertions.assertEquals(\"test2\", parts.get(2).getName());\n      Assertions.assertEquals(\"test2\", parts.get(3).getName());\n    } catch (Throwable e) {\n      Assertions.fail(\"should not throw exception\");\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCseClientHttpRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.net.URI;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.http.HttpMethod;\n\npublic class TestCseClientHttpRequestFactory {\n\n  @Test\n  public void testCseClientHttpRequestFactory() {\n\n    CseClientHttpRequestFactory lCseClientHttpRequestFactory = new CseClientHttpRequestFactory();\n    try {\n      Assertions.assertEquals(HttpMethod.GET,\n          lCseClientHttpRequestFactory.createRequest(URI.create(\"/test\"), HttpMethod.GET).getMethod());\n    } catch (IOException e) {\n      Assertions.assertNotNull(e);\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCseClientHttpResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.http.HttpStatus;\n\npublic class TestCseClientHttpResponse {\n  private Object result;\n\n  Response response = Response.ok(result);\n\n  CseClientHttpResponse cseclientrequest = new CseClientHttpResponse(response);\n\n  @Test\n  public void testGetResult() {\n    Assertions.assertNull(cseclientrequest.getResult());\n  }\n\n  @Test\n  public void testGetBody() throws IOException {\n    Assertions.assertNotNull(cseclientrequest.getBody());\n  }\n\n  @Test\n  public void testGetHeaders() {\n    Assertions.assertNotNull(cseclientrequest.getHeaders());\n  }\n\n  @Test\n  public void testGetStatusCode() throws IOException {\n    Assertions.assertEquals(HttpStatus.OK, cseclientrequest.getStatusCode());\n  }\n\n  @Test\n  public void testGetRawStatusCode() throws IOException {\n    Assertions.assertEquals(200, cseclientrequest.getRawStatusCode());\n  }\n\n  @Test\n  public void testGetStatusText() throws IOException {\n    cseclientrequest.close();\n    Assertions.assertEquals(HttpStatus.OK.getReasonPhrase(), cseclientrequest.getStatusText());\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCseHttpEntity.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestCseHttpEntity {\n  @Test\n  public void test() {\n    CseHttpEntity<String> entity = new CseHttpEntity<>(null, null);\n    entity.addContext(\"c1\", \"c1v\");\n\n    Assertions.assertEquals(1, entity.getContext().getContext().size());\n    Assertions.assertEquals(\"c1v\", entity.getContext().getContext(\"c1\"));\n\n    InvocationContext context = new InvocationContext();\n    context.addContext(\"c2\", \"c2v\");\n    entity.setContext(context);\n\n    Assertions.assertEquals(1, entity.getContext().getContext().size());\n    Assertions.assertEquals(\"c2v\", entity.getContext().getContext(\"c2\"));\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCseRequestCallback.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.web.client.RequestCallback;\n\npublic class TestCseRequestCallback {\n  @Test\n  public void testNormal() throws IOException {\n    RequestCallback callback = Mockito.mock(RequestCallback.class);\n    CseClientHttpRequest request = new CseClientHttpRequest();\n    CseRequestCallback cb = new CseRequestCallback(null, callback, null);\n    cb.doWithRequest(request);\n\n    Assertions.assertNull(request.getContext());\n  }\n\n  @Test\n  public void testCseEntity() throws IOException {\n    CseHttpEntity<?> entity = Mockito.mock(CseHttpEntity.class);\n    RequestCallback callback = Mockito.mock(RequestCallback.class);\n    CseClientHttpRequest request = new CseClientHttpRequest();\n\n    entity.addContext(\"c1\", \"c2\");\n    CseRequestCallback cb = new CseRequestCallback(entity, callback, null);\n    cb.doWithRequest(request);\n\n    Assertions.assertEquals(entity.getContext(), request.getContext());\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCseRestTemplate.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestCseRestTemplate {\n\n    @Test\n    public void testCseRestTemplate() {\n        Assertions.assertEquals(CseRestTemplate.class, new CseRestTemplate().getClass());\n    }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestCseUriTemplateHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestCseUriTemplateHandler {\n  @Test\n  public void testCrossApp() {\n    CseUriTemplateHandler handler = new CseUriTemplateHandler();\n    URI uri = handler.expand(\"cse://{ap}{p}:ms/{path}?q={query}\", \"ap\", \"p\", \"path\", \"query\");\n    Assertions.assertEquals(\"cse://app~ms/path?q=query\", uri.toString());\n\n    Map<String, String> vars = new HashMap<>();\n    vars.put(\"app\", \"app\");\n    vars.put(\"path\", \"path\");\n    vars.put(\"q\", \"query\");\n    uri = handler.expand(\"cse://{app}:ms/{path}?q={q}\", vars);\n    Assertions.assertEquals(\"cse://app~ms/path?q=query\", uri.toString());\n\n    uri = handler.expand(\"cse://ms/{path}?q={query}\", \"path\", \"query\");\n    Assertions.assertEquals(\"cse://ms/path?q=query\", uri.toString());\n  }\n\n  @Test\n  public void testCrossAppServiceComb() {\n    CseUriTemplateHandler handler = new CseUriTemplateHandler();\n    URI uri = handler.expand(\"servicecomb://{ap}{p}:ms/{path}?q={query}\", \"ap\", \"p\", \"path\", \"query\");\n    Assertions.assertEquals(\"servicecomb://app~ms/path?q=query\", uri.toString());\n\n    Map<String, String> vars = new HashMap<>();\n    vars.put(\"app\", \"app\");\n    vars.put(\"path\", \"path\");\n    vars.put(\"q\", \"query\");\n    uri = handler.expand(\"servicecomb://{app}:ms/{path}?q={q}\", vars);\n    Assertions.assertEquals(\"servicecomb://app~ms/path?q=query\", uri.toString());\n\n    uri = handler.expand(\"servicecomb://ms/{path}?q={query}\", \"path\", \"query\");\n    Assertions.assertEquals(\"servicecomb://ms/path?q=query\", uri.toString());\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestRequestMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.provider.consumer.ReferenceConfig;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestRequestMeta {\n  ReferenceConfig referenceConfig = Mockito.mock(ReferenceConfig.class);\n\n  RestOperationMeta swaggerRestOperation = Mockito.mock(RestOperationMeta.class);\n\n  Map<String, String> pathParams = new HashMap<>();\n\n  RequestMeta requestmeta = new RequestMeta(referenceConfig, swaggerRestOperation, pathParams);\n\n  OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n\n  @Test\n  public void testGetReferenceConfig() {\n    ReferenceConfig value = requestmeta.getReferenceConfig();\n    Assertions.assertNotNull(value);\n  }\n\n  @Test\n  public void testGetPathParams() {\n    Map<String, String> value = requestmeta.getPathParams();\n    Assertions.assertNotNull(value);\n  }\n\n  @Test\n  public void testGetSwaggerRestOperation() {\n    RestOperationMeta value = requestmeta.getSwaggerRestOperation();\n    Assertions.assertNotNull(value);\n  }\n\n  @Test\n  public void testGetOperationMeta() {\n    Assertions.assertNull(requestmeta.getOperationMeta());\n  }\n\n  @Test\n  public void testGetOperationQualifiedName() {\n    Mockito.when(operationMeta.getSchemaQualifiedName()).thenReturn(\"value\");\n    String qualifiedName = operationMeta.getSchemaQualifiedName();\n    Assertions.assertEquals(\"value\", qualifiedName);\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestRestTemplateBuilder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport static org.hamcrest.core.Is.is;\nimport static org.hamcrest.core.IsInstanceOf.instanceOf;\n\nimport java.net.URI;\n\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.web.client.RestOperations;\n\nimport com.seanyinx.github.unit.scaffolding.Randomness;\n\npublic class TestRestTemplateBuilder {\n\n  private final String url = Randomness.uniquify(\"url\");\n\n  private final AcceptableRestTemplate underlying = new AlwaysAcceptableRestTemplate();\n\n  private static class AlwaysAcceptableRestTemplate extends AcceptableRestTemplate {\n\n    @Override\n    public boolean isAcceptable(String uri) {\n      return true;\n    }\n\n    @Override\n    public boolean isAcceptable(URI uri) {\n      return true;\n    }\n  }\n\n  @Test\n  public void addsRestTemplateToWrapper() {\n    RestTemplateBuilder.addAcceptableRestTemplate(1, underlying);\n\n    RestOperations restTemplate = RestTemplateBuilder.create();\n\n    MatcherAssert.assertThat(restTemplate, instanceOf(RestTemplateWrapper.class));\n\n    RestTemplateWrapper wrapper = (RestTemplateWrapper) restTemplate;\n\n    MatcherAssert.assertThat(wrapper.getRestTemplate(url), is(underlying));\n    MatcherAssert.assertThat(wrapper.getRestTemplate(URI.create(url)), is(underlying));\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestRestTemplateWrapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;\nimport static java.util.Arrays.asList;\nimport static java.util.Collections.singletonList;\nimport static org.hamcrest.collection.IsIterableContainingInOrder.contains;\nimport static org.hamcrest.core.Is.is;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.never;\nimport static org.mockito.Mockito.reset;\nimport static org.mockito.Mockito.verify;\nimport static org.mockito.Mockito.when;\nimport static org.springframework.http.HttpMethod.DELETE;\nimport static org.springframework.http.HttpMethod.GET;\nimport static org.springframework.http.HttpMethod.HEAD;\nimport static org.springframework.http.HttpMethod.OPTIONS;\nimport static org.springframework.http.HttpMethod.PATCH;\nimport static org.springframework.http.HttpMethod.POST;\nimport static org.springframework.http.HttpMethod.PUT;\nimport static org.springframework.http.HttpMethod.TRACE;\nimport static org.springframework.http.HttpStatus.OK;\n\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.core.ParameterizedTypeReference;\nimport org.springframework.http.HttpEntity;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpMethod;\nimport org.springframework.http.RequestEntity;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.http.client.ClientHttpRequestFactory;\nimport org.springframework.http.client.ClientHttpRequestInterceptor;\nimport org.springframework.http.converter.ByteArrayHttpMessageConverter;\nimport org.springframework.web.client.RequestCallback;\nimport org.springframework.web.client.ResponseErrorHandler;\nimport org.springframework.web.client.ResponseExtractor;\nimport org.springframework.web.client.RestTemplate;\nimport org.springframework.web.util.DefaultUriBuilderFactory;\nimport org.springframework.web.util.UriTemplateHandler;\n\npublic class TestRestTemplateWrapper {\n\n  private final AcceptableRestTemplate underlying = mock(AcceptableRestTemplate.class);\n\n  private final RestTemplateWrapper wrapper = new RestTemplateWrapper();\n\n  private final String url = uniquify(\"someUrl\");\n\n  private final URI uri = URI.create(url);\n\n  private final String param1 = uniquify(\"param1\");\n\n  private final String param2 = uniquify(\"param2\");\n\n  private final Map<String, String> paramsMap = new HashMap<>() {\n    {\n      put(uniquify(\"key1\"), param1);\n      put(uniquify(\"key2\"), param2);\n    }\n  };\n\n  private final HttpEntity<String> requestEntity = new HttpEntity<>(uniquify(\"requestBody\"));\n\n  private final String response = uniquify(\"response\");\n\n  private final ResponseEntity<List<String>> typedResponse = new ResponseEntity<>(singletonList(response), OK);\n\n  private final ResponseEntity<String> responseEntity = new ResponseEntity<>(response, OK);\n\n  private final List<HttpMethod> httpMethods = asList(GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE);\n\n  @BeforeEach\n  public void setUp() throws Exception {\n    when(underlying.isAcceptable(url)).thenReturn(true);\n    when(underlying.isAcceptable(uri)).thenReturn(true);\n    wrapper.addAcceptableRestTemplate(1, underlying);\n  }\n\n  @Test\n  public void headForHeadersWithUnderlyingRestTemplate() {\n    HttpHeaders expected = new HttpHeaders();\n    HttpHeaders actual;\n\n    when(underlying.headForHeaders(url, param1, param2)).thenReturn(expected);\n    actual = wrapper.headForHeaders(url, param1, param2);\n    MatcherAssert.assertThat(actual, is(expected));\n    verify(underlying).headForHeaders(url, param1, param2);\n\n    when(underlying.headForHeaders(url, paramsMap)).thenReturn(expected);\n    actual = wrapper.headForHeaders(url, paramsMap);\n    MatcherAssert.assertThat(actual, is(expected));\n    verify(underlying).headForHeaders(url, paramsMap);\n\n    when(underlying.headForHeaders(uri)).thenReturn(expected);\n    actual = wrapper.headForHeaders(uri);\n    MatcherAssert.assertThat(actual, is(expected));\n    verify(underlying).headForHeaders(uri);\n  }\n\n  @Test\n  public void optionsForAllowWithUnderlyingRestTemplate() {\n    Set<HttpMethod> expected = new HashSet<>(this.httpMethods);\n    Set<HttpMethod> actual;\n\n    when(underlying.optionsForAllow(url, param1, param2)).thenReturn(expected);\n    actual = wrapper.optionsForAllow(url, param1, param2);\n    MatcherAssert.assertThat(actual, is(expected));\n    verify(underlying).optionsForAllow(url, param1, param2);\n\n    when(underlying.optionsForAllow(url, paramsMap)).thenReturn(expected);\n    actual = wrapper.optionsForAllow(url, paramsMap);\n    MatcherAssert.assertThat(actual, is(expected));\n    verify(underlying).optionsForAllow(url, paramsMap);\n\n    when(underlying.optionsForAllow(uri)).thenReturn(expected);\n    actual = wrapper.optionsForAllow(uri);\n    MatcherAssert.assertThat(actual, is(expected));\n    verify(underlying).optionsForAllow(uri);\n  }\n\n  @Test\n  public void getForObjectWithUnderlyingRestTemplate() {\n    String actual;\n\n    when(underlying.getForObject(url, String.class, param1, param2)).thenReturn(response);\n    actual = wrapper.getForObject(url, String.class, param1, param2);\n    MatcherAssert.assertThat(actual, is(response));\n    verify(underlying).getForObject(url, String.class, param1, param2);\n\n    when(underlying.getForObject(url, String.class, paramsMap)).thenReturn(response);\n    actual = wrapper.getForObject(url, String.class, paramsMap);\n    MatcherAssert.assertThat(actual, is(response));\n    verify(underlying).getForObject(url, String.class, paramsMap);\n\n    when(underlying.getForObject(uri, String.class)).thenReturn(response);\n    actual = wrapper.getForObject(uri, String.class);\n    MatcherAssert.assertThat(actual, is(response));\n    verify(underlying).getForObject(uri, String.class);\n  }\n\n  @Test\n  public void getForEntityWithUnderlyingRestTemplate() {\n    ResponseEntity<String> actual;\n\n    when(underlying.getForEntity(url, String.class, param1, param2)).thenReturn(responseEntity);\n    actual = wrapper.getForEntity(url, String.class, param1, param2);\n    MatcherAssert.assertThat(actual, is(responseEntity));\n    verify(underlying).getForEntity(url, String.class, param1, param2);\n\n    when(underlying.getForEntity(url, String.class, paramsMap)).thenReturn(responseEntity);\n    actual = wrapper.getForEntity(url, String.class, paramsMap);\n    MatcherAssert.assertThat(actual, is(responseEntity));\n    verify(underlying).getForEntity(url, String.class, paramsMap);\n\n    when(underlying.getForEntity(uri, String.class)).thenReturn(responseEntity);\n    actual = wrapper.getForEntity(uri, String.class);\n    MatcherAssert.assertThat(actual, is(responseEntity));\n    verify(underlying).getForEntity(uri, String.class);\n  }\n\n  @Test\n  public void postForObjectWithUnderlyingRestTemplate() {\n    String actual;\n\n    when(underlying.postForObject(url, requestEntity, String.class, param1, param2)).thenReturn(response);\n    actual = wrapper.postForObject(url, requestEntity, String.class, param1, param2);\n    MatcherAssert.assertThat(actual, is(response));\n    verify(underlying).postForObject(url, requestEntity, String.class, param1, param2);\n\n    when(underlying.postForObject(url, requestEntity, String.class, paramsMap)).thenReturn(response);\n    actual = wrapper.postForObject(url, requestEntity, String.class, paramsMap);\n    MatcherAssert.assertThat(actual, is(response));\n    verify(underlying).postForObject(url, requestEntity, String.class, paramsMap);\n\n    when(underlying.postForObject(uri, requestEntity, String.class)).thenReturn(response);\n    actual = wrapper.postForObject(uri, requestEntity, String.class);\n    MatcherAssert.assertThat(actual, is(response));\n    verify(underlying).postForObject(uri, requestEntity, String.class);\n  }\n\n  @Test\n  public void postForEntityWithUnderlyingRestTemplate() {\n    ResponseEntity<String> actual;\n\n    when(underlying.postForEntity(url, requestEntity, String.class, param1, param2)).thenReturn(responseEntity);\n    actual = wrapper.postForEntity(url, requestEntity, String.class, param1, param2);\n    MatcherAssert.assertThat(actual, is(responseEntity));\n    verify(underlying).postForEntity(url, requestEntity, String.class, param1, param2);\n\n    when(underlying.postForEntity(url, requestEntity, String.class, paramsMap)).thenReturn(responseEntity);\n    actual = wrapper.postForEntity(url, requestEntity, String.class, paramsMap);\n    MatcherAssert.assertThat(actual, is(responseEntity));\n    verify(underlying).postForEntity(url, requestEntity, String.class, paramsMap);\n\n    when(underlying.postForEntity(uri, requestEntity, String.class)).thenReturn(responseEntity);\n    actual = wrapper.postForEntity(uri, requestEntity, String.class);\n    MatcherAssert.assertThat(actual, is(responseEntity));\n    verify(underlying).postForEntity(uri, requestEntity, String.class);\n  }\n\n  @Test\n  public void postForLocationWithUnderlyingRestTemplate() {\n    URI actual;\n\n    when(underlying.postForLocation(url, requestEntity, param1, param2)).thenReturn(uri);\n    actual = wrapper.postForLocation(url, requestEntity, param1, param2);\n    MatcherAssert.assertThat(actual, is(uri));\n    verify(underlying).postForLocation(url, requestEntity, param1, param2);\n\n    when(underlying.postForLocation(url, requestEntity, paramsMap)).thenReturn(uri);\n    actual = wrapper.postForLocation(url, requestEntity, paramsMap);\n    MatcherAssert.assertThat(actual, is(uri));\n    verify(underlying).postForLocation(url, requestEntity, paramsMap);\n\n    when(underlying.postForLocation(uri, requestEntity)).thenReturn(uri);\n    actual = wrapper.postForLocation(uri, requestEntity);\n    MatcherAssert.assertThat(actual, is(uri));\n    verify(underlying).postForLocation(uri, requestEntity);\n  }\n\n  @Test\n  public void executeWithUnderlyingRestTemplate() {\n    RequestCallback requestCallback = clientHttpRequest -> {\n    };\n    ResponseExtractor<ResponseEntity<String>> responseExtractor = clientHttpResponse -> responseEntity;\n\n    ResponseEntity<String> actual;\n\n    for (HttpMethod method : httpMethods) {\n      when(underlying.execute(url, method, requestCallback, responseExtractor, param1, param2))\n          .thenReturn(responseEntity);\n      actual = wrapper.execute(url, method, requestCallback, responseExtractor, param1, param2);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).execute(url, method, requestCallback, responseExtractor, param1, param2);\n\n      when(underlying.execute(url, method, requestCallback, responseExtractor, paramsMap)).thenReturn(responseEntity);\n      actual = wrapper.execute(url, method, requestCallback, responseExtractor, paramsMap);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).execute(url, method, requestCallback, responseExtractor, paramsMap);\n\n      when(underlying.execute(uri, method, requestCallback, responseExtractor)).thenReturn(responseEntity);\n      actual = wrapper.execute(uri, method, requestCallback, responseExtractor);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).execute(uri, method, requestCallback, responseExtractor);\n    }\n  }\n\n  @Test\n  public void exchangeWithUnderlyingRestTemplate() {\n    ResponseEntity<String> actual;\n\n    for (HttpMethod method : httpMethods) {\n      when(underlying.exchange(url, method, requestEntity, String.class, param1, param2)).thenReturn(responseEntity);\n      actual = wrapper.exchange(url, method, requestEntity, String.class, param1, param2);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).exchange(url, method, requestEntity, String.class, param1, param2);\n\n      when(underlying.exchange(url, method, requestEntity, String.class, paramsMap)).thenReturn(responseEntity);\n      actual = wrapper.exchange(url, method, requestEntity, String.class, paramsMap);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).exchange(url, method, requestEntity, String.class, paramsMap);\n\n      when(underlying.exchange(uri, method, requestEntity, String.class)).thenReturn(responseEntity);\n      actual = wrapper.exchange(uri, method, requestEntity, String.class);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).exchange(uri, method, requestEntity, String.class);\n\n      RequestEntity<String> request = new RequestEntity<>(method, uri);\n      when(underlying.exchange(request, String.class)).thenReturn(responseEntity);\n      actual = wrapper.exchange(request, String.class);\n      MatcherAssert.assertThat(actual, is(responseEntity));\n      verify(underlying).exchange(request, String.class);\n    }\n  }\n\n  @Test\n  public void exchangeUsingParameterizedTypeWithUnderlyingRestTemplate() {\n    ParameterizedTypeReference<List<String>> typeReference = new ParameterizedTypeReference<>() {\n    };\n    ResponseEntity<List<String>> actual;\n\n    for (HttpMethod method : httpMethods) {\n      when(underlying.exchange(url, method, requestEntity, typeReference, param1, param2)).thenReturn(typedResponse);\n      actual = wrapper.exchange(url, method, requestEntity, typeReference, param1, param2);\n      MatcherAssert.assertThat(actual, is(typedResponse));\n      verify(underlying).exchange(url, method, requestEntity, typeReference, param1, param2);\n\n      when(underlying.exchange(url, method, requestEntity, typeReference, paramsMap)).thenReturn(typedResponse);\n      actual = wrapper.exchange(url, method, requestEntity, typeReference, paramsMap);\n      MatcherAssert.assertThat(actual, is(typedResponse));\n      verify(underlying).exchange(url, method, requestEntity, typeReference, paramsMap);\n\n      when(underlying.exchange(uri, method, requestEntity, typeReference)).thenReturn(typedResponse);\n      actual = wrapper.exchange(uri, method, requestEntity, typeReference);\n      MatcherAssert.assertThat(actual, is(typedResponse));\n      verify(underlying).exchange(uri, method, requestEntity, typeReference);\n\n      RequestEntity<String> request = new RequestEntity<>(method, uri);\n      when(underlying.exchange(request, typeReference)).thenReturn(typedResponse);\n      actual = wrapper.exchange(request, typeReference);\n      MatcherAssert.assertThat(actual, is(typedResponse));\n      verify(underlying).exchange(request, typeReference);\n    }\n  }\n\n  @Test\n  public void putWithUnderlyingRestTemplate() {\n    wrapper.put(url, requestEntity, param1, param2);\n    verify(underlying).put(url, requestEntity, param1, param2);\n\n    wrapper.put(url, requestEntity, paramsMap);\n    verify(underlying).put(url, requestEntity, paramsMap);\n\n    wrapper.put(uri, requestEntity);\n    verify(underlying).put(uri, requestEntity);\n  }\n\n  @Test\n  public void deleteWithUnderlyingRestTemplate() {\n    wrapper.delete(url, param1, param2);\n    verify(underlying).delete(url, param1, param2);\n\n    wrapper.delete(url, paramsMap);\n    verify(underlying).delete(url, paramsMap);\n\n    wrapper.delete(uri);\n    verify(underlying).delete(uri);\n  }\n\n  @Test\n  public void setInterceptorsWithUnderlying() {\n    ClientHttpRequestInterceptor interceptor1 = mock(ClientHttpRequestInterceptor.class);\n    ClientHttpRequestInterceptor interceptor2 = mock(ClientHttpRequestInterceptor.class);\n    List<ClientHttpRequestInterceptor> interceptors = asList(interceptor1, interceptor2);\n\n    wrapper.setInterceptors(interceptors);\n\n    MatcherAssert.assertThat(wrapper.getInterceptors(), contains(interceptor1, interceptor2));\n    MatcherAssert.assertThat(wrapper.defaultRestTemplate.getInterceptors(), contains(interceptor1, interceptor2));\n    verify(underlying, never()).setInterceptors(interceptors);\n  }\n\n  @Test\n  public void doNotSetRequestFactoryWithUnderlying() {\n    ClientHttpRequestFactory requestFactory = mock(ClientHttpRequestFactory.class);\n\n    wrapper.setRequestFactory(requestFactory);\n\n    MatcherAssert.assertThat(wrapper.getRequestFactory(), is(requestFactory));\n    MatcherAssert.assertThat(wrapper.defaultRestTemplate.getRequestFactory(), is(requestFactory));\n\n    verify(underlying, never()).setRequestFactory(requestFactory);\n  }\n\n  @Test\n  public void setErrorHandlerWithUnderlying() {\n    ResponseErrorHandler errorHandler = mock(ResponseErrorHandler.class);\n\n    wrapper.setErrorHandler(errorHandler);\n\n    MatcherAssert.assertThat(wrapper.getErrorHandler(), is(errorHandler));\n    MatcherAssert.assertThat(wrapper.defaultRestTemplate.getErrorHandler(), is(errorHandler));\n\n    verify(underlying).setErrorHandler(errorHandler);\n  }\n\n  @Test\n  public void setDefaultUriVariablesWithUnderlying() {\n    Map<String, Object> uriVariables = new HashMap<>();\n\n    wrapper.setDefaultUriVariables(uriVariables);\n\n    MatcherAssert.assertThat(defaultUriVariablesOf(wrapper), is(uriVariables));\n    MatcherAssert.assertThat(defaultUriVariablesOf(wrapper.defaultRestTemplate), is(uriVariables));\n\n    verify(underlying).setDefaultUriVariables(uriVariables);\n  }\n\n  @Test\n  public void dotNotSetUriTemplateHandlerWithUnderlying() {\n    UriTemplateHandler uriTemplateHandler = mock(UriTemplateHandler.class);\n\n    wrapper.setUriTemplateHandler(uriTemplateHandler);\n\n    MatcherAssert.assertThat(wrapper.getUriTemplateHandler(), is(uriTemplateHandler));\n    MatcherAssert.assertThat(wrapper.defaultRestTemplate.getUriTemplateHandler(), is(uriTemplateHandler));\n\n    verify(underlying, never()).setUriTemplateHandler(uriTemplateHandler);\n  }\n\n  @Test\n  public void setMessageConvertersWithUnderlying() {\n    ByteArrayHttpMessageConverter messageConverter = mock(ByteArrayHttpMessageConverter.class);\n\n    wrapper.setMessageConverters(singletonList(messageConverter));\n\n    MatcherAssert.assertThat(wrapper.getMessageConverters(), contains(messageConverter));\n    MatcherAssert.assertThat(wrapper.defaultRestTemplate.getMessageConverters(), contains(messageConverter));\n\n    verify(underlying, never()).setMessageConverters(singletonList(messageConverter));\n  }\n\n  @Test\n  public void getsAcceptableRestTemplate() {\n    MatcherAssert.assertThat(wrapper.getRestTemplate(uri), is(underlying));\n    MatcherAssert.assertThat(wrapper.getRestTemplate(url), is(underlying));\n  }\n\n  @Test\n  public void getsDefaultRestTemplate() {\n    reset(underlying);\n    MatcherAssert.assertThat(wrapper.getRestTemplate(uri), is(wrapper.defaultRestTemplate));\n    MatcherAssert.assertThat(wrapper.getRestTemplate(url), is(wrapper.defaultRestTemplate));\n  }\n\n  private Map<String, ?> defaultUriVariablesOf(RestTemplate wrapper1) {\n    return ((DefaultUriBuilderFactory) wrapper1.getUriTemplateHandler()).getDefaultUriVariables();\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestUrlWithProviderPrefixClientHttpRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.provider.springmvc.reference.UrlWithProviderPrefixClientHttpRequestFactory.UrlWithProviderPrefixClientHttpRequest;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.springframework.http.HttpMethod;\n\npublic class TestUrlWithProviderPrefixClientHttpRequestFactory {\n  UrlWithProviderPrefixClientHttpRequestFactory factory = new UrlWithProviderPrefixClientHttpRequestFactory(\"/a/b/c\");\n\n  URI uri = URI.create(\"cse://ms/a/b/c/v1/path\");\n\n  @Test\n  public void findUriPath() throws IOException {\n    UrlWithProviderPrefixClientHttpRequest request =\n        (UrlWithProviderPrefixClientHttpRequest) factory.createRequest(uri, HttpMethod.GET);\n\n    Assertions.assertEquals(\"/v1/path\", request.findUriPath(uri));\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void invoke_checkPath() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    RequestMeta requestMeta = Mockito.mock(RequestMeta.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(requestMeta.getOperationMeta()).thenReturn(operationMeta);\n    Map<String, Object> handlerContext = new HashMap<>();\n    UrlWithProviderPrefixClientHttpRequest request = new UrlWithProviderPrefixClientHttpRequest(uri, HttpMethod.GET,\n        \"/a/b/c\") {\n      @Override\n      protected Response doInvoke(Invocation invocation) {\n        return Response.ok(null);\n      }\n    };\n\n    Mockito.when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    try (MockedStatic<InvocationFactory> invocationFactoryMockedStatic = Mockito.mockStatic(InvocationFactory.class)) {\n      invocationFactoryMockedStatic.when(() -> InvocationFactory.forConsumer(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))\n              .thenReturn(invocation);\n      request.setRequestMeta(requestMeta);\n      request.setPath(request.findUriPath(uri));\n\n      request.invoke(new HashMap<>());\n\n      Assertions.assertEquals(\"/v1/path\", handlerContext.get(RestConst.REST_CLIENT_REQUEST_PATH));\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/java/org/apache/servicecomb/provider/springmvc/reference/TestUrlWithServiceNameClientHttpRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.provider.springmvc.reference;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory.UrlWithServiceNameClientHttpRequest;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\nimport org.springframework.http.HttpMethod;\n\npublic class TestUrlWithServiceNameClientHttpRequestFactory {\n  UrlWithServiceNameClientHttpRequestFactory factory = new UrlWithServiceNameClientHttpRequestFactory();\n\n  URI uri = URI.create(\"cse://ms/v1/path\");\n\n  @Test\n  public void findUriPath() throws IOException {\n    UrlWithServiceNameClientHttpRequest request =\n        (UrlWithServiceNameClientHttpRequest) factory.createRequest(uri, HttpMethod.GET);\n\n    Assertions.assertEquals(\"/ms/v1/path\", request.findUriPath(uri));\n  }\n\n  @Test\n  @SuppressWarnings(\"unchecked\")\n  public void invoke_checkPath() {\n    Invocation invocation = Mockito.mock(Invocation.class);\n    RequestMeta requestMeta = Mockito.mock(RequestMeta.class);\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(requestMeta.getOperationMeta()).thenReturn(operationMeta);\n    Map<String, Object> handlerContext = new HashMap<>();\n    UrlWithServiceNameClientHttpRequest request = new UrlWithServiceNameClientHttpRequest(uri, HttpMethod.GET) {\n      @Override\n      protected Response doInvoke(Invocation invocation) {\n        return Response.ok(null);\n      }\n    };\n\n    Mockito.when(invocation.getHandlerContext()).thenReturn(handlerContext);\n    try (MockedStatic<InvocationFactory> invocationFactoryMockedStatic = Mockito.mockStatic(InvocationFactory.class)) {\n      invocationFactoryMockedStatic.when(() -> InvocationFactory.forConsumer(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))\n              .thenReturn(invocation);\n      request.setRequestMeta(requestMeta);\n      request.setPath(request.findUriPath(uri));\n      request.invoke(new HashMap<>());\n\n      Assertions.assertEquals(\"/ms/v1/path\", handlerContext.get(RestConst.REST_CLIENT_REQUEST_PATH));\n    }\n  }\n}\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "providers/provider-springmvc/src/test/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb:\n  filter-chains:\n    consumer:\n      default: empty\n    producer:\n      default: empty\n"
  },
  {
    "path": "samples/README.md",
    "content": "java-chassis samples are moved to [servicecomb-samples](https://github.com/apache/servicecomb-samples/tree/master/java-chassis-samples)\n"
  },
  {
    "path": "service-registry/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>service-registry-parent</artifactId>\n  <name>Java Chassis::Service Registry</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>registry-local</module>\n    <module>registry-service-center</module>\n    <module>registry-lightweight</module>\n    <module>registry-zero-config</module>\n    <module>registry-nacos</module>\n    <module>registry-zookeeper</module>\n    <module>registry-etcd</module>\n    <module>registry-consul</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "service-registry/registry-consul/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>service-registry-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <artifactId>registry-consul</artifactId>\n  <name>Java Chassis::Service Registry::Consul</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.kiwiproject</groupId>\n      <artifactId>consul-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>com.google.code.gson</groupId>\n      <artifactId>gson</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\nimport com.google.common.net.HostAndPort;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.consul.config.ConsulDiscoveryProperties;\nimport org.apache.servicecomb.registry.consul.config.ConsulProperties;\nimport org.kiwiproject.consul.Consul;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnBean;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@ConditionalOnProperty(prefix = \"servicecomb.registry.consul\", name = \"enabled\", matchIfMissing = true)\n@Configuration\npublic class ConsulConfiguration {\n\n  @Bean\n  @ConfigurationProperties(prefix = ConsulConst.CONSUL_REGISTRY_PREFIX)\n  @ConditionalOnMissingBean\n  public ConsulProperties consulProperties() {\n    return new ConsulProperties();\n  }\n\n  @Bean\n  @ConfigurationProperties(prefix = ConsulConst.CONSUL_DISCOVERY_REGISTRY_PREFIX)\n  @ConditionalOnMissingBean\n  public ConsulDiscoveryProperties consulDiscoveryProperties() {\n    return new ConsulDiscoveryProperties();\n  }\n\n  @Bean\n  @ConditionalOnBean(value = {ConsulProperties.class, ConsulDiscoveryProperties.class})\n  @ConditionalOnMissingBean\n  public Consul consulClient(ConsulProperties consulProperties, ConsulDiscoveryProperties consulDiscoveryProperties) {\n    Consul.Builder builder = Consul.builder()\n        .withHostAndPort(HostAndPort.fromParts(consulProperties.getHost(), consulProperties.getPort()));\n    if (StringUtils.isNotBlank(consulDiscoveryProperties.getAclToken())) {\n      builder.withAclToken(consulDiscoveryProperties.getAclToken());\n    }\n    return builder.build();\n  }\n\n  @Bean\n  @ConditionalOnBean(value = {Consul.class, Environment.class, RegistrationId.class, DataCenterProperties.class})\n  @ConditionalOnMissingBean\n  public ConsulDiscovery consulDiscovery() {\n    return new ConsulDiscovery();\n  }\n\n  @Bean\n  @ConditionalOnBean(value = {Consul.class, Environment.class, RegistrationId.class, DataCenterProperties.class})\n  @ConditionalOnMissingBean\n  public ConsulRegistration consulRegistration() {\n    return new ConsulRegistration();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\npublic class ConsulConst {\n\n  public static final String CONSUL_REGISTRY_NAME = \"consul-registry\";\n\n  public static final String CONSUL_REGISTRY_PREFIX = \"servicecomb.registry.consul\";\n\n  public static final String CONSUL_DISCOVERY_REGISTRY_PREFIX = \"servicecomb.registry.consul.discovery\";\n\n  public static final String CONSUL_DEFAULT_ENVIRONMENT = \"production\";\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\nimport com.google.common.collect.Lists;\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\n\nimport jakarta.annotation.Resource;\nimport jakarta.validation.constraints.NotNull;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.apache.servicecomb.registry.consul.config.ConsulDiscoveryProperties;\nimport org.apache.servicecomb.registry.consul.config.ConsulProperties;\nimport org.kiwiproject.consul.Consul;\nimport org.kiwiproject.consul.HealthClient;\nimport org.kiwiproject.consul.cache.ServiceHealthCache;\nimport org.kiwiproject.consul.cache.ServiceHealthKey;\nimport org.kiwiproject.consul.model.health.Service;\nimport org.kiwiproject.consul.model.health.ServiceHealth;\nimport org.kiwiproject.consul.option.Options;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\npublic class ConsulDiscovery implements Discovery<ConsulDiscoveryInstance> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsulDiscovery.class);\n\n  @Resource\n  private ConsulProperties consulProperties;\n\n  @Resource\n  private ConsulDiscoveryProperties consulDiscoveryProperties;\n\n  @Resource\n  private Consul consulClient;\n\n  @Resource\n  private Environment environment;\n\n  private List<ConsulDiscoveryInstance> consulDiscoveryInstanceList;\n\n  private InstanceChangedListener<ConsulDiscoveryInstance> instanceChangedListener;\n\n  private ServiceHealthCache svHealth;\n\n  @Override\n  public String name() {\n    return ConsulConst.CONSUL_REGISTRY_NAME;\n  }\n\n  @Override\n  public boolean enabled(String application, String serviceName) {\n    return consulDiscoveryProperties.isEnabled();\n  }\n\n  @Override\n  public List<ConsulDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    LOGGER.info(\"findServiceInstances application:{}, serviceName:{}\", application, serviceName);\n    consulDiscoveryInstanceList = getInstances(serviceName);\n    return consulDiscoveryInstanceList;\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n    LOGGER.info(\"ConsulDiscovery findServices(application={})\", application);\n    Map<String, List<String>> response = consulClient.catalogClient().getServices().getResponse();\n    if (!CollectionUtils.isEmpty(response)) {\n      return Lists.newArrayList(response.keySet());\n    }\n    return Lists.newArrayList();\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<ConsulDiscoveryInstance> instanceChangedListener) {\n    this.instanceChangedListener = instanceChangedListener;\n  }\n\n  @Override\n  public boolean enabled() {\n    return consulDiscoveryProperties.isEnabled();\n  }\n\n  @Override\n  public void init() {\n    LOGGER.info(\"ConsulDiscovery init\");\n  }\n\n  @Override\n  public void run() {\n    LOGGER.info(\"ConsulDiscovery run\");\n    String serviceName = BootStrapProperties.readServiceName(environment);\n    HealthClient healthClient = consulClient.healthClient();\n    svHealth = ServiceHealthCache.newCache(healthClient, serviceName, true, Options.BLANK_QUERY_OPTIONS,\n        consulDiscoveryProperties.getWatchSeconds());\n    svHealth.addListener((Map<ServiceHealthKey, ServiceHealth> newValues) -> instanceChangedListener.onInstanceChanged(\n        name(), BootStrapProperties.readApplication(environment), serviceName, getInstances(serviceName)));\n    svHealth.start();\n  }\n\n  @Override\n  public void destroy() {\n    if (svHealth != null) {\n      svHealth.stop();\n    }\n    String serviceId = consulDiscoveryProperties.getServiceId();\n    LOGGER.info(\"ConsulDiscovery destroy consul service id={}\", serviceId);\n    if (consulClient != null) {\n      LOGGER.info(\"ConsulDiscovery consulClient destroy\");\n      consulClient.agentClient().deregister(serviceId);\n      consulClient.destroy();\n    }\n  }\n\n  public List<ConsulDiscoveryInstance> getInstances(@NotNull final String serviceName) {\n    List<ConsulDiscoveryInstance> instances = new ArrayList<>();\n    addInstancesToList(instances, serviceName);\n    return instances;\n  }\n\n  private void addInstancesToList(List<ConsulDiscoveryInstance> instances, String serviceName) {\n    List<ServiceHealth> healthServices = getHealthServices(serviceName);\n    if (!CollectionUtils.isEmpty(healthServices)) {\n      for (ServiceHealth serviceHealth : healthServices) {\n        Service service = serviceHealth.getService();\n        Gson gson = new GsonBuilder().disableHtmlEscaping().create();\n        ConsulInstance consulInstance = gson.fromJson(service.getMeta().get(\"meta\"), ConsulInstance.class);\n        instances.add(new ConsulDiscoveryInstance(consulInstance));\n      }\n    }\n  }\n\n  private List<ServiceHealth> getHealthServices(String serviceName) {\n    HealthClient healthClient = consulClient.healthClient();\n    return healthClient.getHealthyServiceInstances(serviceName).getResponse();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\n\npublic class ConsulDiscoveryInstance extends ConsulInstance implements DiscoveryInstance {\n\n  public ConsulDiscoveryInstance(ConsulInstance consulInstance) {\n    super(consulInstance);\n  }\n\n  @Override\n  public String getRegistryName() {\n    return ConsulConst.CONSUL_REGISTRY_NAME;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstance;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class ConsulInstance implements MicroserviceInstance {\n  private String serviceId;\n\n  private String instanceId;\n\n  private String environment;\n\n  private String application;\n\n  private String serviceName;\n\n  private String alias;\n\n  private String version;\n\n  private String description;\n\n  private DataCenterInfo dataCenterInfo;\n\n  private List<String> endpoints = new ArrayList<>();\n\n  private Map<String, String> schemas = new HashMap<>();\n\n  private Map<String, String> properties = new HashMap<>();\n\n  private MicroserviceInstanceStatus status;\n\n  public ConsulInstance() {\n\n  }\n\n  public ConsulInstance(ConsulInstance other) {\n    this.serviceId = other.serviceId;\n    this.instanceId = other.instanceId;\n    this.environment = other.environment;\n    this.application = other.application;\n    this.serviceName = other.serviceName;\n    this.alias = other.alias;\n    this.version = other.version;\n    this.description = other.description;\n    this.dataCenterInfo = other.dataCenterInfo;\n    this.endpoints = other.endpoints;\n    this.schemas = other.schemas;\n    this.properties = other.properties;\n    this.status = other.status;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  public void setEnvironment(String environment) {\n    this.environment = environment;\n  }\n\n  public void setApplication(String application) {\n    this.application = application;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public void setAlias(String alias) {\n    this.alias = alias;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public void setDescription(String description) {\n    this.description = description;\n  }\n\n  public void setDataCenterInfo(DataCenterInfo dataCenterInfo) {\n    this.dataCenterInfo = dataCenterInfo;\n  }\n\n  public void setEndpoints(List<String> endpoints) {\n    this.endpoints = endpoints;\n  }\n\n  public void setSchemas(Map<String, String> schemas) {\n    this.schemas = schemas;\n  }\n\n  public void setProperties(Map<String, String> properties) {\n    this.properties = properties;\n  }\n\n  public void setStatus(MicroserviceInstanceStatus status) {\n    this.status = status;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return this.environment;\n  }\n\n  @Override\n  public String getApplication() {\n    return this.application;\n  }\n\n  @Override\n  public String getServiceName() {\n    return this.serviceName;\n  }\n\n  @Override\n  public String getAlias() {\n    return alias;\n  }\n\n  @Override\n  public String getVersion() {\n    return version;\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return dataCenterInfo == null ? new DataCenterInfo() : dataCenterInfo;\n  }\n\n  @Override\n  public String getDescription() {\n    return description;\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return properties;\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return schemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  public void addSchema(String schemaId, String content) {\n    this.schemas.put(schemaId, content);\n  }\n\n  public void addEndpoint(String endpoint) {\n    this.endpoints.add(endpoint);\n  }\n\n  public void addProperty(String key, String value) {\n    this.properties.put(key, value);\n  }\n\n  @Override\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  @Override\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return this.status;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\n\nimport jakarta.annotation.Resource;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.invocation.endpoint.EndpointUtils;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.apache.servicecomb.registry.consul.config.ConsulDiscoveryProperties;\nimport org.kiwiproject.consul.AgentClient;\nimport org.kiwiproject.consul.Consul;\nimport org.kiwiproject.consul.model.agent.ImmutableRegistration;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n\npublic class ConsulRegistration implements Registration<ConsulRegistrationInstance> {\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsulRegistration.class);\n\n  private ConsulInstance consulInstance;\n\n  @Resource\n  private ConsulDiscoveryProperties consulDiscoveryProperties;\n\n  @Resource\n  private Consul consulClient;\n\n  @Resource\n  private Environment environment;\n\n  @Resource\n  private DataCenterProperties dataCenterProperties;\n\n  @Resource\n  private RegistrationId registrationId;\n\n  @Value(\"${servicecomb.rest.address:127.0.0.1:8080}\")\n  private String restAddress;\n\n  private ImmutableRegistration.Builder registrationBuilder;\n\n  @Override\n  public String name() {\n    return ConsulConst.CONSUL_REGISTRY_NAME;\n  }\n\n  @Override\n  public ConsulRegistrationInstance getMicroserviceInstance() {\n    return new ConsulRegistrationInstance(consulInstance);\n  }\n\n  @Override\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    consulInstance.setStatus(status);\n    Gson gson = new GsonBuilder().disableHtmlEscaping().create();\n    Map<String, String> meta = new HashMap<>();\n    meta.put(\"meta\", gson.toJson(consulInstance));\n    registrationBuilder.meta(meta);\n    ImmutableRegistration newService = registrationBuilder.build();\n    AgentClient agentClient = consulClient.agentClient();\n    agentClient.register(newService);\n    return true;\n  }\n\n  @Override\n  public void addSchema(String schemaId, String content) {\n    if (consulDiscoveryProperties.isEnableSwaggerRegistration()) {\n      consulInstance.addSchema(schemaId, content);\n    }\n  }\n\n  @Override\n  public void addEndpoint(String endpoint) {\n    consulInstance.addEndpoint(endpoint);\n  }\n\n  @Override\n  public void addProperty(String key, String value) {\n    consulInstance.addProperty(key, value);\n  }\n\n  @Override\n  public boolean enabled() {\n    return consulDiscoveryProperties.isEnabled();\n  }\n\n  @Override\n  public void init() {\n    LOGGER.info(\"ConsulRegistration init\");\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = ConsulConst.CONSUL_DEFAULT_ENVIRONMENT;\n    }\n    String instanceId = registrationId.getInstanceId();\n    consulInstance = new ConsulInstance();\n    consulInstance.setInstanceId(instanceId);\n    consulInstance.setEnvironment(env);\n    consulInstance.setApplication(BootStrapProperties.readApplication(environment));\n    consulInstance.setServiceName(BootStrapProperties.readServiceName(environment));\n    consulInstance.setAlias(BootStrapProperties.readServiceAlias(environment));\n    consulInstance.setDescription(BootStrapProperties.readServiceDescription(environment));\n    if (StringUtils.isNotEmpty(dataCenterProperties.getName())) {\n      DataCenterInfo dataCenterInfo = new DataCenterInfo();\n      dataCenterInfo.setName(dataCenterProperties.getName());\n      dataCenterInfo.setRegion(dataCenterProperties.getRegion());\n      dataCenterInfo.setAvailableZone(dataCenterProperties.getAvailableZone());\n      consulInstance.setDataCenterInfo(dataCenterInfo);\n    }\n    consulInstance.setProperties(BootStrapProperties.readServiceProperties(environment));\n    consulInstance.setVersion(BootStrapProperties.readServiceVersion(environment));\n    consulInstance.setStatus(\n        MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment)));\n  }\n\n  @Override\n  public void run() {\n    LOGGER.info(\"ConsulRegistration run\");\n    registrationBuilder = ImmutableRegistration.builder()\n        .name(consulInstance.getServiceName());\n    List<String> endpoints = consulInstance.getEndpoints();\n    for (String endpoint : endpoints) {\n      Endpoint temp = EndpointUtils.parse(endpoint);\n      if (temp.getAddress() instanceof URIEndpointObject) {\n        String hostOrIp = ((URIEndpointObject) temp.getAddress()).getHostOrIp();\n        int port = ((URIEndpointObject) temp.getAddress()).getPort();\n        String serviceId = hostOrIp + \":\" + port;\n        consulDiscoveryProperties.setServiceId(serviceId);\n        consulInstance.setServiceId(serviceId);\n        registrationBuilder.id(serviceId);\n        registrationBuilder.address(hostOrIp);\n        registrationBuilder.port(port);\n        break;\n      }\n    }\n    List<String> tags = consulDiscoveryProperties.getTags();\n    if (CollectionUtils.isEmpty(tags)) {\n      tags.add(consulInstance.getServiceName());\n    }\n    registrationBuilder.tags(tags);\n    Gson gson = new GsonBuilder().disableHtmlEscaping().create();\n    Map<String, String> meta = new HashMap<>();\n    meta.put(\"meta\", gson.toJson(consulInstance));\n    registrationBuilder.meta(meta);\n    ImmutableRegistration newService = registrationBuilder.build();\n    AgentClient agentClient = consulClient.agentClient();\n    agentClient.register(newService);\n    LOGGER.info(\"ConsulRegistration newService\");\n  }\n\n  @Override\n  public void destroy() {\n    LOGGER.info(\"ConsulRegistration destroy\");\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul;\n\n\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\n\npublic class ConsulRegistrationInstance extends ConsulInstance implements RegistrationInstance {\n\n  public ConsulRegistrationInstance(ConsulInstance instance) {\n    super(instance);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulDiscoveryProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul.config;\n\nimport org.springframework.core.style.ToStringCreator;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\npublic class ConsulDiscoveryProperties {\n\n  private String aclToken;\n\n  private List<String> tags = new ArrayList<>();\n\n  private Boolean enabled = true;\n\n  private Integer watchSeconds = 8;\n\n  private Boolean enableSwaggerRegistration = false;\n\n  private String serviceId;\n\n  public String getAclToken() {\n    return this.aclToken;\n  }\n\n  public void setAclToken(String aclToken) {\n    this.aclToken = aclToken;\n  }\n\n  public List<String> getTags() {\n    return this.tags;\n  }\n\n  public void setTags(List<String> tags) {\n    this.tags = tags;\n  }\n\n  public Boolean isEnabled() {\n    return this.enabled;\n  }\n\n  public void setEnabled(Boolean enabled) {\n    this.enabled = enabled;\n  }\n\n  public Boolean isEnableSwaggerRegistration() {\n    return enableSwaggerRegistration;\n  }\n\n  public void setEnableSwaggerRegistration(Boolean enableSwaggerRegistration) {\n    this.enableSwaggerRegistration = enableSwaggerRegistration;\n  }\n\n  public Integer getWatchSeconds() {\n    return watchSeconds;\n  }\n\n  public void setWatchSeconds(Integer watchSeconds) {\n    this.watchSeconds = watchSeconds;\n  }\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  @Override\n  public String toString() {\n    return new ToStringCreator(this).append(\"aclToken\", this.aclToken)\n        .append(\"enabled\", this.enabled)\n        .append(\"serviceId\", this.serviceId)\n        .append(\"tags\", this.tags)\n        .append(\"watchSeconds\", this.watchSeconds)\n        .toString();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.consul.config;\n\nimport jakarta.validation.constraints.NotNull;\n\nimport org.springframework.validation.annotation.Validated;\n\n\n@Validated\npublic class ConsulProperties {\n\n  @NotNull\n  private String host = \"localhost\";\n\n  private String scheme = \"http\";\n\n  @NotNull\n  private Integer port = 8500;\n\n  private Boolean enabled = true;\n\n  public String getHost() {\n    return this.host;\n  }\n\n  public void setHost(String host) {\n    this.host = host;\n  }\n\n  public Integer getPort() {\n    return this.port;\n  }\n\n  public void setPort(Integer port) {\n    this.port = port;\n  }\n\n  public Boolean isEnabled() {\n    return this.enabled;\n  }\n\n  public void setEnabled(Boolean enabled) {\n    this.enabled = enabled;\n  }\n\n  public String getScheme() {\n    return this.scheme;\n  }\n\n  public void setScheme(String scheme) {\n    this.scheme = scheme;\n  }\n\n  @Override\n  public String toString() {\n    return \"ConsulProperties{\" + \"host='\" + this.host + '\\'' + \", port=\" + this.port + \", scheme=\" + this.scheme\n        + \", enabled=\" + this.enabled + \"}\";\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.consul.ConsulConfiguration\n"
  },
  {
    "path": "service-registry/registry-etcd/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>service-registry-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-etcd</artifactId>\n  <name>Java Chassis::Service Registry::Etcd</name>\n\n  <dependencies>\n\n    <dependency>\n      <groupId>io.etcd</groupId>\n      <artifactId>jetcd-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class EtcdConfiguration {\n  @Bean\n  @ConfigurationProperties(prefix = EtcdConst.ETCD_REGISTRY_PREFIX)\n  public EtcdRegistryProperties etcdRegistryProperties() {\n    return new EtcdRegistryProperties();\n  }\n\n  @Bean\n  public EtcdDiscovery etcdDiscovery() {\n    return new EtcdDiscovery();\n  }\n\n  @Bean\n  public EtcdRegistration etcdRegistration() {\n    return new EtcdRegistration();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\npublic class EtcdConst {\n\n  public static final String ETCD_REGISTRY_NAME = \"etcd-registry\";\n\n  public static final String ETCD_DISCOVERY_ROOT = \"/servicecomb/registry/%s\";\n\n  public static final String ETCD_REGISTRY_PREFIX = \"servicecomb.registry.etcd\";\n\n  public static final String ETCD_DISCOVERY_ENABLED = ETCD_REGISTRY_PREFIX + \".%s.%s.enabled\";\n\n  public static final String ETCD_DEFAULT_ENVIRONMENT = \"production\";\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\nimport java.nio.charset.Charset;\nimport java.nio.charset.StandardCharsets;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.TimeUnit;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.ConditionWaiter;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.foundation.common.utils.MuteExceptionUtil;\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.collect.Lists;\n\nimport io.etcd.jetcd.ByteSequence;\nimport io.etcd.jetcd.Client;\nimport io.etcd.jetcd.KeyValue;\nimport io.etcd.jetcd.Watch;\nimport io.etcd.jetcd.kv.GetResponse;\nimport io.etcd.jetcd.options.GetOption;\nimport io.etcd.jetcd.options.WatchOption;\n\npublic class EtcdDiscovery implements Discovery<EtcdDiscoveryInstance> {\n\n  private Environment environment;\n\n  private String basePath;\n\n  private EtcdRegistryProperties etcdRegistryProperties;\n\n  private Client client;\n\n  private InstanceChangedListener<EtcdDiscoveryInstance> instanceChangedListener;\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(EtcdDiscovery.class);\n\n  private Map<String, Watch> watchMap = new ConcurrentHashMapEx<>();\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEtcdRegistryProperties(EtcdRegistryProperties etcdRegistryProperties) {\n    this.etcdRegistryProperties = etcdRegistryProperties;\n  }\n\n  @Override\n  public String name() {\n    return EtcdConst.ETCD_REGISTRY_NAME;\n  }\n\n  @Override\n  public boolean enabled(String application, String serviceName) {\n    return environment.getProperty(String.format(EtcdConst.ETCD_DISCOVERY_ENABLED, application, serviceName),\n        boolean.class, true);\n  }\n\n  @Override\n  public List<EtcdDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n\n    String prefixPath = basePath + \"/\" + application + \"/\" + serviceName;\n    watchMap.computeIfAbsent(prefixPath, listenServiceName -> {\n      Watch watchClient = client.getWatchClient();\n      try {\n        ByteSequence prefixByteSeq = ByteSequence.from(prefixPath, Charset.defaultCharset());\n        watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(),\n            resp -> watchNode(application, serviceName, prefixPath));\n      } catch (Exception e) {\n        LOGGER.error(\"Failed to add watch\", e);\n      }\n      return watchClient;\n    });\n\n//     async get all instances,because sync is bad way in etcd.\n    ConditionWaiter<List<EtcdDiscoveryInstance>> waiter = new ConditionWaiter<>(new ArrayList<>(), 50,\n        TimeUnit.MILLISECONDS);\n    waiter.executeTaskAsync(() -> {\n      CompletableFuture<GetResponse> getFuture = client.getKVClient()\n          .get(ByteSequence.from(prefixPath, StandardCharsets.UTF_8),\n              GetOption.builder().withPrefix(ByteSequence.from(prefixPath, StandardCharsets.UTF_8)).build());\n      GetResponse getResponse = getFuture.get();\n      return convertServiceInstanceList(getResponse.getKvs());\n    });\n    return waiter.waitForCompletion();\n  }\n\n  private void watchNode(String application, String serviceName, String prefixPath) {\n\n    CompletableFuture<GetResponse> getFuture = client.getKVClient()\n        .get(ByteSequence.from(prefixPath, StandardCharsets.UTF_8),\n            GetOption.builder().withPrefix(ByteSequence.from(prefixPath, StandardCharsets.UTF_8)).build());\n    getFuture.thenAcceptAsync(response -> {\n      List<EtcdDiscoveryInstance> discoveryInstanceList = convertServiceInstanceList(response.getKvs());\n      instanceChangedListener.onInstanceChanged(name(), application, serviceName, discoveryInstanceList);\n    }).exceptionally(e -> {\n      LOGGER.error(\"watchNode error\", e);\n      return null;\n    });\n  }\n\n  private List<KeyValue> getValuesByPrefix(String prefix) {\n\n    CompletableFuture<GetResponse> getFuture = client.getKVClient()\n        .get(ByteSequence.from(prefix, StandardCharsets.UTF_8),\n            GetOption.builder().withPrefix(ByteSequence.from(prefix, StandardCharsets.UTF_8)).build());\n    GetResponse response = MuteExceptionUtil.builder().withLog(\"get kv by prefix error\")\n        .executeCompletableFuture(getFuture);\n    return response.getKvs();\n  }\n\n  private List<EtcdDiscoveryInstance> convertServiceInstanceList(List<KeyValue> keyValueList) {\n\n    List<EtcdDiscoveryInstance> list = Lists.newArrayListWithExpectedSize(keyValueList.size());\n    for (KeyValue keyValue : keyValueList) {\n      EtcdDiscoveryInstance etcdDiscoveryInstance = getEtcdDiscoveryInstance(keyValue);\n      list.add(etcdDiscoveryInstance);\n    }\n    return list;\n  }\n\n  private static EtcdDiscoveryInstance getEtcdDiscoveryInstance(KeyValue keyValue) {\n    String valueJson = new String(keyValue.getValue().getBytes(), Charset.defaultCharset());\n\n    EtcdInstance etcdInstance = MuteExceptionUtil.builder()\n        .withLog(\"convert json value to obj from etcd failure, {}\", valueJson)\n        .executeFunctionWithDoubleParam(JsonUtils::readValue, valueJson.getBytes(StandardCharsets.UTF_8),\n            EtcdInstance.class);\n    return new EtcdDiscoveryInstance(etcdInstance);\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n\n    ConditionWaiter<List<String>> waiter = new ConditionWaiter<>(new ArrayList<>(), 50, TimeUnit.MILLISECONDS);\n    waiter.executeTaskAsync(() -> {\n      String prefixPath = basePath + \"/\" + application;\n      List<KeyValue> endpointKv = getValuesByPrefix(prefixPath);\n      return endpointKv.stream()\n          .map(kv -> kv.getKey().toString(StandardCharsets.UTF_8))\n          .map(key -> {\n            String[] parts = StringUtils.split(key, \"/\");\n            return parts.length > 5 ? parts[4] : null;\n          })\n          .filter(Objects::nonNull)\n          .distinct()\n          .collect(Collectors.toList());\n    });\n    return waiter.waitForCompletion();\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<EtcdDiscoveryInstance> instanceChangedListener) {\n    this.instanceChangedListener = instanceChangedListener;\n  }\n\n  @Override\n  public boolean enabled() {\n    return etcdRegistryProperties.isEnabled();\n  }\n\n  @Override\n  public void init() {\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = EtcdConst.ETCD_DEFAULT_ENVIRONMENT;\n    }\n    basePath = String.format(EtcdConst.ETCD_DISCOVERY_ROOT, env);\n  }\n\n  @Override\n  public void run() {\n    if (StringUtils.isEmpty(etcdRegistryProperties.getAuthenticationInfo())) {\n      this.client = Client.builder().endpoints(etcdRegistryProperties.getConnectString()).build();\n    } else {\n      String[] authInfo = etcdRegistryProperties.getAuthenticationInfo().split(\":\");\n      this.client = Client.builder().endpoints(etcdRegistryProperties.getConnectString())\n          .user(ByteSequence.from(authInfo[0], Charset.defaultCharset()))\n          .password(ByteSequence.from(authInfo[1], Charset.defaultCharset())).build();\n    }\n  }\n\n  @Override\n  public void destroy() {\n    if (client != null) {\n      client.close();\n      watchMap = null;\n    }\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\npublic class EtcdDiscoveryInstance extends EtcdInstance implements DiscoveryInstance {\n\n  public EtcdDiscoveryInstance(EtcdInstance other) {\n    super(other);\n  }\n\n  @Override\n  public String getRegistryName() {\n    return EtcdConst.ETCD_REGISTRY_NAME;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstance;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\n\npublic class EtcdInstance implements MicroserviceInstance {\n  private String serviceId;\n\n  private String instanceId;\n\n  private String environment;\n\n  private String application;\n\n  private String serviceName;\n\n  private String alias;\n\n  private String version;\n\n  private String description;\n\n  private DataCenterInfo dataCenterInfo;\n\n  private List<String> endpoints = new ArrayList<>();\n\n  private Map<String, String> schemas = new HashMap<>();\n\n  private Map<String, String> properties = new HashMap<>();\n\n  private MicroserviceInstanceStatus status;\n\n  public EtcdInstance() {\n\n  }\n\n  public EtcdInstance(EtcdInstance other) {\n    this.serviceId = other.serviceId;\n    this.instanceId = other.instanceId;\n    this.environment = other.environment;\n    this.application = other.application;\n    this.serviceName = other.serviceName;\n    this.alias = other.alias;\n    this.version = other.version;\n    this.description = other.description;\n    this.dataCenterInfo = other.dataCenterInfo;\n    this.endpoints = other.endpoints;\n    this.schemas = other.schemas;\n    this.properties = other.properties;\n    this.status = other.status;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  public void setEnvironment(String environment) {\n    this.environment = environment;\n  }\n\n  public void setApplication(String application) {\n    this.application = application;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public void setAlias(String alias) {\n    this.alias = alias;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public void setDescription(String description) {\n    this.description = description;\n  }\n\n  public void setDataCenterInfo(DataCenterInfo dataCenterInfo) {\n    this.dataCenterInfo = dataCenterInfo;\n  }\n\n  public void setEndpoints(List<String> endpoints) {\n    this.endpoints = endpoints;\n  }\n\n  public void setSchemas(Map<String, String> schemas) {\n    this.schemas = schemas;\n  }\n\n  public void setProperties(Map<String, String> properties) {\n    this.properties = properties;\n  }\n\n  public void setStatus(MicroserviceInstanceStatus status) {\n    this.status = status;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return this.environment;\n  }\n\n  @Override\n  public String getApplication() {\n    return this.application;\n  }\n\n  @Override\n  public String getServiceName() {\n    return this.serviceName;\n  }\n\n  @Override\n  public String getAlias() {\n    return alias;\n  }\n\n  @Override\n  public String getVersion() {\n    return version;\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return dataCenterInfo == null ? new DataCenterInfo() : dataCenterInfo;\n  }\n\n  @Override\n  public String getDescription() {\n    return description;\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return properties;\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return schemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  public void addSchema(String schemaId, String content) {\n    this.schemas.put(schemaId, content);\n  }\n\n  public void addEndpoint(String endpoint) {\n    this.endpoints.add(endpoint);\n  }\n\n  public void addProperty(String key, String value) {\n    this.properties.put(key, value);\n  }\n\n  @Override\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  @Override\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return this.status;\n  }\n\n  @Override\n  public String toString() {\n    return \"EtcdInstance{\" +\n        \"serviceId='\" + serviceId + '\\'' +\n        \", instanceId='\" + instanceId + '\\'' +\n        \", environment='\" + environment + '\\'' +\n        \", application='\" + application + '\\'' +\n        \", serviceName='\" + serviceName + '\\'' +\n        \", alias='\" + alias + '\\'' +\n        \", version='\" + version + '\\'' +\n        \", description='\" + description + '\\'' +\n        \", dataCenterInfo=\" + dataCenterInfo +\n        \", endpoints=\" + endpoints +\n        \", schemas=\" + schemas +\n        \", properties=\" + properties +\n        '}';\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\nimport java.nio.charset.Charset;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.foundation.common.utils.MuteExceptionUtil;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport io.etcd.jetcd.ByteSequence;\nimport io.etcd.jetcd.Client;\nimport io.etcd.jetcd.KV;\nimport io.etcd.jetcd.Lease;\nimport io.etcd.jetcd.kv.PutResponse;\nimport io.etcd.jetcd.options.PutOption;\n\npublic class EtcdRegistration implements Registration<EtcdRegistrationInstance> {\n\n  private EtcdInstance etcdInstance;\n\n  private Environment environment;\n\n  private String basePath;\n\n  private RegistrationId registrationId;\n\n  private DataCenterProperties dataCenterProperties;\n\n  private EtcdRegistryProperties etcdRegistryProperties;\n\n  private Client client;\n\n  private ScheduledExecutorService executorService;\n\n  private String keyPath;\n\n  private Long leaseId;\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEtcdRegistryProperties(EtcdRegistryProperties etcdRegistryProperties) {\n    this.etcdRegistryProperties = etcdRegistryProperties;\n  }\n\n  @Autowired\n  public void setRegistrationId(RegistrationId registrationId) {\n    this.registrationId = registrationId;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setDataCenterProperties(DataCenterProperties dataCenterProperties) {\n    this.dataCenterProperties = dataCenterProperties;\n  }\n\n  @Override\n  public String name() {\n    return EtcdConst.ETCD_REGISTRY_NAME;\n  }\n\n  @Override\n  public EtcdRegistrationInstance getMicroserviceInstance() {\n    return new EtcdRegistrationInstance(etcdInstance);\n  }\n\n  @Override\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    this.etcdInstance.setStatus(status);\n    String valueJson = MuteExceptionUtil.builder().withLog(\"to json, key:{}, value:{}\", keyPath, etcdInstance)\n        .executeFunction(JsonUtils::writeValueAsString, etcdInstance);\n    register(ByteSequence.from(keyPath, Charset.defaultCharset()),\n        ByteSequence.from(valueJson, Charset.defaultCharset()));\n    return true;\n  }\n\n  @Override\n  public void addSchema(String schemaId, String content) {\n    if (etcdRegistryProperties.isEnableSwaggerRegistration()) {\n      etcdInstance.addSchema(schemaId, content);\n    }\n  }\n\n  @Override\n  public void addEndpoint(String endpoint) {\n    etcdInstance.addEndpoint(endpoint);\n  }\n\n  @Override\n  public void addProperty(String key, String value) {\n    etcdInstance.addProperty(key, value);\n  }\n\n  @Override\n  public boolean enabled() {\n    return etcdRegistryProperties.isEnabled();\n  }\n\n  @Override\n  public void init() {\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = EtcdConst.ETCD_DEFAULT_ENVIRONMENT;\n    }\n    basePath = String.format(EtcdConst.ETCD_DISCOVERY_ROOT, env);\n    etcdInstance = new EtcdInstance();\n    etcdInstance.setInstanceId(registrationId.getInstanceId());\n    etcdInstance.setEnvironment(env);\n    etcdInstance.setApplication(BootStrapProperties.readApplication(environment));\n    etcdInstance.setServiceName(BootStrapProperties.readServiceName(environment));\n    etcdInstance.setAlias(BootStrapProperties.readServiceAlias(environment));\n    etcdInstance.setDescription(BootStrapProperties.readServiceDescription(environment));\n    if (StringUtils.isNotEmpty(dataCenterProperties.getName())) {\n      DataCenterInfo dataCenterInfo = new DataCenterInfo();\n      dataCenterInfo.setName(dataCenterProperties.getName());\n      dataCenterInfo.setRegion(dataCenterProperties.getRegion());\n      dataCenterInfo.setAvailableZone(dataCenterProperties.getAvailableZone());\n      etcdInstance.setDataCenterInfo(dataCenterInfo);\n    }\n    etcdInstance.setProperties(BootStrapProperties.readServiceProperties(environment));\n    etcdInstance.setVersion(BootStrapProperties.readServiceVersion(environment));\n    etcdInstance.setStatus(\n        MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment)));\n  }\n\n  @Override\n  public void run() {\n    client = Client.builder().endpoints(etcdRegistryProperties.getConnectString())\n        .build();\n    keyPath = basePath + \"/\" +\n        BootStrapProperties.readApplication(environment) + \"/\" +\n        BootStrapProperties.readServiceName(environment) + \"/\" +\n        registrationId.getInstanceId();\n\n    String valueJson = MuteExceptionUtil.builder().withLog(\"to json, key:{}, value:{}\", keyPath, etcdInstance)\n        .executeFunction(JsonUtils::writeValueAsString, etcdInstance);\n    register(ByteSequence.from(keyPath, Charset.defaultCharset()),\n        ByteSequence.from(valueJson, Charset.defaultCharset()));\n  }\n\n  public void register(ByteSequence key, ByteSequence value) {\n\n    Lease leaseClient = client.getLeaseClient();\n    leaseId = MuteExceptionUtil.builder().withLog(\"get lease id, key:{}, value:{}\", keyPath, etcdInstance)\n        .executeCompletableFuture(leaseClient.grant(60)).getID();\n    KV kvClient = client.getKVClient();\n\n    PutOption putOption = PutOption.builder().withLeaseId(leaseId).build();\n    CompletableFuture<PutResponse> putResponse = kvClient.put(key, value, putOption);\n    putResponse.thenRun(() -> {\n      executorService = Executors.newSingleThreadScheduledExecutor();\n      executorService.scheduleAtFixedRate(\n          () -> MuteExceptionUtil.builder().withLog(\"reRegister, {}, {}\", keyPath, etcdInstance)\n              .executeFunction(leaseClient::keepAliveOnce, leaseId), 0, 5, TimeUnit.SECONDS);\n    });\n  }\n\n  private void unregister() {\n    // close job\n    executorService.shutdownNow();\n\n    // close etcd node\n    Lease leaseClient = client.getLeaseClient();\n    leaseClient.revoke(leaseId);\n    client.getKVClient().delete(ByteSequence.from(keyPath, Charset.defaultCharset()));\n  }\n\n  @Override\n  public void destroy() {\n    if (client != null) {\n      unregister();\n      client.close();\n    }\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\n\npublic class EtcdRegistrationInstance extends EtcdInstance implements RegistrationInstance {\n  public EtcdRegistrationInstance(EtcdInstance instance) {\n    super(instance);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistryProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.etcd;\n\npublic class EtcdRegistryProperties {\n  private boolean enabled = true;\n\n  private boolean ephemeral = true;\n\n  private String connectString = \"http://127.0.0.1:2379\";\n\n  private String authenticationSchema;\n\n  private String authenticationInfo;\n\n  private int connectionTimeoutMillis = 1000;\n\n  private int sessionTimeoutMillis = 60000;\n\n  private boolean enableSwaggerRegistration = false;\n\n  public boolean isEnabled() {\n    return enabled;\n  }\n\n  public void setEnabled(boolean enabled) {\n    this.enabled = enabled;\n  }\n\n  public boolean isEphemeral() {\n    return ephemeral;\n  }\n\n  public void setEphemeral(boolean ephemeral) {\n    this.ephemeral = ephemeral;\n  }\n\n  public String getConnectString() {\n    return connectString;\n  }\n\n  public void setConnectString(String connectString) {\n    this.connectString = connectString;\n  }\n\n  public int getConnectionTimeoutMillis() {\n    return connectionTimeoutMillis;\n  }\n\n  public void setConnectionTimeoutMillis(int connectionTimeoutMillis) {\n    this.connectionTimeoutMillis = connectionTimeoutMillis;\n  }\n\n  public int getSessionTimeoutMillis() {\n    return sessionTimeoutMillis;\n  }\n\n  public void setSessionTimeoutMillis(int sessionTimeoutMillis) {\n    this.sessionTimeoutMillis = sessionTimeoutMillis;\n  }\n\n  public boolean isEnableSwaggerRegistration() {\n    return enableSwaggerRegistration;\n  }\n\n  public void setEnableSwaggerRegistration(boolean enableSwaggerRegistration) {\n    this.enableSwaggerRegistration = enableSwaggerRegistration;\n  }\n\n  public String getAuthenticationSchema() {\n    return authenticationSchema;\n  }\n\n  public void setAuthenticationSchema(String authenticationSchema) {\n    this.authenticationSchema = authenticationSchema;\n  }\n\n  public String getAuthenticationInfo() {\n    return authenticationInfo;\n  }\n\n  public void setAuthenticationInfo(String authenticationInfo) {\n    this.authenticationInfo = authenticationInfo;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-etcd/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.etcd.EtcdConfiguration\n"
  },
  {
    "path": "service-registry/registry-lightweight/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>service-registry-parent</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-lightweight</artifactId>\n  <name>Java Chassis::Service Registry::lightweight</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-pojo</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/AbstractLightweightDiscovery.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport org.apache.servicecomb.registry.api.Discovery;\r\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\r\nimport org.apache.servicecomb.registry.lightweight.store.Store;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.core.env.Environment;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\npublic abstract class AbstractLightweightDiscovery<D extends DiscoveryInstance> implements Discovery<D> {\r\n  public static final String ZERO_DISCOVERY_ENABLED = \"servicecomb.registry.zero-config.%s.%s.enabled\";\r\n\r\n  protected EventBus eventBus;\r\n\r\n  protected Store store;\r\n\r\n  private Environment environment;\r\n\r\n  @Autowired\r\n  public void setEnvironment(Environment environment) {\r\n    this.environment = environment;\r\n  }\r\n\r\n  @Autowired\r\n  public AbstractLightweightDiscovery<D> setEventBus(EventBus eventBus) {\r\n    this.eventBus = eventBus;\r\n    return this;\r\n  }\r\n\r\n  @Autowired\r\n  public AbstractLightweightDiscovery<D> setStore(Store store) {\r\n    this.store = store;\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public void init() {\r\n    eventBus.register(this);\r\n  }\r\n\r\n  @Override\r\n  public void destroy() {\r\n  }\r\n\r\n  @Override\r\n  public boolean enabled(String application, String serviceName) {\r\n    return environment.getProperty(String.format(ZERO_DISCOVERY_ENABLED, application, serviceName),\r\n        boolean.class, true);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/AbstractLightweightRegistration.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.io.IOException;\r\nimport java.time.Duration;\r\nimport java.util.concurrent.Executors;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\r\nimport org.apache.servicecomb.registry.api.Registration;\r\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\n@SuppressWarnings(\"UnstableApiUsage\")\r\npublic abstract class AbstractLightweightRegistration<R extends RegistrationInstance> implements Registration<R> {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractLightweightRegistration.class);\r\n\r\n  protected EventBus eventBus;\r\n\r\n  protected StoreService storeService;\r\n\r\n  protected Self self;\r\n\r\n  @Autowired\r\n  public AbstractLightweightRegistration<R> setEventBus(EventBus eventBus) {\r\n    this.eventBus = eventBus;\r\n    return this;\r\n  }\r\n\r\n  @Autowired\r\n  public AbstractLightweightRegistration<R> setStoreService(StoreService storeService) {\r\n    this.storeService = storeService;\r\n    return this;\r\n  }\r\n\r\n  @Autowired\r\n  public AbstractLightweightRegistration<R> setSelf(Self self) {\r\n    this.self = self;\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public void init() {\r\n\r\n  }\r\n\r\n  protected void startRegister(Duration interval) {\r\n    Executors\r\n        .newSingleThreadScheduledExecutor(runnable -> new Thread(runnable, name()))\r\n        .scheduleAtFixedRate(this::sendRegister, 0, interval.getSeconds(), TimeUnit.SECONDS);\r\n  }\r\n\r\n\r\n  protected void sendRegister() {\r\n    try {\r\n      doSendRegister();\r\n    } catch (Exception e) {\r\n      LOGGER.error(\"register failed.\", e);\r\n    }\r\n  }\r\n\r\n  protected abstract void doSendRegister() throws IOException;\r\n\r\n  @Override\r\n  public void addSchema(String schemaId, String content) {\r\n    self.addSchema(schemaId, content);\r\n  }\r\n\r\n  @Override\r\n  public void addEndpoint(String endpoint) {\r\n    self.getInstance().getEndpoints().add(endpoint);\r\n  }\r\n\r\n  @Override\r\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\r\n    return true;\r\n  }\r\n\r\n  @Override\r\n  public void addProperty(String key, String value) {\r\n\r\n  }\r\n\r\n  @Override\r\n  public void run() {\r\n    storeService.registerSelf(self);\r\n  }\r\n\r\n  @Override\r\n  public void destroy() {\r\n    try {\r\n      doSendUnregister();\r\n    } catch (Exception e) {\r\n      LOGGER.error(\"unregister failed.\", e);\r\n    }\r\n  }\r\n\r\n  protected abstract void doSendUnregister() throws IOException;\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/DiscoveryClient.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.util.concurrent.CompletableFuture;\r\n\r\nimport org.apache.servicecomb.core.Endpoint;\r\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\n\r\nimport io.swagger.v3.oas.annotations.Operation;\r\nimport jakarta.ws.rs.GET;\r\nimport jakarta.ws.rs.Path;\r\nimport jakarta.ws.rs.PathParam;\r\nimport jakarta.ws.rs.Produces;\r\nimport jakarta.ws.rs.QueryParam;\r\nimport jakarta.ws.rs.core.MediaType;\r\n\r\n@Path(\"/v1/discovery\")\r\npublic interface DiscoveryClient {\r\n  @Path(\"/info\")\r\n  @GET\r\n  @Operation(summary = \"\", operationId = \"getInfo\")\r\n  CompletableFuture<MicroserviceInfo> getInfoAsync(Endpoint endpoint, @QueryParam(\"service-id\") String serviceId);\r\n\r\n\r\n  default MicroserviceInfo getInfo(Endpoint endpoint, String serviceId) {\r\n    return AsyncUtils.toSync(getInfoAsync(endpoint, serviceId));\r\n  }\r\n\r\n  @Path(\"/microservice\")\r\n  @GET\r\n  @Operation(summary = \"\", operationId = \"getMicroservice\")\r\n  CompletableFuture<Microservice> getMicroserviceAsync(Endpoint endpoint, @QueryParam(\"service-id\") String serviceId);\r\n\r\n  default Microservice getMicroservice(Endpoint endpoint, String serviceId) {\r\n    return AsyncUtils.toSync(getMicroserviceAsync(endpoint, serviceId));\r\n  }\r\n\r\n  @Path(\"/instance\")\r\n  @GET\r\n  @Operation(summary = \"\", operationId = \"getInstance\")\r\n  CompletableFuture<MicroserviceInstance> getInstanceAsync(Endpoint endpoint,\r\n      @QueryParam(\"service-id\") String serviceId);\r\n\r\n  default MicroserviceInstance getInstance(Endpoint endpoint, String serviceId) {\r\n    return AsyncUtils.toSync(getInstanceAsync(endpoint, serviceId));\r\n  }\r\n\r\n  @Path(\"/schemas/{schema-id}\")\r\n  @GET\r\n  @Produces(MediaType.TEXT_PLAIN)\r\n  @Operation(summary = \"\", operationId = \"getSchema\")\r\n  CompletableFuture<String> getSchemaAsync(Endpoint endpoint, @QueryParam(\"service-id\") String serviceId,\r\n      @PathParam(\"schema-id\") String schemaId);\r\n\r\n  default String getSchema(Endpoint endpoint, String serviceId, String schemaId) {\r\n    return AsyncUtils.toSync(getSchemaAsync(endpoint, serviceId, schemaId));\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/DiscoveryEndpoint.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport static org.apache.servicecomb.registry.lightweight.DiscoveryEndpoint.SCHEMA_ID;\r\n\r\nimport java.util.concurrent.CompletableFuture;\r\n\r\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\n\r\nimport io.swagger.v3.oas.annotations.Parameter;\r\nimport io.swagger.v3.oas.annotations.Parameters;\r\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\r\nimport io.swagger.v3.oas.annotations.media.Schema;\r\nimport jakarta.ws.rs.GET;\r\nimport jakarta.ws.rs.Path;\r\nimport jakarta.ws.rs.PathParam;\r\nimport jakarta.ws.rs.Produces;\r\nimport jakarta.ws.rs.core.MediaType;\r\n\r\n@RestSchema(schemaId = SCHEMA_ID)\r\n@Path(\"/v1/discovery\")\r\npublic class DiscoveryEndpoint {\r\n  public static final String SCHEMA_ID = \"scb-discovery\";\r\n\r\n  private final Self self;\r\n\r\n  public DiscoveryEndpoint(Self self) {\r\n    this.self = self;\r\n  }\r\n\r\n  @Parameters(\r\n      {\r\n          @Parameter(name = \"service-id\", in = ParameterIn.QUERY, schema = @Schema(implementation = String.class),\r\n              description = \"just make it possible to mock many instances by one real instance for performance test\")\r\n      }\r\n  )\r\n  @Path(\"/info\")\r\n  @GET\r\n  public CompletableFuture<MicroserviceInfo> getInfo() {\r\n    return CompletableFuture.completedFuture(self.getMicroserviceInfo());\r\n  }\r\n\r\n  @Parameters(\r\n      {\r\n          @Parameter(name = \"service-id\", in = ParameterIn.QUERY, schema = @Schema(implementation = String.class),\r\n              description = \"just make it possible to mock many instances by one real instance for performance test\")\r\n      }\r\n  )\r\n  @Path(\"/microservice\")\r\n  @GET\r\n  public CompletableFuture<Microservice> getMicroservice() {\r\n    return CompletableFuture.completedFuture(self.getMicroservice());\r\n  }\r\n\r\n  @Parameters(\r\n      {\r\n          @Parameter(name = \"service-id\", in = ParameterIn.QUERY, schema = @Schema(implementation = String.class),\r\n              description = \"just make it possible to mock many instances by one real instance for performance test\")\r\n      }\r\n  )\r\n  @Path(\"/instance\")\r\n  @GET\r\n  public CompletableFuture<MicroserviceInstance> getInstance() {\r\n    return CompletableFuture.completedFuture(self.getInstance());\r\n  }\r\n\r\n  @Parameters(\r\n      {\r\n          @Parameter(name = \"service-id\", in = ParameterIn.QUERY, schema = @Schema(implementation = String.class),\r\n              description = \"just make it possible to mock many instances by one real instance for performance test\")\r\n      }\r\n  )\r\n  @Path(\"/schemas/{schema-id}\")\r\n  @GET\r\n  @Produces(MediaType.TEXT_PLAIN)\r\n  public CompletableFuture<String> getSchema(@PathParam(\"schema-id\") String schemaId) {\r\n    return CompletableFuture.completedFuture(self.getMicroservice().getSchemaMap().get(schemaId));\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/LightWeightRegistryConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.lightweight;\n\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.localregistry.RegistryBean;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instances;\nimport org.apache.servicecomb.provider.pojo.Invoker;\nimport org.apache.servicecomb.registry.lightweight.store.Store;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\n@Configuration\n@SuppressWarnings(\"unused\")\npublic class LightWeightRegistryConfiguration {\n\n  public static final String ZERO_CONFIG_DISCOVERY_CLIENT = \"zero-config-discovery-client\";\n\n  @Bean\n  public Store zeroConfigStore() {\n    return new Store();\n  }\n\n  @Bean\n  public MessageExecutor zeroConfigMessageExecutor(Self self, StoreService storeService) {\n    return new MessageExecutor(self, storeService);\n  }\n\n  @Bean\n  public Self zeroConfigSelf() {\n    return new Self();\n  }\n\n  @Bean\n  public StoreService zeroConfigStoreService(EventBus eventBus, Store store, DiscoveryClient discoveryClient) {\n    return new StoreService(eventBus, store, discoveryClient);\n  }\n\n  @Bean\n  public DiscoveryEndpoint zeroConfigDiscoveryEndpoint(Self self) {\n    return new DiscoveryEndpoint(self);\n  }\n\n  @Bean\n  public RegistryBean zeroConfigDiscoveryServer(Environment environment) {\n    return new RegistryBean().setAppId(BootStrapProperties.readApplication(environment))\n        .setServiceName(ZERO_CONFIG_DISCOVERY_CLIENT)\n        .addSchemaInterface(ZERO_CONFIG_DISCOVERY_CLIENT, DiscoveryClient.class)\n        // add an empty instance endpoint so that can invoke by endpoint\n        .setInstances(new Instances().setInstances(List.of(new Instance().setEndpoints(Collections.emptyList()))));\n  }\n\n  @Bean\n  public DiscoveryClient zeroConfigDiscoveryClient() {\n    return Invoker.createProxy(ZERO_CONFIG_DISCOVERY_CLIENT,\n        ZERO_CONFIG_DISCOVERY_CLIENT, DiscoveryClient.class);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/Message.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.io.IOException;\r\n\r\nimport com.fasterxml.jackson.annotation.JsonSubTypes;\r\nimport com.fasterxml.jackson.annotation.JsonSubTypes.Type;\r\nimport com.fasterxml.jackson.annotation.JsonTypeInfo;\r\nimport com.fasterxml.jackson.annotation.JsonTypeInfo.As;\r\nimport com.fasterxml.jackson.annotation.JsonTypeInfo.Id;\r\n\r\nimport io.vertx.core.json.jackson.DatabindCodec;\r\n\r\npublic class Message<T> {\r\n  public static <T> Message<T> of(MessageType type, T body) {\r\n    return new Message<T>()\r\n        .setType(type)\r\n        .setBody(body);\r\n  }\r\n\r\n  private MessageType type;\r\n\r\n  @JsonTypeInfo(use = Id.NAME, property = \"type\", include = As.EXTERNAL_PROPERTY)\r\n  @JsonSubTypes(\r\n      {\r\n          @Type(name = \"REGISTER\", value = RegisterRequest.class),\r\n          @Type(name = \"UNREGISTER\", value = UnregisterRequest.class)\r\n      }\r\n  )\r\n  private T body;\r\n\r\n  public MessageType getType() {\r\n    return type;\r\n  }\r\n\r\n  public Message<T> setType(MessageType type) {\r\n    this.type = type;\r\n    return this;\r\n  }\r\n\r\n  public T getBody() {\r\n    return body;\r\n  }\r\n\r\n  public Message<T> setBody(T body) {\r\n    this.body = body;\r\n    return this;\r\n  }\r\n\r\n  public byte[] encode() throws IOException {\r\n    return DatabindCodec.mapper().writeValueAsBytes(this);\r\n  }\r\n\r\n  public static Message<?> decode(byte[] bytes, int length) throws IOException {\r\n    return DatabindCodec.mapper()\r\n        .readValue(bytes, 0, length, Message.class);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/MessageExecutor.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.time.Duration;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\nimport java.util.Objects;\r\nimport java.util.concurrent.Executors;\r\nimport java.util.concurrent.ScheduledExecutorService;\r\nimport java.util.concurrent.TimeUnit;\r\nimport java.util.function.Consumer;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\npublic class MessageExecutor {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(MessageExecutor.class);\r\n\r\n  private final Self self;\r\n\r\n  private final StoreService storeService;\r\n\r\n  private final Map<MessageType, Consumer<?>> messageProcessors = new HashMap<>();\r\n\r\n  private final ScheduledExecutorService taskExecutor = Executors\r\n      .newSingleThreadScheduledExecutor(runnable -> new Thread(runnable, \"lightweight-message-executor\"));\r\n\r\n  public MessageExecutor(Self self, StoreService storeService) {\r\n    this.self = self;\r\n    this.storeService = storeService;\r\n\r\n    addMessageProcessor(MessageType.REGISTER, this::register);\r\n    addMessageProcessor(MessageType.UNREGISTER, storeService::unregister);\r\n  }\r\n\r\n  public void startCheckDeadInstances(Duration interval) {\r\n    taskExecutor.scheduleAtFixedRate(\r\n        () -> storeService.deleteDeadInstances(interval),\r\n        0, interval.getSeconds(), TimeUnit.SECONDS);\r\n  }\r\n\r\n  private void register(RegisterRequest request) {\r\n    if (request.isCrossApp() || Objects.equals(request.getAppId(), self.getAppId())) {\r\n      storeService.register(request);\r\n    }\r\n  }\r\n\r\n  private <T> void addMessageProcessor(MessageType messageType, Consumer<T> messageProcessor) {\r\n    messageProcessors.put(messageType, messageProcessor);\r\n  }\r\n\r\n  @SuppressWarnings(\"unchecked\")\r\n  public <T> void processMessage(Message<T> message) {\r\n    Consumer<T> consumer = (Consumer<T>) messageProcessors.get(message.getType());\r\n\r\n    taskExecutor.execute(() -> {\r\n      try {\r\n        consumer.accept(message.getBody());\r\n      } catch (Throwable e) {\r\n        LOGGER.error(\"process message error. \", e);\r\n      }\r\n    });\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/MessageType.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\npublic enum MessageType {\r\n  REGISTER,\r\n  UNREGISTER\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/MicroserviceInfo.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.util.Map;\r\n\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\n\r\npublic class MicroserviceInfo {\r\n  private Microservice microservice;\r\n\r\n  private MicroserviceInstance instance;\r\n\r\n  private Map<String, String> schemasById;\r\n\r\n  public Microservice getMicroservice() {\r\n    return microservice;\r\n  }\r\n\r\n  public MicroserviceInfo setMicroservice(Microservice microservice) {\r\n    this.microservice = microservice;\r\n    return this;\r\n  }\r\n\r\n  public Map<String, String> getSchemasById() {\r\n    return schemasById;\r\n  }\r\n\r\n  public MicroserviceInfo setSchemasById(Map<String, String> schemasById) {\r\n    this.schemasById = schemasById;\r\n    return this;\r\n  }\r\n\r\n  public MicroserviceInstance getInstance() {\r\n    return instance;\r\n  }\r\n\r\n  public MicroserviceInfo setInstance(MicroserviceInstance instance) {\r\n    this.instance = instance;\r\n    return this;\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/RegisterException.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\npublic class RegisterException extends RuntimeException {\r\n  private static final long serialVersionUID = 4130899909889771251L;\r\n\r\n  public RegisterException(String message) {\r\n    super(message);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/RegisterInstanceEvent.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\n\r\n/**\r\n * post when a new instance registered<br>\r\n * to notify registration send a new register message<br>\r\n * currently, only \"zero config\" need this\r\n */\r\npublic class RegisterInstanceEvent {\r\n  private final Microservice microservice;\r\n\r\n  private final MicroserviceInstance instance;\r\n\r\n  public RegisterInstanceEvent(Microservice microservice, MicroserviceInstance instance) {\r\n    this.microservice = microservice;\r\n    this.instance = instance;\r\n  }\r\n\r\n  public Microservice getMicroservice() {\r\n    return microservice;\r\n  }\r\n\r\n  public MicroserviceInstance getInstance() {\r\n    return instance;\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/RegisterRequest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.util.List;\r\n\r\nimport org.apache.servicecomb.core.Endpoint;\r\nimport org.apache.servicecomb.core.invocation.endpoint.EndpointCacheUtils;\r\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\r\n\r\npublic class RegisterRequest {\r\n  private String appId;\r\n\r\n  private String serviceId;\r\n\r\n  private boolean crossApp;\r\n\r\n  private String schemasSummary;\r\n\r\n  private String instanceId;\r\n\r\n  private MicroserviceInstanceStatus status;\r\n\r\n  private List<String> endpoints;\r\n\r\n  public String getAppId() {\r\n    return appId;\r\n  }\r\n\r\n  public RegisterRequest setAppId(String appId) {\r\n    this.appId = appId;\r\n    return this;\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return serviceId;\r\n  }\r\n\r\n  public RegisterRequest setServiceId(String serviceId) {\r\n    this.serviceId = serviceId;\r\n    return this;\r\n  }\r\n\r\n  public boolean isCrossApp() {\r\n    return crossApp;\r\n  }\r\n\r\n  public RegisterRequest setCrossApp(boolean crossApp) {\r\n    this.crossApp = crossApp;\r\n    return this;\r\n  }\r\n\r\n  public String getSchemasSummary() {\r\n    return schemasSummary;\r\n  }\r\n\r\n  public RegisterRequest setSchemasSummary(String schemasSummary) {\r\n    this.schemasSummary = schemasSummary;\r\n    return this;\r\n  }\r\n\r\n  public String getInstanceId() {\r\n    return instanceId;\r\n  }\r\n\r\n  public RegisterRequest setInstanceId(String instanceId) {\r\n    this.instanceId = instanceId;\r\n    return this;\r\n  }\r\n\r\n  public MicroserviceInstanceStatus getStatus() {\r\n    return status;\r\n  }\r\n\r\n  public RegisterRequest setStatus(MicroserviceInstanceStatus status) {\r\n    this.status = status;\r\n    return this;\r\n  }\r\n\r\n  public List<String> getEndpoints() {\r\n    return endpoints;\r\n  }\r\n\r\n  public RegisterRequest setEndpoints(List<String> endpoints) {\r\n    this.endpoints = endpoints;\r\n    return this;\r\n  }\r\n\r\n  public Endpoint selectFirstEndpoint() {\r\n    return endpoints.stream()\r\n        .findFirst()\r\n        .map(EndpointCacheUtils::getOrCreate)\r\n        .orElse(null);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/SchemaChangedEvent.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\n\r\npublic class SchemaChangedEvent {\r\n  private final Microservice microservice;\r\n\r\n  public SchemaChangedEvent(Microservice microservice) {\r\n    this.microservice = microservice;\r\n  }\r\n\r\n  public Microservice getMicroservice() {\r\n    return microservice;\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/Self.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport org.apache.servicecomb.core.BootListener;\r\nimport org.apache.servicecomb.registry.RegistrationId;\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceFactory;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\nimport org.springframework.beans.factory.InitializingBean;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.core.env.Environment;\r\n\r\nimport com.google.common.annotations.VisibleForTesting;\r\n\r\npublic class Self implements InitializingBean, BootListener {\r\n  private Microservice microservice;\r\n\r\n  // Whether to allow cross-app calls to me\r\n  private boolean crossApp;\r\n\r\n  private MicroserviceInstance instance;\r\n\r\n  private final MicroserviceInfo microserviceInfo = new MicroserviceInfo();\r\n\r\n  private Environment environment;\r\n\r\n  private RegistrationId registrationId;\r\n\r\n  @Autowired\r\n  public void setEnvironment(Environment environment) {\r\n    this.environment = environment;\r\n  }\r\n\r\n  @Autowired\r\n  public void setRegistrationId(RegistrationId registrationId) {\r\n    this.registrationId = registrationId;\r\n  }\r\n\r\n  @Override\r\n  public void afterPropertiesSet() {\r\n    init(environment);\r\n  }\r\n\r\n  @VisibleForTesting\r\n  public Self init(Environment environment) {\r\n    microservice = new MicroserviceFactory().create(environment);\r\n    microservice.serviceId(String.format(\"%s/%s/%s/%s\",\r\n        microservice.getEnvironment(),\r\n        microservice.getAppId(),\r\n        microservice.getServiceName(),\r\n        microservice.getVersion()));\r\n\r\n    instance = microservice.getInstance()\r\n        .instanceId(registrationId.getInstanceId())\r\n        .serviceId(microservice.getServiceId());\r\n\r\n    microserviceInfo\r\n        .setMicroservice(microservice)\r\n        .setSchemasById(microservice.getSchemaMap())\r\n        .setInstance(instance);\r\n\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public int getOrder() {\r\n    return Integer.MAX_VALUE;\r\n  }\r\n\r\n  @Override\r\n  public void onBeforeRegistry(BootEvent event) {\r\n    crossApp = microservice.allowCrossApp();\r\n  }\r\n\r\n  public Microservice getMicroservice() {\r\n    return microservice;\r\n  }\r\n\r\n  public String getAppId() {\r\n    return microservice.getAppId();\r\n  }\r\n\r\n  public Microservice setServiceName(String serviceName) {\r\n    return microservice.serviceName(serviceName);\r\n  }\r\n\r\n  public String getVersion() {\r\n    return microservice.getVersion();\r\n  }\r\n\r\n  public String getInstanceId() {\r\n    return instance.getInstanceId();\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return instance.getServiceId();\r\n  }\r\n\r\n  public MicroserviceInstance getInstance() {\r\n    return instance;\r\n  }\r\n\r\n  public MicroserviceInfo getMicroserviceInfo() {\r\n    return microserviceInfo;\r\n  }\r\n\r\n  public Self addSchema(String schemaId, String content) {\r\n    microservice.addSchema(schemaId, content);\r\n    return this;\r\n  }\r\n\r\n  public Self addEndpoint(String endpoint) {\r\n    instance.getEndpoints().add(endpoint);\r\n    return this;\r\n  }\r\n\r\n  public RegisterRequest buildRegisterRequest() {\r\n    return createRegisterRequest()\r\n        .setAppId(microservice.getAppId())\r\n        .setServiceId(microservice.getServiceId())\r\n        .setCrossApp(crossApp)\r\n        .setInstanceId(instance.getInstanceId())\r\n        .setStatus(instance.getStatus())\r\n        .setEndpoints(instance.getEndpoints());\r\n  }\r\n\r\n  protected RegisterRequest createRegisterRequest() {\r\n    return new RegisterRequest();\r\n  }\r\n\r\n  public UnregisterRequest buildUnregisterRequest() {\r\n    return createUnregisterRequest()\r\n        .setServiceId(microservice.getServiceId())\r\n        .setInstanceId(instance.getInstanceId());\r\n  }\r\n\r\n  protected UnregisterRequest createUnregisterRequest() {\r\n    return new UnregisterRequest();\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/StoreService.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport java.time.Duration;\r\nimport java.util.concurrent.CompletableFuture;\r\n\r\nimport org.apache.servicecomb.core.Endpoint;\r\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\nimport org.apache.servicecomb.registry.lightweight.store.InstanceStore;\r\nimport org.apache.servicecomb.registry.lightweight.store.MicroserviceStore;\r\nimport org.apache.servicecomb.registry.lightweight.store.Store;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\npublic class StoreService {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(StoreService.class);\r\n\r\n  private final EventBus eventBus;\r\n\r\n  private final Store store;\r\n\r\n  private final DiscoveryClient discoveryClient;\r\n\r\n  public StoreService(EventBus eventBus, Store store, DiscoveryClient discoveryClient) {\r\n    this.store = store;\r\n    this.discoveryClient = discoveryClient;\r\n    this.eventBus = eventBus;\r\n  }\r\n\r\n  public void registerSelf(Self self) {\r\n    MicroserviceStore microserviceStore = store.addMicroservice(self.getMicroservice());\r\n    addInstance(microserviceStore, self.getInstance());\r\n  }\r\n\r\n  public InstanceStore register(RegisterRequest request) {\r\n    return AsyncUtils.toSync(registerAsync(request));\r\n  }\r\n\r\n  public CompletableFuture<InstanceStore> registerAsync(RegisterRequest request) {\r\n    return doRegisterAsync(request)\r\n        .whenComplete((r, e) -> logFailedRegister(request, e));\r\n  }\r\n\r\n  private void logFailedRegister(RegisterRequest request, Throwable throwable) {\r\n    if (throwable == null) {\r\n      return;\r\n    }\r\n\r\n    LOGGER.error(\"register instance failed, serviceId={}, instanceId={}, endpoints={}.\",\r\n        request.getServiceId(),\r\n        request.getInstanceId(),\r\n        request.getEndpoints(),\r\n        throwable);\r\n  }\r\n\r\n  private CompletableFuture<InstanceStore> doRegisterAsync(RegisterRequest request) {\r\n    InstanceStore instanceStore = store.findInstanceStore(request.getInstanceId());\r\n    if (instanceStore == null) {\r\n      return addInstance(request);\r\n    }\r\n\r\n    if (instanceStore.isStatusChanged(request.getStatus())) {\r\n      updateInstanceStatus(request, instanceStore);\r\n    }\r\n    return heartbeat(instanceStore);\r\n  }\r\n\r\n  private CompletableFuture<InstanceStore> addInstance(RegisterRequest request) {\r\n    Endpoint endpoint = request.selectFirstEndpoint();\r\n    if (endpoint == null) {\r\n      return AsyncUtils.completeExceptionally(new RegisterException(\"can not select endpoint\"));\r\n    }\r\n\r\n    MicroserviceStore microserviceStore = this.store.findMicroserviceStore(request.getServiceId());\r\n    if (microserviceStore == null) {\r\n      return addMicroserviceAndInstance(endpoint, request);\r\n    }\r\n\r\n    return CompletableFuture.completedFuture(null).thenCompose(v ->\r\n            discoveryClient.getInstanceAsync(endpoint, request.getServiceId()))\r\n        .thenApply(instance -> addInstance(microserviceStore, instance));\r\n  }\r\n\r\n  private CompletableFuture<InstanceStore> addMicroserviceAndInstance(Endpoint endpoint, RegisterRequest request) {\r\n    return discoveryClient.getInfoAsync(endpoint, request.getServiceId())\r\n        .thenApply(info -> {\r\n          info.getMicroservice().getSchemaMap().putAll(info.getSchemasById());\r\n          MicroserviceStore microserviceStore = store\r\n              .addMicroservice(info.getMicroservice());\r\n\r\n          LOGGER.info(\"add microservice and instance, serviceId={}, instanceId={}, endpoints={}\",\r\n              request.getServiceId(),\r\n              request.getInstanceId(),\r\n              request.getEndpoints());\r\n          return doAddInstance(microserviceStore, info.getInstance());\r\n        });\r\n  }\r\n\r\n  private InstanceStore addInstance(MicroserviceStore microserviceStore, MicroserviceInstance instance) {\r\n    LOGGER.info(\"add instance, serviceId={}, instanceId={}, endpoints={}\",\r\n        instance.getServiceId(),\r\n        instance.getInstanceId(),\r\n        instance.getEndpoints());\r\n\r\n    return doAddInstance(microserviceStore, instance);\r\n  }\r\n\r\n  private InstanceStore doAddInstance(MicroserviceStore microserviceStore, MicroserviceInstance instance) {\r\n    InstanceStore instanceStore = store.addInstance(microserviceStore, instance);\r\n    eventBus.post(new RegisterInstanceEvent(microserviceStore.getMicroservice(), instance));\r\n    return instanceStore;\r\n  }\r\n\r\n  private void updateInstanceStatus(RegisterRequest request, InstanceStore instanceStore) {\r\n    LOGGER.info(\"update instance status, old status={}, new status={}, serviceId={}, instanceId={}, endpoints={}\",\r\n        instanceStore.getStatus(),\r\n        request.getStatus(),\r\n        instanceStore.getServiceId(),\r\n        instanceStore.getInstanceId(),\r\n        instanceStore.getEndpoints());\r\n\r\n    store.findMicroserviceStore(instanceStore.getServiceId())\r\n        .updateInstanceStatus(instanceStore, request.getStatus());\r\n  }\r\n\r\n  private CompletableFuture<InstanceStore> heartbeat(InstanceStore instanceStore) {\r\n    instanceStore.updateLastHeartBeat();\r\n\r\n    LOGGER.debug(\"instance heartbeat, serviceId={}, instanceId={}, endpoints={}\",\r\n        instanceStore.getServiceId(),\r\n        instanceStore.getInstanceId(),\r\n        instanceStore.getEndpoints());\r\n\r\n    return CompletableFuture.completedFuture(instanceStore);\r\n  }\r\n\r\n  public Void unregister(UnregisterRequest request) {\r\n    return AsyncUtils.toSync(unregisterAsync(request));\r\n  }\r\n\r\n  public CompletableFuture<Void> unregisterAsync(UnregisterRequest request) {\r\n    deleteInstance(\"unregister\", request.getServiceId(), request.getInstanceId());\r\n    return CompletableFuture.completedFuture(null);\r\n  }\r\n\r\n  public void deleteInstance(String action, String serviceId, String instanceId) {\r\n    InstanceStore instanceStore = store.deleteInstance(serviceId, instanceId);\r\n    if (instanceStore == null) {\r\n      return;\r\n    }\r\n\r\n    LOGGER.info(\"{} instance, serviceId={}, instanceId={}, endpoints={}\",\r\n        action,\r\n        instanceStore.getServiceId(),\r\n        instanceStore.getInstanceId(),\r\n        instanceStore.getEndpoints());\r\n  }\r\n\r\n  public void deleteDeadInstances(Duration timeout) {\r\n    store.findDeadInstances(timeout)\r\n        .forEach(instance -> deleteInstance(\"delete dead\", instance.getServiceId(), instance.getInstanceId()));\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/UnregisterRequest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\npublic class UnregisterRequest {\r\n  private String serviceId;\r\n\r\n  private String instanceId;\r\n\r\n  public String getServiceId() {\r\n    return serviceId;\r\n  }\r\n\r\n  public UnregisterRequest setServiceId(String serviceId) {\r\n    this.serviceId = serviceId;\r\n    return this;\r\n  }\r\n\r\n  public String getInstanceId() {\r\n    return instanceId;\r\n  }\r\n\r\n  public UnregisterRequest setInstanceId(String instanceId) {\r\n    this.instanceId = instanceId;\r\n    return this;\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/AbstractPropertiesLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.registry.api.PropertyExtended;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\n/**\n * Loading microservice properties\n */\npublic abstract class AbstractPropertiesLoader {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPropertiesLoader.class);\n\n  public Map<String, String> loadProperties(Environment environment) {\n    Map<String, String> propertiesMap = new HashMap<>();\n    loadPropertiesFromConfigMap(environment, propertiesMap);\n    loadPropertiesFromExtendedClass(environment, propertiesMap);\n\n    return propertiesMap;\n  }\n\n  protected abstract Map<String, String> readProperties(Environment environment);\n\n  protected abstract String readPropertiesExtendedClass(Environment environment);\n\n  private void loadPropertiesFromConfigMap(Environment environment, Map<String, String> propertiesMap) {\n    propertiesMap.putAll(readProperties(environment));\n  }\n\n  private void loadPropertiesFromExtendedClass(Environment environment, Map<String, String> propertiesMap) {\n    String extendedPropertyClass = readPropertiesExtendedClass(environment);\n\n    if (StringUtils.isEmpty(extendedPropertyClass)) {\n      return;\n    }\n\n    try {\n      Class<?> classExternalProperty = Class.forName(extendedPropertyClass);\n      if (!PropertyExtended.class.isAssignableFrom(classExternalProperty)) {\n        String errMsg = String.format(\n            \"Define propertyExtendedClass %s in yaml, but not implement the interface PropertyExtended.\",\n            extendedPropertyClass);\n        LOGGER.error(errMsg);\n        throw new Error(errMsg);\n      }\n\n      PropertyExtended instance = (PropertyExtended) classExternalProperty.getDeclaredConstructor().newInstance();\n      Map<String, String> extendedPropertiesMap = instance.getExtendedProperties();\n      if (extendedPropertiesMap != null && !extendedPropertiesMap.isEmpty()) {\n        propertiesMap.putAll(extendedPropertiesMap);\n      }\n    } catch (ReflectiveOperationException e) {\n      String errMsg = \"Fail to create instance of class: \" + extendedPropertyClass;\n      LOGGER.error(errMsg);\n      throw new Error(errMsg, e);\n    }\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/FindInstancesResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.util.List;\n\npublic class FindInstancesResponse {\n  private List<MicroserviceInstance> instances;\n\n  public List<MicroserviceInstance> getInstances() {\n    return instances;\n  }\n\n  public FindInstancesResponse setInstances(List<MicroserviceInstance> instances) {\n    this.instances = instances;\n    return this;\n  }\n\n  public void mergeInstances(List<MicroserviceInstance> instances) {\n    if (this.instances == null) {\n      this.instances = instances;\n    } else {\n      this.instances.addAll(instances);\n    }\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/HealthCheck.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n/**\n * Created by   on 2017/1/13.\n */\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class HealthCheck {\n  private HealthCheckMode mode;\n\n  private int port;\n\n  private int interval;\n\n  private int times;\n\n  public int getInterval() {\n    return interval;\n  }\n\n  public void setInterval(int interval) {\n    this.interval = interval;\n  }\n\n  public int getTimes() {\n    return times;\n  }\n\n  public void setTimes(int times) {\n    this.times = times;\n  }\n\n  public HealthCheckMode getMode() {\n    return mode;\n  }\n\n  public void setMode(HealthCheckMode mode) {\n    this.mode = mode;\n  }\n\n  public int getTTL() {\n    if (this.mode != HealthCheckMode.HEARTBEAT) {\n      return 0;\n    }\n    return getInterval() * (getTimes() + 1);\n  }\n\n  public int getPort() {\n    return port;\n  }\n\n  public void setPort(int port) {\n    this.port = port;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/HealthCheckMode.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport com.fasterxml.jackson.annotation.JsonValue;\n\n/**\n * Created by   on 2017/1/25.\n */\npublic enum HealthCheckMode {\n  UNKNOWN(\"unknown\"),\n  HEARTBEAT(\"push\"),\n  PLATFORM(\"pull\");\n\n  private final String name;\n\n  HealthCheckMode(String name) {\n    this.name = name;\n  }\n\n  @JsonValue\n  public String getName() {\n    return name;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/InstancePropertiesLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.springframework.core.env.Environment;\n\npublic final class InstancePropertiesLoader extends AbstractPropertiesLoader {\n\n  public static final InstancePropertiesLoader INSTANCE = new InstancePropertiesLoader();\n\n  private InstancePropertiesLoader() {\n  }\n\n\n  @Override\n  protected Map<String, String> readProperties(Environment environment) {\n    return BootStrapProperties.readServiceInstanceProperties(environment);\n  }\n\n  @Override\n  protected String readPropertiesExtendedClass(Environment environment) {\n    return BootStrapProperties.readServiceInstanceExtendedClass(environment);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/Microservice.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n/**\n * Created by on 2016/12/5.\n */\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class Microservice {\n  // service center rule: max length: 64\n  // two way to generate service id\n  // 1. microservice instance generate by some rule, ex: env/app/name/version\n  //    and then register to service center with the id\n  // 2. register to service center with the id to be null, and then service center generate by UUID\n  private String serviceId;\n\n  private String registerBy;\n\n  private String environment;\n\n  // service center rule: max length: 160\n  private String appId;\n\n  // service center rule: max length: 128\n  private String serviceName;\n\n  /**\n   * for governance\n   * when invoke cross app, if not use alias name, then {microservice}.{schema}.{operation} will conflict\n   */\n  private String alias;\n\n  private String version;\n\n  private String description;\n\n  private String level;\n\n  private List<String> schemas = new ArrayList<>();\n\n  @JsonIgnore\n  private final Map<String, String> schemaMap = new HashMap<>();\n\n\n  private Map<String, String> properties = new HashMap<>();\n\n  @JsonIgnore\n  private MicroserviceInstance instance;\n\n  /**\n   * Currently this field only exists in ServiceComb-Java-Chassis,\n   * and ServiceComb-Service-Center does not hold this field.\n   * Once the 3rd party services are supported to be registered into ServiceComb-Service-Center,\n   * the corresponding field should be added into Service-Center.\n   */\n  private boolean thirdPartyService;\n\n  public Microservice() {\n  }\n\n  public MicroserviceInstance getInstance() {\n    return instance;\n  }\n\n  public void setInstance(MicroserviceInstance instance) {\n    this.instance = instance;\n  }\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public Microservice serviceId(String serviceId) {\n    this.serviceId = serviceId;\n    return this;\n  }\n\n  public String getAppId() {\n    return appId;\n  }\n\n  public void setAppId(String appId) {\n    this.appId = appId;\n  }\n\n  public Microservice appId(String appId) {\n    this.appId = appId;\n    return this;\n  }\n\n  public String getAlias() {\n    return alias;\n  }\n\n  public void setAlias(String alias) {\n    this.alias = alias;\n  }\n\n  public String getServiceName() {\n    return serviceName;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public Microservice serviceName(String serviceName) {\n    this.serviceName = serviceName;\n    return this;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public Microservice version(String version) {\n    this.version = version;\n    return this;\n  }\n\n  public String getDescription() {\n    return description;\n  }\n\n  public void setDescription(String description) {\n    this.description = description;\n  }\n\n  public String getLevel() {\n    return level;\n  }\n\n  public void setLevel(String level) {\n    this.level = level;\n  }\n\n  public List<String> getSchemas() {\n    return schemas;\n  }\n\n  public void setSchemas(List<String> schemas) {\n    this.schemas = schemas;\n  }\n\n  public void addSchema(String schemaId, String content) {\n    this.schemaMap.put(schemaId, content);\n    schemas.add(schemaId);\n  }\n\n  public Map<String, String> getSchemaMap() {\n    return schemaMap;\n  }\n\n  public Map<String, String> getProperties() {\n    return properties;\n  }\n\n  public void setProperties(Map<String, String> properties) {\n    this.properties = properties;\n  }\n\n  public static String generateAbsoluteMicroserviceName(String appId, String microserviceName) {\n    StringBuilder sb = new StringBuilder(appId.length() + microserviceName.length() + 1);\n    sb.append(appId).append(DefinitionConst.APP_SERVICE_SEPARATOR).append(microserviceName);\n    return sb.toString();\n  }\n\n\n  public String getRegisterBy() {\n    return registerBy;\n  }\n\n  public void setRegisterBy(String registerBy) {\n    this.registerBy = registerBy;\n  }\n\n  public String getEnvironment() {\n    return environment;\n  }\n\n  public void setEnvironment(String environment) {\n    this.environment = environment;\n  }\n\n  public boolean isThirdPartyService() {\n    return thirdPartyService;\n  }\n\n  public void setThirdPartyService(boolean thirdPartyService) {\n    this.thirdPartyService = thirdPartyService;\n  }\n\n  // Whether to allow cross-app calls to me\n  public boolean allowCrossApp() {\n    return Boolean.parseBoolean(properties.get(DefinitionConst.CONFIG_ALLOW_CROSS_APP_KEY));\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/MicroserviceFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.APP_MAPPING;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_DEFAULT_REGISTER_BY;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.SERVICE_MAPPING;\nimport static org.apache.servicecomb.foundation.common.base.ServiceCombConstants.VERSION_MAPPING;\n\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.Version;\nimport org.springframework.core.env.Environment;\n\npublic class MicroserviceFactory {\n  public Microservice create(Environment environment) {\n    Microservice microservice = createMicroserviceFromConfiguration(environment);\n    microservice.setInstance(MicroserviceInstance.createFromDefinition(environment));\n    return microservice;\n  }\n\n  private Microservice createMicroserviceFromConfiguration(Environment environment) {\n    Microservice microservice = new Microservice();\n\n    if (!StringUtils.isEmpty(environment.getProperty(APP_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(APP_MAPPING)))) {\n      microservice.setAppId(environment.getProperty(environment.getProperty(APP_MAPPING)));\n    } else {\n      microservice.setAppId(BootStrapProperties.readApplication(environment));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(SERVICE_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(SERVICE_MAPPING)))) {\n      microservice.setServiceName(environment.getProperty(environment.getProperty(SERVICE_MAPPING)));\n    } else {\n      microservice.setServiceName(BootStrapProperties.readServiceName(environment));\n    }\n    String version;\n    if (!StringUtils.isEmpty(environment.getProperty(VERSION_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(VERSION_MAPPING)))) {\n      version = environment.getProperty(environment.getProperty(VERSION_MAPPING));\n    } else {\n      version = BootStrapProperties.readServiceVersion(environment);\n    }\n    // just check version format\n    new Version(version);\n    microservice.setVersion(version);\n\n    microservice.setDescription(BootStrapProperties.readServiceDescription(environment));\n    microservice.setLevel(BootStrapProperties.readServiceRole(environment));\n    Map<String, String> propertiesMap = MicroservicePropertiesLoader.INSTANCE.loadProperties(environment);\n    microservice.setProperties(propertiesMap);\n    microservice.setEnvironment(BootStrapProperties.readServiceEnvironment(environment));\n\n    // set alias name when allow cross app\n    if (microservice.allowCrossApp()) {\n      microservice.setAlias(Microservice.generateAbsoluteMicroserviceName(microservice.getAppId(),\n          microservice.getServiceName()));\n    }\n\n    microservice.setRegisterBy(CONFIG_DEFAULT_REGISTER_BY);\n\n    return microservice;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/MicroserviceInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.springframework.core.env.Environment;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\n\n/**\n * Created by   on 2016/12/5.\n */\n@JsonIgnoreProperties(ignoreUnknown = true)\npublic class MicroserviceInstance {\n  // even disconnected from service center\n  // instanceId will not be changed\n  // when register to service center again, use the old instanceId.\n  private String instanceId;\n\n  // service center rule: max length: 64\n  private String serviceId;\n\n  private List<String> endpoints = new ArrayList<>();\n\n  private String hostName;\n\n  private MicroserviceInstanceStatus status = MicroserviceInstanceStatus.UP;\n\n  private Map<String, String> properties = new HashMap<>(); // reserved key list: region|az|stage|group\n\n  private HealthCheck healthCheck;\n\n  private String stage;\n\n  private DataCenterInfo dataCenterInfo;\n\n  private String timestamp;\n\n  @Override\n  public String toString() {\n    StringBuilder sb = new StringBuilder();\n    sb.append(\"instanceId=\" + instanceId + \";\");\n    sb.append(\"serviceId=\" + serviceId + \";\");\n    sb.append(\"status=\" + status + \";\");\n    sb.append(\"endpoints=\" + endpoints.toString());\n    return sb.toString();\n  }\n\n  public String getTimestamp() {\n    return timestamp;\n  }\n\n  public void setTimestamp(String timestamp) {\n    this.timestamp = timestamp;\n  }\n\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  public MicroserviceInstance instanceId(String instanceId) {\n    this.instanceId = instanceId;\n    return this;\n  }\n\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public MicroserviceInstance serviceId(String serviceId) {\n    this.serviceId = serviceId;\n    return this;\n  }\n\n  public String getHostName() {\n    return hostName;\n  }\n\n  public void setHostName(String hostName) {\n    this.hostName = hostName;\n  }\n\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  public void setEndpoints(List<String> endpoints) {\n    this.endpoints = endpoints;\n  }\n\n  public MicroserviceInstanceStatus getStatus() {\n    return status;\n  }\n\n  public void setStatus(MicroserviceInstanceStatus status) {\n    this.status = status;\n  }\n\n  public Map<String, String> getProperties() {\n    return properties;\n  }\n\n  public void setProperties(Map<String, String> properties) {\n    this.properties = properties;\n  }\n\n  public HealthCheck getHealthCheck() {\n    return healthCheck;\n  }\n\n  public void setHealthCheck(HealthCheck healthCheck) {\n    this.healthCheck = healthCheck;\n  }\n\n  @Deprecated\n  public String getStage() {\n    return stage;\n  }\n\n  @Deprecated\n  public void setStage(String stage) {\n    this.stage = stage;\n  }\n\n  public DataCenterInfo getDataCenterInfo() {\n    return dataCenterInfo;\n  }\n\n  @Override\n  public int hashCode() {\n    return this.instanceId.hashCode();\n  }\n\n  @Override\n  public boolean equals(Object obj) {\n    if (obj instanceof MicroserviceInstance) {\n      return this.instanceId.equals(((MicroserviceInstance) obj).instanceId);\n    }\n    return false;\n  }\n\n  public void setDataCenterInfo(DataCenterInfo dataCenterInfo) {\n    this.dataCenterInfo = dataCenterInfo;\n  }\n\n  // Some properties of microservice instance are dynamic changed, not cover them all now.\n  public static MicroserviceInstance createFromDefinition(Environment environment) {\n    MicroserviceInstance microserviceInstance = new MicroserviceInstance();\n    // default hard coded values\n    microserviceInstance.setStage(DefinitionConst.DEFAULT_STAGE);\n    microserviceInstance.setStatus(MicroserviceInstanceStatus\n        .valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment)));\n    HealthCheck healthCheck = new HealthCheck();\n    healthCheck.setMode(HealthCheckMode.HEARTBEAT);\n    microserviceInstance.setHealthCheck(healthCheck);\n\n    // load properties\n    Map<String, String> propertiesMap = InstancePropertiesLoader.INSTANCE.loadProperties(environment);\n    microserviceInstance.setProperties(propertiesMap);\n\n    // load data center information\n    loadDataCenterInfo(environment, microserviceInstance);\n    return microserviceInstance;\n  }\n\n  private static void loadDataCenterInfo(Environment environment, MicroserviceInstance microserviceInstance) {\n    String dataCenterName = environment.getProperty(\"servicecomb.datacenter.name\");\n    if (StringUtils.isEmpty(dataCenterName)) {\n      return;\n    }\n    String region = environment.getProperty(\"servicecomb.datacenter.region\");\n    String availableZone = environment.getProperty(\"servicecomb.datacenter.availableZone\");\n    DataCenterInfo dataCenterInfo = new DataCenterInfo();\n    dataCenterInfo.setName(dataCenterName);\n    dataCenterInfo.setRegion(region);\n    dataCenterInfo.setAvailableZone(availableZone);\n    microserviceInstance.setDataCenterInfo(dataCenterInfo);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/MicroserviceInstances.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.nio.charset.StandardCharsets;\n\nimport javax.crypto.Mac;\n\nimport org.apache.commons.codec.binary.Base64;\nimport org.apache.commons.codec.digest.HmacAlgorithms;\nimport org.apache.commons.codec.digest.HmacUtils;\nimport org.apache.commons.lang3.StringUtils;\n\npublic class MicroserviceInstances {\n  private boolean microserviceNotExist;\n\n  private boolean needRefresh = true;\n\n  private String revision;\n\n  private FindInstancesResponse instancesResponse;\n\n  public boolean isMicroserviceNotExist() {\n    return microserviceNotExist;\n  }\n\n  public MicroserviceInstances setMicroserviceNotExist(boolean microserviceNotExist) {\n    this.microserviceNotExist = microserviceNotExist;\n    return this;\n  }\n\n  public boolean isNeedRefresh() {\n    return needRefresh;\n  }\n\n  public MicroserviceInstances setNeedRefresh(boolean needRefresh) {\n    this.needRefresh = needRefresh;\n    return this;\n  }\n\n  public String getRevision() {\n    return revision;\n  }\n\n  public MicroserviceInstances setRevision(String revision) {\n    this.revision = revision;\n    return this;\n  }\n\n  public FindInstancesResponse getInstancesResponse() {\n    return instancesResponse;\n  }\n\n  public MicroserviceInstances setInstancesResponse(FindInstancesResponse instancesResponse) {\n    this.instancesResponse = instancesResponse;\n    return this;\n  }\n\n  public void mergeMicroserviceInstances(MicroserviceInstances other) {\n    mergeNeedRefresh(other.needRefresh);\n    mergeMicroserviceNotExist(other.microserviceNotExist);\n    mergeRevision(other);\n    mergeInstanceResponse(other.getInstancesResponse());\n  }\n\n  private void mergeRevision(MicroserviceInstances other) {\n    if (!other.isMicroserviceNotExist() && other.needRefresh) {\n      Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_1, stringToBytes(this.revision));\n      this.revision = Base64.encodeBase64String(mac.doFinal(stringToBytes(other.revision)));\n    }\n  }\n\n  private byte[] stringToBytes(String input) {\n    if (StringUtils.isEmpty(input)) {\n      input = \"@\";\n    }\n    return input.getBytes(StandardCharsets.UTF_8);\n  }\n\n  private void mergeMicroserviceNotExist(boolean microserviceNotExist) {\n    // only is all not exists, set to not exits.\n    if (this.microserviceNotExist) {\n      this.microserviceNotExist = microserviceNotExist;\n    }\n  }\n\n  private void mergeNeedRefresh(boolean needRefresh) {\n    // if one of discovery need refresh, all need refresh\n    if (!this.needRefresh) {\n      this.needRefresh = needRefresh;\n    }\n  }\n\n  private void mergeInstanceResponse(FindInstancesResponse instancesResponse) {\n    if (instancesResponse == null) {\n      return;\n    }\n\n    if (this.instancesResponse == null) {\n      this.instancesResponse = instancesResponse;\n      return;\n    }\n\n    this.instancesResponse.mergeInstances(instancesResponse.getInstances());\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/model/MicroservicePropertiesLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.lightweight.model;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.springframework.core.env.Environment;\n\npublic final class MicroservicePropertiesLoader extends AbstractPropertiesLoader {\n\n  public static final MicroservicePropertiesLoader INSTANCE = new MicroservicePropertiesLoader();\n\n  private MicroservicePropertiesLoader() {\n  }\n\n  @Override\n  protected Map<String, String> readProperties(Environment environment) {\n    return BootStrapProperties.readServiceProperties(environment);\n  }\n\n  @Override\n  protected String readPropertiesExtendedClass(Environment environment) {\n    return BootStrapProperties.readServiceExtendedClass(environment);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/store/AppStore.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight.store;\r\n\r\nimport java.util.Map;\r\n\r\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstances;\r\n\r\npublic class AppStore {\r\n  private final Map<String, MicroserviceStore> microserviceByName = new ConcurrentHashMapEx<>();\r\n\r\n  public void addMicroservice(MicroserviceStore microserviceStore) {\r\n    microserviceByName.put(microserviceStore.getServiceName(), microserviceStore);\r\n  }\r\n\r\n  public MicroserviceInstances findServiceInstances(String serviceName, String revision) {\r\n    MicroserviceStore microserviceStore = microserviceByName.get(serviceName);\r\n    if (microserviceStore == null) {\r\n      return new MicroserviceInstances()\r\n          .setMicroserviceNotExist(true);\r\n    }\r\n\r\n    return microserviceStore.findServiceInstances(revision);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/store/InstanceStore.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight.store;\r\n\r\nimport java.util.List;\r\nimport java.util.Objects;\r\n\r\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\n\r\nimport com.google.common.base.Ticker;\r\n\r\npublic class InstanceStore {\r\n  private final Ticker ticker;\r\n\r\n  private MicroserviceInstance instance;\r\n\r\n  private long lastHeartBeat;\r\n\r\n  public InstanceStore(Ticker ticker, MicroserviceInstance instance) {\r\n    this.ticker = ticker;\r\n    this.instance = instance;\r\n\r\n    this.updateLastHeartBeat();\r\n  }\r\n\r\n  public boolean isStatusChanged(MicroserviceInstanceStatus status) {\r\n    return !Objects.equals(instance.getStatus(), status);\r\n  }\r\n\r\n  public MicroserviceInstance getInstance() {\r\n    return instance;\r\n  }\r\n\r\n  public InstanceStore setInstance(MicroserviceInstance instance) {\r\n    this.instance = instance;\r\n    return this;\r\n  }\r\n\r\n  public String getInstanceId() {\r\n    return getInstance().getInstanceId();\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return getInstance().getServiceId();\r\n  }\r\n\r\n  public List<String> getEndpoints() {\r\n    return getInstance().getEndpoints();\r\n  }\r\n\r\n  public MicroserviceInstanceStatus getStatus() {\r\n    return instance.getStatus();\r\n  }\r\n\r\n  public void setStatus(MicroserviceInstanceStatus status) {\r\n    instance.setStatus(status);\r\n  }\r\n\r\n  public void updateLastHeartBeat() {\r\n    this.lastHeartBeat = ticker.read();\r\n  }\r\n\r\n  public long getLastHeartBeat() {\r\n    return lastHeartBeat;\r\n  }\r\n\r\n  public boolean isHeartBeatTimeout(long nanoNow, long nanoTimeout) {\r\n    return (nanoNow - lastHeartBeat) > nanoTimeout;\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/store/MicroserviceStore.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight.store;\r\n\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.stream.Collectors;\r\n\r\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\r\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\r\nimport org.apache.servicecomb.registry.lightweight.model.FindInstancesResponse;\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstances;\r\n\r\nimport com.google.common.base.Ticker;\r\n\r\npublic class MicroserviceStore {\r\n  private final Ticker ticker;\r\n\r\n  private final Microservice microservice;\r\n\r\n  private final Map<String, InstanceStore> instancesById = new ConcurrentHashMapEx<>();\r\n\r\n  private String instancesRevision;\r\n\r\n  public MicroserviceStore(Ticker ticker, Microservice microservice) {\r\n    this.ticker = ticker;\r\n    this.microservice = microservice;\r\n\r\n    updateInstancesRevision();\r\n  }\r\n\r\n  public void updateInstancesRevision() {\r\n    this.instancesRevision = String.valueOf(ticker.read());\r\n  }\r\n\r\n  public String getServiceName() {\r\n    return microservice.getServiceName();\r\n  }\r\n\r\n  public String getServiceId() {\r\n    return microservice.getServiceId();\r\n  }\r\n\r\n  public Microservice getMicroservice() {\r\n    return microservice;\r\n  }\r\n\r\n  public InstanceStore addInstance(MicroserviceInstance instance) {\r\n    InstanceStore instanceStore = new InstanceStore(ticker, instance);\r\n\r\n    instancesById.put(instance.getInstanceId(), instanceStore);\r\n\r\n    updateInstancesRevision();\r\n    return instanceStore;\r\n  }\r\n\r\n  public InstanceStore deleteInstance(String instanceId) {\r\n    InstanceStore instanceStore = instancesById.remove(instanceId);\r\n    if (instanceStore != null) {\r\n      updateInstancesRevision();\r\n    }\r\n    return instanceStore;\r\n  }\r\n\r\n  public void updateInstanceStatus(InstanceStore instanceStore, MicroserviceInstanceStatus status) {\r\n    instanceStore.setStatus(status);\r\n    updateInstancesRevision();\r\n  }\r\n\r\n  public MicroserviceInstances findServiceInstances(String revision) {\r\n    if (instancesRevision.equals(revision)) {\r\n      return new MicroserviceInstances()\r\n          .setRevision(instancesRevision)\r\n          .setNeedRefresh(false);\r\n    }\r\n\r\n    List<MicroserviceInstance> instances = instancesById.values().stream()\r\n        .map(InstanceStore::getInstance)\r\n        .collect(Collectors.toList());\r\n    FindInstancesResponse response = new FindInstancesResponse()\r\n        .setInstances(instances);\r\n    return new MicroserviceInstances()\r\n        .setRevision(instancesRevision)\r\n        .setInstancesResponse(response);\r\n  }\r\n\r\n\r\n  public boolean hasInstance() {\r\n    return !instancesById.isEmpty();\r\n  }\r\n\r\n  public int getInstanceCount() {\r\n    return instancesById.size();\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/java/org/apache/servicecomb/registry/lightweight/store/Store.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight.store;\r\n\r\nimport java.time.Duration;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.Optional;\r\nimport java.util.stream.Collectors;\r\nimport java.util.stream.Stream;\r\n\r\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\r\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstances;\r\n\r\nimport com.google.common.base.Ticker;\r\n\r\npublic class Store {\r\n  private Ticker ticker = Ticker.systemTicker();\r\n\r\n  private final Map<String, AppStore> appsById = new ConcurrentHashMapEx<>();\r\n\r\n  private final Map<String, MicroserviceStore> microservicesByName = new ConcurrentHashMapEx<>();\r\n\r\n  private final Map<String, MicroserviceStore> microservicesById = new ConcurrentHashMapEx<>();\r\n\r\n  private final Map<String, InstanceStore> instancesById = new ConcurrentHashMapEx<>();\r\n\r\n  public Store setTicker(Ticker ticker) {\r\n    this.ticker = ticker;\r\n    return this;\r\n  }\r\n\r\n  public AppStore getOrCreateAppStore(String appId) {\r\n    return appsById.computeIfAbsent(appId, key -> new AppStore());\r\n  }\r\n\r\n  public MicroserviceStore findMicroserviceStore(String serviceId) {\r\n    return microservicesById.get(serviceId);\r\n  }\r\n\r\n  public InstanceStore findInstanceStore(String instanceId) {\r\n    return instancesById.get(instanceId);\r\n  }\r\n\r\n  public MicroserviceStore addMicroservice(Microservice microservice) {\r\n    MicroserviceStore microserviceStore = new MicroserviceStore(ticker, microservice);\r\n\r\n    getOrCreateAppStore(microservice.getAppId())\r\n        .addMicroservice(microserviceStore);\r\n    microservicesById.put(microservice.getServiceId(), microserviceStore);\r\n    microservicesByName.put(microservice.getServiceName(), microserviceStore);\r\n\r\n    return microserviceStore;\r\n  }\r\n\r\n  public InstanceStore addInstance(MicroserviceStore microserviceStore, MicroserviceInstance instance) {\r\n    InstanceStore instanceStore = microserviceStore.addInstance(instance);\r\n    instancesById.put(instance.getInstanceId(), instanceStore);\r\n    return instanceStore;\r\n  }\r\n\r\n  public InstanceStore deleteInstance(String serviceId, String instanceId) {\r\n    MicroserviceStore microserviceStore = findMicroserviceStore(serviceId);\r\n    if (microserviceStore == null) {\r\n      return null;\r\n    }\r\n\r\n    InstanceStore instanceStore = microserviceStore.deleteInstance(instanceId);\r\n    if (instanceStore != null) {\r\n      instancesById.remove(instanceId);\r\n    }\r\n    return instanceStore;\r\n  }\r\n\r\n  public Optional<Microservice> getMicroservice(String microserviceId) {\r\n    return Optional.ofNullable(microservicesById.get(microserviceId))\r\n        .map(MicroserviceStore::getMicroservice);\r\n  }\r\n\r\n  public Optional<MicroserviceInstance> getMicroserviceInstance(String instanceId) {\r\n    return Optional.ofNullable(instancesById.get(instanceId))\r\n        .map(InstanceStore::getInstance);\r\n  }\r\n\r\n  public MicroserviceInstances findServiceInstances(String appId, String serviceName, String revision) {\r\n    return Optional.ofNullable(appsById.get(appId))\r\n        .map(appStore -> appStore.findServiceInstances(serviceName, revision))\r\n        .orElse(new MicroserviceInstances()\r\n            .setMicroserviceNotExist(true));\r\n  }\r\n\r\n  public List<Microservice> getAllMicroservices() {\r\n    return microservicesByName.values().stream()\r\n        .map(MicroserviceStore::getMicroservice)\r\n        .collect(Collectors.toList());\r\n  }\r\n\r\n  public int getMicroserviceCount() {\r\n    return microservicesByName.size();\r\n  }\r\n\r\n  public int getInstanceCount() {\r\n    return instancesById.size();\r\n  }\r\n\r\n  public Stream<MicroserviceInstance> findDeadInstances(Duration timeout) {\r\n    long nanoNow = ticker.read();\r\n    long nanoTimeout = timeout.toNanos();\r\n    return instancesById.values().stream()\r\n        .filter(instanceStore -> instanceStore.isHeartBeatTimeout(nanoNow, nanoTimeout))\r\n        .map(InstanceStore::getInstance);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.lightweight.LightWeightRegistryConfiguration\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/config/TestAbstractPropertiesLoader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.config;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.registry.lightweight.model.AbstractPropertiesLoader;\nimport org.apache.servicecomb.registry.lightweight.model.MicroservicePropertiesLoader;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.ConfigurableEnvironment;\nimport org.springframework.core.env.EnumerablePropertySource;\nimport org.springframework.core.env.MutablePropertySources;\n\npublic class TestAbstractPropertiesLoader {\n  @Test\n  public void testExtendedClassCompatible() {\n    ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\n    EnumerablePropertySource<?> propertySource = Mockito.mock(EnumerablePropertySource.class);\n    mutablePropertySources.addLast(propertySource);\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {});\n\n    Mockito.when(environment.getProperty(BootStrapProperties.CONFIG_SERVICE_EXTENDED_CLASS))\n        .thenReturn(\"invalidClass\");\n    AbstractPropertiesLoader loader = MicroservicePropertiesLoader.INSTANCE;\n    try {\n      loader.loadProperties(environment);\n      Assertions.fail(\"Must throw exception\");\n    } catch (Error e) {\n      Assertions.assertEquals(ClassNotFoundException.class, e.getCause().getClass());\n      Assertions.assertEquals(\"invalidClass\", e.getCause().getMessage());\n    }\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/lightweight/MessageTest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\nimport static org.assertj.core.api.Assertions.fail;\r\n\r\nimport org.junit.jupiter.api.Test;\r\n\r\nimport io.vertx.core.json.Json;\r\nimport org.skyscreamer.jsonassert.JSONAssert;\r\n\r\nclass MessageTest {\r\n  private String toLinuxPrettyJson(Object value) {\r\n    return Json.encodePrettily(value)\r\n        .replaceAll(\"\\r\\n\", \"\\n\");\r\n  }\r\n\r\n  @Test\r\n  void should_encode_register_type() {\r\n    Message<RegisterRequest> msg = Message.of(MessageType.REGISTER, new RegisterRequest());\r\n\r\n    try {\r\n      JSONAssert.assertEquals(toLinuxPrettyJson(msg), \"\"\r\n        + \"{\\n\"\r\n        + \"  \\\"type\\\" : \\\"REGISTER\\\",\\n\"\r\n        + \"  \\\"body\\\" : {\\n\"\r\n        + \"    \\\"appId\\\" : null,\\n\"\r\n        + \"    \\\"serviceId\\\" : null,\\n\"\r\n        + \"    \\\"crossApp\\\" : false,\\n\"\r\n        + \"    \\\"schemasSummary\\\" : null,\\n\"\r\n        + \"    \\\"instanceId\\\" : null,\\n\"\r\n        + \"    \\\"status\\\" : null,\\n\"\r\n        + \"    \\\"endpoints\\\" : null\\n\"\r\n        + \"  }\\n\"\r\n        + \"}\", false);\r\n    } catch (Exception e) {\r\n      fail(\"Failed to compare JSONs: \" + e.getMessage(), e);\r\n    }\r\n\r\n  }\r\n\r\n  @Test\r\n  void should_decode_register_type() {\r\n    String json = Json.encode(Message.of(MessageType.REGISTER, new RegisterRequest()));\r\n    Message<?> message = Json.decodeValue(json, Message.class);\r\n\r\n    assertThat(message.getBody()).isInstanceOf(RegisterRequest.class);\r\n  }\r\n\r\n  @Test\r\n  void should_encode_unregister_type() {\r\n    Message<UnregisterRequest> msg = Message.of(MessageType.UNREGISTER, new UnregisterRequest());\r\n\r\n    try {\r\n      JSONAssert.assertEquals(toLinuxPrettyJson(msg), \"\"\r\n        + \"{\\n\"\r\n        + \"  \\\"type\\\" : \\\"UNREGISTER\\\",\\n\"\r\n        + \"  \\\"body\\\" : {\\n\"\r\n        + \"    \\\"serviceId\\\" : null,\\n\"\r\n        + \"    \\\"instanceId\\\" : null\\n\"\r\n        + \"  }\\n\"\r\n        + \"}\", false);\r\n    } catch (Exception e) {\r\n      fail(\"Failed to compare JSONs: \" + e.getMessage(), e);\r\n    }\r\n  }\r\n\r\n  @Test\r\n  void should_decode_unregister_type() {\r\n    String json = Json.encode(Message.of(MessageType.UNREGISTER, new UnregisterRequest()));\r\n    Message<?> message = Json.decodeValue(json, Message.class);\r\n\r\n    assertThat(message.getBody()).isInstanceOf(UnregisterRequest.class);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/lightweight/StoreServiceTest.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.registry.lightweight;\r\n\r\nimport static org.assertj.core.api.Assertions.assertThat;\r\n\r\nimport java.util.concurrent.CompletableFuture;\r\n\r\nimport org.apache.servicecomb.core.Endpoint;\r\nimport org.apache.servicecomb.foundation.test.scaffolding.time.MockTicker;\r\nimport org.apache.servicecomb.registry.RegistrationId;\r\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\r\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\r\nimport org.apache.servicecomb.registry.lightweight.store.InstanceStore;\r\nimport org.apache.servicecomb.registry.lightweight.store.Store;\r\nimport org.junit.jupiter.api.BeforeEach;\r\nimport org.junit.jupiter.api.Test;\r\nimport org.mockito.ArgumentMatchers;\r\nimport org.mockito.Mockito;\r\nimport org.springframework.core.env.ConfigurableEnvironment;\r\nimport org.springframework.core.env.EnumerablePropertySource;\r\nimport org.springframework.core.env.MutablePropertySources;\r\n\r\nimport com.google.common.eventbus.EventBus;\r\n\r\nimport io.vertx.core.json.Json;\r\n\r\npublic class StoreServiceTest {\r\n  static Endpoint endpoint = Mockito.mock(Endpoint.class);\r\n\r\n  static class MockRegisterRequest extends RegisterRequest {\r\n    @Override\r\n    public Endpoint selectFirstEndpoint() {\r\n      return endpoint;\r\n    }\r\n  }\r\n\r\n  static ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class);\r\n\r\n  Self self;\r\n\r\n  EventBus eventBus = new EventBus();\r\n\r\n  MockTicker ticker = new MockTicker();\r\n\r\n  Store store = new Store().setTicker(ticker);\r\n\r\n  DiscoveryClient discoveryClient = Mockito.mock(DiscoveryClient.class);\r\n\r\n  StoreService service = new StoreService(eventBus, store, discoveryClient);\r\n\r\n  @BeforeEach\r\n  void setUp() {\r\n    MutablePropertySources mutablePropertySources = new MutablePropertySources();\r\n    EnumerablePropertySource<?> propertySource = Mockito.mock(EnumerablePropertySource.class);\r\n    mutablePropertySources.addLast(propertySource);\r\n    Mockito.when(environment.getPropertySources()).thenReturn(mutablePropertySources);\r\n    Mockito.when(propertySource.getPropertyNames()).thenReturn(new String[] {});\r\n    Mockito.when(environment.getProperty(\"servicecomb.service.application\")).thenReturn(\"app\");\r\n    Mockito.when(environment.getProperty(\"servicecomb.service.name\")).thenReturn(\"svc\");\r\n    Mockito.when(environment.getProperty(\"servicecomb.service.version\")).thenReturn(\"1.0.0.0\");\r\n    Mockito.when(environment.getProperty(\"servicecomb.instance.initialStatus\")).thenReturn(\"UP\");\r\n\r\n    self = new Self() {\r\n      @Override\r\n      protected RegisterRequest createRegisterRequest() {\r\n        return new MockRegisterRequest();\r\n      }\r\n    };\r\n    self.setRegistrationId(new RegistrationId());\r\n    self.init(environment)\r\n        .addSchema(\"schema-1\", \"s1\")\r\n        .addEndpoint(\"rest://1.1.1.1:80\");\r\n\r\n    Mockito.when(discoveryClient.getInfoAsync(ArgumentMatchers.any(), ArgumentMatchers.any()))\r\n        .thenReturn(CompletableFuture.completedFuture(self.getMicroserviceInfo()));\r\n    Mockito.when(discoveryClient.getInstanceAsync(ArgumentMatchers.any(), ArgumentMatchers.any()))\r\n        .thenReturn(CompletableFuture.completedFuture(self.getInstance()));\r\n  }\r\n\r\n  @Test\r\n  void should_register_microservice_and_instance_when_both_not_exist() {\r\n    RegisterRequest request = self.buildRegisterRequest();\r\n    InstanceStore instanceStore = service.register(request);\r\n\r\n    assertThat(store.findMicroserviceStore(self.getServiceId()).getMicroservice())\r\n        .isSameAs(self.getMicroservice());\r\n    assertThat(instanceStore.getInstance()).isSameAs(self.getInstance());\r\n    assertThat(self.getInstance().getStatus()).isEqualTo(MicroserviceInstanceStatus.UP);\r\n  }\r\n\r\n  @Test\r\n  void should_register_instance_when_microservice_exist() {\r\n    Microservice microservice = Json.decodeValue(Json.encode(self.getMicroservice()), Microservice.class);\r\n    store.addMicroservice(microservice);\r\n\r\n    RegisterRequest request = self.buildRegisterRequest();\r\n    InstanceStore instanceStore = service.register(request);\r\n\r\n    assertThat(microservice).isNotSameAs(self.getMicroservice());\r\n    assertThat(store.findMicroserviceStore(self.getServiceId()).getMicroservice())\r\n        .isSameAs(microservice);\r\n    assertThat(instanceStore.getInstance()).isSameAs(self.getInstance());\r\n  }\r\n\r\n\r\n  @Test\r\n  void should_allow_update_instance_status() {\r\n    should_register_microservice_and_instance_when_both_not_exist();\r\n\r\n    RegisterRequest request = self.buildRegisterRequest()\r\n        .setStatus(MicroserviceInstanceStatus.TESTING);\r\n    ticker.setValues(1L);\r\n    InstanceStore instanceStore = service.register(request);\r\n\r\n    assertThat(self.getInstance().getStatus()).isEqualTo(MicroserviceInstanceStatus.TESTING);\r\n    assertThat(instanceStore.getLastHeartBeat()).isEqualTo(1);\r\n  }\r\n\r\n  @Test\r\n  void should_process_as_heartbeat_when_nothing_changed() {\r\n    should_register_microservice_and_instance_when_both_not_exist();\r\n    InstanceStore instanceStore = store.findInstanceStore(self.getInstanceId());\r\n    assertThat(instanceStore.getLastHeartBeat()).isEqualTo(0);\r\n\r\n    ticker.setValues(1L);\r\n    should_register_microservice_and_instance_when_both_not_exist();\r\n    assertThat(instanceStore.getLastHeartBeat()).isEqualTo(1);\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-local/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>service-registry-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-local</artifactId>\n  <name>Java Chassis::Java Chassis::Service Registry::Local</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.localregistry;\n\n\nimport java.util.List;\n\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class LocalDiscovery implements Discovery<LocalDiscoveryInstance> {\n  public static final String LOCAL_DISCOVERY_ENABLED = \"servicecomb.registry.local.%s.%s.enabled\";\n\n  private LocalRegistryStore localRegistryStore;\n\n  private Environment environment;\n\n  @Autowired\n  public void setLocalRegistryStore(LocalRegistryStore localRegistryStore) {\n    this.localRegistryStore = localRegistryStore;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public int getOrder() {\n    return -10000;\n  }\n\n  @Override\n  public String name() {\n    return LocalRegistryConst.LOCAL_REGISTRY_NAME;\n  }\n\n  @Override\n  public boolean enabled(String application, String serviceName) {\n    return environment.getProperty(String.format(LOCAL_DISCOVERY_ENABLED, application, serviceName),\n        boolean.class, true);\n  }\n\n  @Override\n  public List<LocalDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    return this.localRegistryStore.findServiceInstances(application, serviceName);\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n    return this.localRegistryStore.findServices(application);\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<LocalDiscoveryInstance> instanceChangedListener) {\n\n  }\n\n  @Override\n  public void init() {\n    this.localRegistryStore.init();\n  }\n\n  @Override\n  public void run() {\n    this.localRegistryStore.run();\n  }\n\n  @Override\n  public void destroy() {\n  }\n\n  @Override\n  public boolean enabled() {\n    return this.environment.getProperty(LocalRegistryConst.LOCAL_REGISTRY_ENABLED, boolean.class, true);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.localregistry;\n\nimport java.lang.management.ManagementFactory;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.registry.api.AbstractDiscoveryInstance;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class LocalDiscoveryInstance extends AbstractDiscoveryInstance {\n  private static final AtomicLong INSTANCE_ID = new AtomicLong();\n\n  private final RegistryBean registryBean;\n\n  private final LocalRegistrationInstance localRegistrationInstance;\n\n  private final List<String> endpoints;\n\n  private final String instanceId;\n\n  public LocalDiscoveryInstance(LocalOpenAPIRegistry localOpenAPIRegistry,\n      RegistryBean registryBean, List<String> endpoints,\n      LocalRegistrationInstance localRegistrationInstance) {\n    this.registryBean = registryBean;\n    this.localRegistrationInstance = localRegistrationInstance;\n    this.endpoints = endpoints;\n    this.instanceId = System.currentTimeMillis() + \"-\" +\n        ManagementFactory.getRuntimeMXBean().getPid() + \"-\" + INSTANCE_ID.getAndIncrement();\n\n    registryBean.getSchemaInterfaces().forEach((k, v) -> {\n      SwaggerGenerator generator = SwaggerGenerator.create(v);\n      OpenAPI openAPI = generator.generate();\n      if (openAPI == null) {\n        throw new IllegalStateException(String.format(\"Generate schema for %s/%s/%s failed.\",\n            registryBean.getAppId(), registryBean.getServiceName(), k));\n      }\n      String schemaContent = SwaggerUtils.swaggerToString(openAPI);\n      if (StringUtils.isEmpty(schemaContent)) {\n        throw new IllegalStateException(String.format(\"Generate schema for %s/%s/%s failed.\",\n            registryBean.getAppId(), registryBean.getServiceName(), k));\n      }\n      localOpenAPIRegistry.registerOpenAPI(registryBean.getAppId(), registryBean.getServiceName(),\n          k, openAPI);\n    });\n  }\n\n  public LocalDiscoveryInstance(LocalRegistrationInstance registrationInstance) {\n    this.registryBean = new RegistryBean();\n    this.registryBean.setAppId(registrationInstance.getApplication());\n    this.registryBean.setServiceName(registrationInstance.getServiceName());\n    this.registryBean.setVersion(registrationInstance.getVersion());\n    this.localRegistrationInstance = registrationInstance;\n    this.endpoints = registrationInstance.getEndpoints();\n    this.instanceId = registrationInstance.getInstanceId();\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return MicroserviceInstanceStatus.UP;\n  }\n\n  @Override\n  public String getRegistryName() {\n    return LocalRegistryConst.LOCAL_REGISTRY_NAME;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return localRegistrationInstance.getEnvironment();\n  }\n\n  @Override\n  public String getApplication() {\n    return registryBean.getAppId();\n  }\n\n  @Override\n  public String getServiceName() {\n    return registryBean.getServiceName();\n  }\n\n  @Override\n  public String getAlias() {\n    return null;\n  }\n\n  @Override\n  public String getVersion() {\n    return registryBean.getVersion();\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return null;\n  }\n\n  @Override\n  public String getDescription() {\n    return null;\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return null;\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    // not implement\n    return Collections.emptyMap();\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  @Override\n  public String getInstanceId() {\n    return instanceId;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.localregistry;\n\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class LocalRegistration implements Registration<LocalRegistrationInstance> {\n  private final LocalRegistrationInstance localRegistrationInstance;\n\n  private Environment environment;\n\n  public LocalRegistration(LocalRegistrationInstance localRegistrationInstance) {\n    this.localRegistrationInstance = localRegistrationInstance;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void init() {\n\n  }\n\n  @Override\n  public void run() {\n\n  }\n\n  @Override\n  public void destroy() {\n\n  }\n\n  @Override\n  public String name() {\n    return LocalRegistryConst.LOCAL_REGISTRY_NAME;\n  }\n\n  @Override\n  public LocalRegistrationInstance getMicroserviceInstance() {\n    return localRegistrationInstance;\n  }\n\n  @Override\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    return true;\n  }\n\n  @Override\n  public void addSchema(String schemaId, String content) {\n    // not implement\n  }\n\n  @Override\n  public void addEndpoint(String endpoint) {\n    localRegistrationInstance.addEndpoint(endpoint);\n  }\n\n  @Override\n  public void addProperty(String key, String value) {\n    localRegistrationInstance.addProperty(key, value);\n  }\n\n  @Override\n  public boolean enabled() {\n    return this.environment.getProperty(LocalRegistryConst.LOCAL_REGISTRY_ENABLED, Boolean.class, true);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.localregistry;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\nimport org.springframework.core.env.Environment;\n\npublic class LocalRegistrationInstance implements RegistrationInstance {\n  private final Environment environment;\n\n  private final DataCenterInfo dataCenterInfo;\n\n  private final LocalOpenAPIRegistry localOpenAPIRegistry;\n\n  private final String instanceId;\n\n  private final Map<String, String> schemas = new HashMap<>();\n\n  private final List<String> endpoints = new ArrayList<>();\n\n  private final Map<String, String> properties = new HashMap<>();\n\n  public LocalRegistrationInstance(\n      Environment environment,\n      DataCenterProperties dataCenterProperties,\n      LocalOpenAPIRegistry localOpenAPIRegistry,\n      RegistrationId registrationId) {\n    this.environment = environment;\n    this.localOpenAPIRegistry = localOpenAPIRegistry;\n\n    this.dataCenterInfo = new DataCenterInfo();\n    this.dataCenterInfo.setName(dataCenterProperties.getName());\n    this.dataCenterInfo.setRegion(dataCenterProperties.getRegion());\n    this.dataCenterInfo.setAvailableZone(dataCenterProperties.getAvailableZone());\n\n    this.properties.putAll(BootStrapProperties.readServiceProperties(environment));\n\n    this.instanceId = registrationId.getInstanceId();\n  }\n\n  @Override\n  public String getEnvironment() {\n    return BootStrapProperties.readServiceEnvironment(environment);\n  }\n\n  @Override\n  public String getApplication() {\n    return BootStrapProperties.readApplication(environment);\n  }\n\n  @Override\n  public String getServiceName() {\n    return BootStrapProperties.readServiceName(environment);\n  }\n\n  @Override\n  public String getAlias() {\n    return BootStrapProperties.readServiceAlias(environment);\n  }\n\n  @Override\n  public String getVersion() {\n    return BootStrapProperties.readServiceVersion(environment);\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return dataCenterInfo;\n  }\n\n  @Override\n  public String getDescription() {\n    return BootStrapProperties.readServiceDescription(environment);\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return this.properties;\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return this.schemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return this.endpoints;\n  }\n\n  @Override\n  public String getInstanceId() {\n    return this.instanceId;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return MicroserviceInstanceStatus.UP;\n  }\n\n  public void addEndpoint(String endpoint) {\n    this.endpoints.add(endpoint);\n  }\n\n  public void addProperty(String key, String value) {\n    this.properties.put(key, value);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistryConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.localregistry;\n\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\npublic class LocalRegistryConfiguration {\n  @Bean\n  public LocalRegistrationInstance localRegistrationInstance(\n      Environment environment,\n      DataCenterProperties dataCenterProperties,\n      LocalOpenAPIRegistry localOpenAPIRegistry,\n      RegistrationId registrationId) {\n    return new LocalRegistrationInstance(environment, dataCenterProperties, localOpenAPIRegistry, registrationId);\n  }\n\n  @Bean\n  public LocalRegistration localRegistration(LocalRegistrationInstance localRegistrationInstance) {\n    return new LocalRegistration(localRegistrationInstance);\n  }\n\n  @Bean\n  public LocalDiscovery localDiscovery() {\n    return new LocalDiscovery();\n  }\n\n  @Bean\n  public LocalRegistryStore localRegistryStore() {\n    return new LocalRegistryStore();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistryConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.localregistry;\n\npublic class LocalRegistryConst {\n  public static final String LOCAL_REGISTRY_ENABLED = \"servicecomb.registry.local.enabled\";\n\n  public static final String LOCAL_REGISTRY_NAME = \"local-registry\";\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistryStore.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.localregistry;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Enumeration;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.servicecomb.config.YAMLUtil;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.common.utils.JvmUtils;\nimport org.apache.servicecomb.localregistry.RegistryBean.Instance;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class LocalRegistryStore {\n  private static final String REGISTRY_FILE_NAME = \"registry.yaml\";\n\n  private LocalRegistrationInstance selfMicroserviceInstance;\n\n  private LocalOpenAPIRegistry localOpenAPIRegistry;\n\n  // application:serviceName\n  private final Map<String, Map<String, List<LocalDiscoveryInstance>>>\n      microserviceInstanceMap = new ConcurrentHashMap<>();\n\n  public LocalRegistryStore() {\n\n  }\n\n  @Autowired\n  public void setLocalRegistrationInstance(LocalRegistrationInstance selfMicroserviceInstance) {\n    this.selfMicroserviceInstance = selfMicroserviceInstance;\n  }\n\n  @Autowired\n  public void setLocalOpenAPIRegistry(LocalOpenAPIRegistry localOpenAPIRegistry) {\n    this.localOpenAPIRegistry = localOpenAPIRegistry;\n  }\n\n  public void init() {\n    microserviceInstanceMap.clear();\n  }\n\n  public void run() {\n    List<RegistryBean> beans = loadYamlBeans();\n    BeanUtils.getBeansOfType(RegistryBean.class).forEach((key, value) -> beans.add(value));\n\n    initRegistryFromBeans(beans);\n\n    addSelf();\n  }\n\n  private void addSelf() {\n    microserviceInstanceMap.computeIfAbsent(selfMicroserviceInstance.getApplication(), key ->\n        new ConcurrentHashMapEx<>()).computeIfAbsent(selfMicroserviceInstance.getServiceName(), key ->\n        new ArrayList<>()).add(new LocalDiscoveryInstance(selfMicroserviceInstance));\n  }\n\n  private List<RegistryBean> loadYamlBeans() {\n    List<RegistryBean> beans = new ArrayList<>();\n\n    try {\n      ClassLoader loader = JvmUtils.findClassLoader();\n      Enumeration<URL> urls = loader.getResources(REGISTRY_FILE_NAME);\n\n      while (urls.hasMoreElements()) {\n        URL url = urls.nextElement();\n\n        try (InputStream is = url.openStream()) {\n          if (is != null) {\n            beans.addAll(initFromData(is));\n          }\n        }\n      }\n    } catch (IOException e) {\n      throw new IllegalStateException(e);\n    }\n\n    return beans;\n  }\n\n  private List<RegistryBean> initFromData(InputStream is) {\n    Map<String, Object> data = YAMLUtil.yaml2Properties(is);\n    return initFromData(data);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private List<RegistryBean> initFromData(Map<String, Object> data) {\n    List<RegistryBean> beans = new ArrayList<>();\n\n    for (Entry<String, Object> entry : data.entrySet()) {\n      String name = entry.getKey();\n      List<Map<String, Object>> serviceConfigs = (List<Map<String, Object>>) entry.getValue();\n      for (Map<String, Object> serviceConfig : serviceConfigs) {\n        beans.add(RegistryBean.buildFromYamlModel(name, serviceConfig));\n      }\n    }\n    return beans;\n  }\n\n  private void initRegistryFromBeans(List<RegistryBean> beans) {\n    beans.forEach((bean -> {\n      List<LocalDiscoveryInstance> instances = microserviceInstanceMap.computeIfAbsent(bean.getAppId(), key ->\n          new ConcurrentHashMapEx<>()).computeIfAbsent(bean.getServiceName(), key ->\n          new ArrayList<>());\n      if (bean.getInstances() == null) {\n        return;\n      }\n      for (Instance instance : bean.getInstances().getInstances()) {\n        instances.add(new LocalDiscoveryInstance(localOpenAPIRegistry,\n            bean, instance.getEndpoints(), selfMicroserviceInstance));\n      }\n    }));\n  }\n\n  public List<LocalDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    Map<String, List<LocalDiscoveryInstance>> app = microserviceInstanceMap.get(application);\n    if (app == null) {\n      return Collections.emptyList();\n    }\n    List<LocalDiscoveryInstance> instances = app.get(serviceName);\n    if (instances == null) {\n      return Collections.emptyList();\n    }\n    return instances;\n  }\n\n  public List<String> findServices(String application) {\n    if (microserviceInstanceMap.get(application) == null) {\n      return Collections.emptyList();\n    }\n    return microserviceInstanceMap.get(application).keySet().stream().toList();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/RegistryBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.localregistry;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\n\n/**\n *\n * Configuration bean for local services. Bean configuration is token\n * same as `registry.yaml` file configuration.\n *\n */\npublic class RegistryBean {\n  public static class Instances {\n    private List<Instance> instances;\n\n    public List<Instance> getInstances() {\n      return instances;\n    }\n\n    public Instances setInstances(List<Instance> instances) {\n      this.instances = instances;\n      return this;\n    }\n  }\n\n  public static class Instance {\n    private List<String> endpoints;\n\n    public List<String> getEndpoints() {\n      return endpoints;\n    }\n\n    public Instance setEndpoints(List<String> endpoints) {\n      this.endpoints = endpoints;\n      return this;\n    }\n  }\n\n  private String id;\n\n  private String serviceName;\n\n  private String version;\n\n  private String appId;\n\n  /**\n   * Schema ids configured from RegistryBean. Generate schema content from Class.\n   */\n  private final Map<String, Class<?>> schemaInterfaces = new HashMap<>();\n\n  /**\n   * Schema ids configured in yaml. Will load contents from local file.\n   */\n  private List<String> schemaIds = new ArrayList<>();\n\n  private Instances instances;\n\n  @SuppressWarnings(\"unchecked\")\n  public static RegistryBean buildFromYamlModel\n      (String serviceName, Map<String, Object> serviceConfig) {\n    return new RegistryBean()\n        .setId(validId((String) serviceConfig.get(\"id\")))\n        .setServiceName(serviceName)\n        .setVersion((String) serviceConfig.get(\"version\"))\n        .setAppId(validAppId((String) serviceConfig.get(\"appid\")))\n        .setSchemaIds(validListsValue((List<String>) serviceConfig.get(\"schemaIds\")))\n        .setInstances(\n            new Instances()\n                .setInstances(validInstances((List<Map<String, Object>>) serviceConfig.get(\"instances\"))));\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private static List<Instance> validInstances(List<Map<String, Object>> instancesConfig) {\n    if (instancesConfig == null) {\n      return Collections.emptyList();\n    }\n\n    List<Instance> instances = new ArrayList<>();\n    for (Map<String, Object> instanceConfig : instancesConfig) {\n      instances.add(new Instance().setEndpoints(\n          validListsValue((List<String>) instanceConfig.get(\"endpoints\"))));\n    }\n    return instances;\n  }\n\n  private static List<String> validListsValue(List<String> listsValue) {\n    return listsValue == null ? Collections.emptyList() : listsValue;\n  }\n\n  private static String validId(String serviceId) {\n    return StringUtils.isEmpty(serviceId) ? UUID.randomUUID().toString() : serviceId;\n  }\n\n  private static String validAppId(String configAppId) {\n    if (!StringUtils.isEmpty(configAppId)) {\n      return configAppId;\n    }\n    return BootStrapProperties.DEFAULT_APPLICATION;\n  }\n\n  public String getId() {\n    return id;\n  }\n\n  public RegistryBean setId(String id) {\n    this.id = id;\n    return this;\n  }\n\n  public String getServiceName() {\n    return serviceName;\n  }\n\n  public RegistryBean setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n    return this;\n  }\n\n  public String getVersion() {\n    return version;\n  }\n\n  public RegistryBean setVersion(String version) {\n    this.version = version;\n    return this;\n  }\n\n  public String getAppId() {\n    return appId;\n  }\n\n  public RegistryBean setAppId(String appId) {\n    this.appId = appId;\n    return this;\n  }\n\n  public RegistryBean addSchemaInterface(String schemaId, Class<?> schemaInterface) {\n    this.schemaInterfaces.put(schemaId, schemaInterface);\n    return this;\n  }\n\n  public RegistryBean addSchemaId(String schemaId) {\n    this.schemaIds.add(schemaId);\n    return this;\n  }\n\n  public RegistryBean setSchemaIds(List<String> schemaIds) {\n    this.schemaIds = schemaIds;\n    return this;\n  }\n\n  public List<String> getSchemaIds() {\n    return this.schemaIds;\n  }\n\n  public Map<String, Class<?>> getSchemaInterfaces() {\n    return this.schemaInterfaces;\n  }\n\n  public Instances getInstances() {\n    return instances;\n  }\n\n  public RegistryBean setInstances(Instances instances) {\n    this.instances = instances;\n    return this;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-local/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.localregistry.LocalRegistryConfiguration\n"
  },
  {
    "path": "service-registry/registry-nacos/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>service-registry-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-nacos</artifactId>\n  <name>Java Chassis::Service Registry::Nacos</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>com.alibaba.nacos</groupId>\n      <artifactId>nacos-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\npublic class NacosConfiguration {\n  @Bean\n  @ConfigurationProperties(prefix = NacosConst.NACOS_REGISTRY_PREFIX)\n  public NacosDiscoveryProperties nacosDiscoveryProperties() {\n    return new NacosDiscoveryProperties();\n  }\n\n  @Bean\n  public NacosRegistration nacosRegistration(\n      DataCenterProperties dataCenterProperties,\n      @Qualifier(\"nacosDiscoveryProperties\") NacosDiscoveryProperties nacosDiscoveryProperties,\n      Environment environment, RegistrationId registrationId) {\n    return new NacosRegistration(dataCenterProperties, nacosDiscoveryProperties, environment, registrationId);\n  }\n\n  @Bean\n  public NacosDiscovery nacosDiscovery(\n      @Qualifier(\"nacosDiscoveryProperties\") NacosDiscoveryProperties nacosDiscoveryProperties) {\n    return new NacosDiscovery(nacosDiscoveryProperties);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\npublic class NacosConst {\n  public static final String PROPERTY_VERSION = \"scb-version\";\n\n  public static final String PROPERTY_ALIAS = \"scb-alias\";\n\n  public static final String PROPERTY_DESCRIPTION = \"scb-description\";\n\n  public static final String PROPERTY_ENDPOINT = \"scb-endpoint\";\n\n  public static final String PROPERTY_REGION = \"scb-region\";\n\n  public static final String PROPERTY_ZONE = \"scb-zone\";\n\n  public static final String PROPERTY_DATACENTER = \"scb-datacenter\";\n\n  public static final String PROPERTY_SCHEMA_PREFIX = \"scb-schema-\";\n\n  public static final String ENDPOINT_PROPERTY_SEPARATOR = \",\";\n\n  public static final String NACOS_REGISTRY_PREFIX = \"servicecomb.registry.nacos\";\n\n  public static final String SERVER_ADDR = \"serverAddr\";\n\n  public static final String USERNAME = \"username\";\n\n  public static final String PASSWORD = \"password\";\n\n  public static final String NAMESPACE = \"namespace\";\n\n  public static final String NACOS_NAMING_LOG_NAME = \"com.alibaba.nacos.naming.log.filename\";\n\n  public static final String ACCESS_KEY = \"accessKey\";\n\n  public static final String SECRET_KEY = \"secretKey\";\n\n  public static final String CLUSTER_NAME = \"clusterName\";\n\n  public static final String NAMING_LOAD_CACHE_AT_START = \"namingLoadCacheAtStart\";\n\n  public static final String NACOS_REGISTRY_NAME = \"nacos-registry\";\n\n  public static final String NACOS_STATUS = \"nacos-status\";\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport com.alibaba.nacos.api.exception.NacosException;\n\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport com.alibaba.nacos.api.naming.NamingService;\nimport com.alibaba.nacos.api.naming.listener.NamingEvent;\nimport com.alibaba.nacos.api.naming.pojo.Instance;\n\npublic class NacosDiscovery implements Discovery<NacosDiscoveryInstance> {\n  public static final String NACOS_DISCOVERY_ENABLED = \"servicecomb.registry.nacos.%s.%s.enabled\";\n\n  private static final Map<String, Map<String, AtomicBoolean>> SUBSCRIBES = new HashMap<>();\n\n  private final Object lock = new Object();\n\n  private final NacosDiscoveryProperties nacosDiscoveryProperties;\n\n  private Environment environment;\n\n  private NamingService namingService;\n\n  private InstanceChangedListener<NacosDiscoveryInstance> instanceChangedListener;\n\n  @Autowired\n  public NacosDiscovery(NacosDiscoveryProperties nacosDiscoveryProperties) {\n    this.nacosDiscoveryProperties = nacosDiscoveryProperties;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public String name() {\n    return NacosConst.NACOS_REGISTRY_NAME;\n  }\n\n  @Override\n  public boolean enabled(String application, String serviceName) {\n    return environment.getProperty(String.format(NACOS_DISCOVERY_ENABLED, application, serviceName),\n        boolean.class, true);\n  }\n\n  @Override\n  public List<NacosDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    try {\n      // Get the instance first, and the Listener will not be executed for the first subscribe.\n      List<Instance> instances = namingService.getAllInstances(serviceName, application, true);\n\n      AtomicBoolean result = SUBSCRIBES.computeIfAbsent(application,\n          k -> new HashMap<>()).computeIfAbsent(serviceName, k -> new AtomicBoolean(true));\n      if (result.get()) {\n        synchronized (lock) {\n          if (result.get()) {\n            namingService.subscribe(serviceName, application, (event) -> {\n              if (event instanceof NamingEvent) {\n                this.instanceChangedListener.onInstanceChanged(name(), application, serviceName,\n                    convertServiceInstanceList(((NamingEvent) event).getInstances(), application, serviceName));\n              }\n            });\n            result.set(false);\n          }\n        }\n      }\n      return convertServiceInstanceList(instances, application, serviceName);\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n    try {\n      return namingService.getServicesOfServer(0, Integer.MAX_VALUE, application)\n          .getData();\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  private List<NacosDiscoveryInstance> convertServiceInstanceList(\n      List<Instance> instances, String application, String serviceName) {\n    if (CollectionUtils.isEmpty(instances)) {\n      return Collections.emptyList();\n    }\n    List<NacosDiscoveryInstance> result = new ArrayList<>();\n    for (Instance instance : instances) {\n      result.add(new NacosDiscoveryInstance(instance, application, serviceName, environment));\n    }\n    return result;\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<NacosDiscoveryInstance> instanceChangedListener) {\n    this.instanceChangedListener = instanceChangedListener;\n  }\n\n  @Override\n  public void init() {\n    namingService = NamingServiceManager.buildNamingService(environment, nacosDiscoveryProperties);\n  }\n\n  @Override\n  public void run() {\n\n  }\n\n  @Override\n  public void destroy() {\n    if (namingService != null) {\n      try {\n        namingService.shutDown();\n      } catch (NacosException e) {\n        throw new IllegalStateException(\"destroy process is interrupted.\");\n      }\n    }\n  }\n\n  @Override\n  public boolean enabled() {\n    return nacosDiscoveryProperties.isEnabled();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.registry.api.AbstractDiscoveryInstance;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.springframework.core.env.Environment;\n\nimport com.alibaba.nacos.api.naming.pojo.Instance;\n\npublic class NacosDiscoveryInstance extends AbstractDiscoveryInstance {\n  private final Instance instance;\n\n  private final String application;\n\n  private final String serviceName;\n\n  private final Environment environment;\n\n  private final Map<String, String> schemas;\n\n  private final List<String> endpoints;\n\n  public NacosDiscoveryInstance(Instance instance, String application, String serviceName,\n      Environment environment) {\n    this.instance = instance;\n    this.environment = environment;\n    this.application = application;\n    this.serviceName = serviceName;\n    this.endpoints = readEndpoints(instance);\n    this.schemas = readSchemas(instance);\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    if (instance.isEnabled()) {\n      String instanceStatus = instance.getMetadata().get(NacosConst.NACOS_STATUS);\n      if (StringUtils.isBlank(instanceStatus)) {\n        return MicroserviceInstanceStatus.UP;\n      }\n      return MicroserviceInstanceStatus.valueOf(instanceStatus);\n    } else {\n      return MicroserviceInstanceStatus.DOWN;\n    }\n  }\n\n  @Override\n  public String getRegistryName() {\n    return NacosConst.NACOS_REGISTRY_NAME;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return BootStrapProperties.readServiceEnvironment(environment);\n  }\n\n  @Override\n  public String getApplication() {\n    return this.application;\n  }\n\n  @Override\n  public String getServiceName() {\n    // nacos instance service name may contain group and `@` annotations\n    return this.serviceName;\n  }\n\n  @Override\n  public String getAlias() {\n    return instance.getMetadata().get(NacosConst.PROPERTY_ALIAS);\n  }\n\n  @Override\n  public String getVersion() {\n    return instance.getMetadata().get(NacosConst.PROPERTY_VERSION);\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    DataCenterInfo dataCenterInfo = new DataCenterInfo();\n    dataCenterInfo.setRegion(instance.getMetadata().get(NacosConst.PROPERTY_REGION));\n    dataCenterInfo.setAvailableZone(instance.getMetadata().get(NacosConst.PROPERTY_ZONE));\n    dataCenterInfo.setName(instance.getMetadata().get(NacosConst.PROPERTY_DATACENTER));\n    return dataCenterInfo;\n  }\n\n  @Override\n  public String getDescription() {\n    return instance.getMetadata().get(NacosConst.PROPERTY_DESCRIPTION);\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return instance.getMetadata();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return schemas;\n  }\n\n  private static Map<String, String> readSchemas(Instance instance) {\n    Map<String, String> metaData = instance.getMetadata();\n    Map<String, String> instanceSchemas = new HashMap<>();\n    for (Map.Entry<String, String> entry : metaData.entrySet()) {\n      if (entry.getKey().startsWith(NacosConst.PROPERTY_SCHEMA_PREFIX)) {\n        instanceSchemas.put(entry.getKey().substring(NacosConst.PROPERTY_SCHEMA_PREFIX.length()),\n            entry.getValue());\n      }\n    }\n    return instanceSchemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  private static List<String> readEndpoints(Instance instance) {\n    if (StringUtils.isEmpty(instance.getMetadata().get(NacosConst.PROPERTY_ENDPOINT))) {\n      // interoperate with spring cloud using nacos\n      if (StringUtils.isNotEmpty(instance.getIp()) && instance.getPort() > 0) {\n        return List.of(\"rest://\" + instance.getIp() + \":\" + instance.getPort());\n      }\n      return Collections.emptyList();\n    }\n    return Arrays.asList(instance.getMetadata().get(NacosConst.PROPERTY_ENDPOINT)\n        .split(NacosConst.ENDPOINT_PROPERTY_SEPARATOR));\n  }\n\n  @Override\n  public String getInstanceId() {\n    return instance.getInstanceId();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscoveryProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class NacosDiscoveryProperties {\n  private boolean enabled = true;\n\n  private String serverAddr = \"http://127.0.0.1:8848\";\n\n  private Map<String, String> metadata = new HashMap<>();\n\n  private boolean ephemeral = true;\n\n  private String username;\n\n  private String password;\n\n  private String accessKey;\n\n  private String secretKey;\n\n  private String namingLoadCacheAtStart = \"false\";\n\n  private String clusterName = \"DEFAULT\";\n\n  private float weight = 1;\n\n  private boolean instanceEnabled = true;\n\n  private String logName;\n\n  private boolean enableSwaggerRegistration = false;\n\n  public String getServerAddr() {\n    return serverAddr;\n  }\n\n  public void setServerAddr(String serverAddr) {\n    this.serverAddr = serverAddr;\n  }\n\n  public boolean isEnabled() {\n    return enabled;\n  }\n\n  public void setEnabled(boolean enabled) {\n    this.enabled = enabled;\n  }\n\n  public Map<String, String> getMetadata() {\n    return metadata;\n  }\n\n  public void setMetadata(Map<String, String> metadata) {\n    this.metadata = metadata;\n  }\n\n  public boolean isEphemeral() {\n    return ephemeral;\n  }\n\n  public void setEphemeral(boolean ephemeral) {\n    this.ephemeral = ephemeral;\n  }\n\n  public String getUsername() {\n    return username;\n  }\n\n  public void setUsername(String username) {\n    this.username = username;\n  }\n\n  public String getPassword() {\n    return password;\n  }\n\n  public void setPassword(String password) {\n    this.password = password;\n  }\n\n  public String getAccessKey() {\n    return accessKey;\n  }\n\n  public void setAccessKey(String accessKey) {\n    this.accessKey = accessKey;\n  }\n\n  public String getSecretKey() {\n    return secretKey;\n  }\n\n  public void setSecretKey(String secretKey) {\n    this.secretKey = secretKey;\n  }\n\n  public String getNamingLoadCacheAtStart() {\n    return namingLoadCacheAtStart;\n  }\n\n  public void setNamingLoadCacheAtStart(String namingLoadCacheAtStart) {\n    this.namingLoadCacheAtStart = namingLoadCacheAtStart;\n  }\n\n  public String getClusterName() {\n    return clusterName;\n  }\n\n  public void setClusterName(String clusterName) {\n    this.clusterName = clusterName;\n  }\n\n  public float getWeight() {\n    return weight;\n  }\n\n  public void setWeight(float weight) {\n    this.weight = weight;\n  }\n\n  public boolean isInstanceEnabled() {\n    return instanceEnabled;\n  }\n\n  public void setInstanceEnabled(boolean instanceEnabled) {\n    this.instanceEnabled = instanceEnabled;\n  }\n\n  public String getLogName() {\n    return logName;\n  }\n\n  public void setLogName(String logName) {\n    this.logName = logName;\n  }\n\n  public boolean isEnableSwaggerRegistration() {\n    return enableSwaggerRegistration;\n  }\n\n  public void setEnableSwaggerRegistration(boolean enableSwaggerRegistration) {\n    this.enableSwaggerRegistration = enableSwaggerRegistration;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosMicroserviceHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.springframework.core.env.Environment;\n\nimport com.alibaba.nacos.api.naming.pojo.Instance;\nimport com.alibaba.nacos.api.naming.utils.NamingUtils;\n\npublic class NacosMicroserviceHandler {\n  private static final String VERSION_MAPPING = \"VERSION_MAPPING\";\n\n  private static final String CAS_APPLICATION_ID = \"CAS_APPLICATION_ID\";\n\n  private static final String CAS_COMPONENT_NAME = \"CAS_COMPONENT_NAME\";\n\n  private static final String CAS_INSTANCE_VERSION = \"CAS_INSTANCE_VERSION\";\n\n  private static final String CAS_INSTANCE_ID = \"CAS_INSTANCE_ID\";\n\n  private static final String CAS_ENVIRONMENT_ID = \"CAS_ENVIRONMENT_ID\";\n\n  private static final String INSTANCE_PROPS = \"SERVICECOMB_INSTANCE_PROPS\";\n\n  public static Instance createMicroserviceInstance(\n      DataCenterProperties dataCenterProperties, NacosDiscoveryProperties properties, Environment environment) {\n    Instance instance = new Instance();\n    instance.setServiceName(NamingUtils.getGroupedName(\n        BootStrapProperties.readServiceName(environment), BootStrapProperties.readApplication(environment)));\n    instance.setWeight(properties.getWeight());\n    instance.setEnabled(properties.isInstanceEnabled());\n    instance.setClusterName(properties.getClusterName());\n    instance.setEphemeral(properties.isEphemeral());\n\n    Map<String, String> metadata = properties.getMetadata();\n    metadata.put(NacosConst.PROPERTY_VERSION, BootStrapProperties.readServiceVersion(environment));\n    metadata.put(NacosConst.PROPERTY_ALIAS, BootStrapProperties.readServiceAlias(environment));\n    metadata.put(NacosConst.PROPERTY_DESCRIPTION, BootStrapProperties.readServiceDescription(environment));\n    metadata.put(NacosConst.PROPERTY_DATACENTER, dataCenterProperties.getName());\n    metadata.put(NacosConst.PROPERTY_REGION, dataCenterProperties.getRegion());\n    metadata.put(NacosConst.PROPERTY_ZONE, dataCenterProperties.getAvailableZone());\n    if (!StringUtils.isEmpty(environment.getProperty(VERSION_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(VERSION_MAPPING)))) {\n      metadata.put(\"version\", environment.getProperty(environment.getProperty(VERSION_MAPPING)));\n    }\n    metadata.putAll(genCasProperties(environment));\n    instance.setMetadata(metadata);\n    return instance;\n  }\n\n  private static Map<String, String> genCasProperties(Environment environment) {\n    Map<String, String> properties = new HashMap<>();\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_APPLICATION_ID))) {\n      properties.put(CAS_APPLICATION_ID, environment.getProperty(CAS_APPLICATION_ID));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_COMPONENT_NAME))) {\n      properties.put(CAS_COMPONENT_NAME, environment.getProperty(CAS_COMPONENT_NAME));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_INSTANCE_VERSION))) {\n      properties.put(CAS_INSTANCE_VERSION, environment.getProperty(CAS_INSTANCE_VERSION));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_INSTANCE_ID))) {\n      properties.put(CAS_INSTANCE_ID, environment.getProperty(CAS_INSTANCE_ID));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_ENVIRONMENT_ID))) {\n      properties.put(CAS_ENVIRONMENT_ID, environment.getProperty(CAS_ENVIRONMENT_ID));\n    }\n\n    String[] instancePropArray = ConfigUtil.parseArrayValue(environment.getProperty(INSTANCE_PROPS))\n        .toArray(new String[0]);\n    if (instancePropArray.length != 0) {\n      properties.putAll(parseProps(instancePropArray));\n    }\n\n    return properties;\n  }\n\n  private static Map<String, String> parseProps(String... value) {\n    return Arrays.stream(value).map(v -> v.split(\":\"))\n        .filter(v -> v.length == 2)\n        .collect(Collectors.toMap(v -> v[0], v -> v[1]));\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.invocation.endpoint.EndpointUtils;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport com.alibaba.nacos.api.exception.NacosException;\nimport com.alibaba.nacos.api.naming.NamingService;\nimport com.alibaba.nacos.api.naming.pojo.Instance;\n\npublic class NacosRegistration implements Registration<NacosRegistrationInstance> {\n  private final NacosDiscoveryProperties nacosDiscoveryProperties;\n\n  private final Environment environment;\n\n  private final String instanceId;\n\n  private final DataCenterProperties dataCenterProperties;\n\n  private NacosRegistrationInstance nacosRegistrationInstance;\n\n  private Instance instance;\n\n  private NamingService namingService;\n\n  @Autowired\n  public NacosRegistration(DataCenterProperties dataCenterProperties, NacosDiscoveryProperties nacosDiscoveryProperties,\n      Environment environment, RegistrationId registrationId) {\n    this.instanceId = registrationId.getInstanceId();\n    this.dataCenterProperties = dataCenterProperties;\n    this.nacosDiscoveryProperties = nacosDiscoveryProperties;\n    this.environment = environment;\n  }\n\n  @Override\n  public void init() {\n    instance = NacosMicroserviceHandler.createMicroserviceInstance(dataCenterProperties, nacosDiscoveryProperties,\n        environment);\n    instance.setInstanceId(instanceId);\n    nacosRegistrationInstance = new NacosRegistrationInstance(instance, environment);\n    instance.getMetadata()\n        .put(NacosConst.NACOS_STATUS, BootStrapProperties.readServiceInstanceInitialStatus(environment));\n    namingService = NamingServiceManager.buildNamingService(environment, nacosDiscoveryProperties);\n  }\n\n  @Override\n  public void run() {\n    try {\n      if (nacosDiscoveryProperties.isEnableSwaggerRegistration()) {\n        addSchemas(nacosRegistrationInstance.getSchemas(), instance);\n      }\n      addEndpoints(nacosRegistrationInstance.getEndpoints(), instance);\n      namingService.registerInstance(nacosRegistrationInstance.getServiceName(),\n          nacosRegistrationInstance.getApplication(), instance);\n    } catch (NacosException e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  private static void addSchemas(Map<String, String> schemas, Instance instance) {\n    if (CollectionUtils.isEmpty(schemas)) {\n      return;\n    }\n    for (Map.Entry<String, String> entry : schemas.entrySet()) {\n      instance.addMetadata(NacosConst.PROPERTY_SCHEMA_PREFIX + entry.getKey(), entry.getValue());\n    }\n  }\n\n  private static void addEndpoints(List<String> endpoints, Instance instance) {\n    if (endpoints.isEmpty()) {\n      return;\n    }\n\n    for (String endpoint : endpoints) {\n      Endpoint temp = EndpointUtils.parse(endpoint);\n      if (temp.getAddress() instanceof URIEndpointObject) {\n        instance.setIp(((URIEndpointObject) temp.getAddress()).getHostOrIp());\n        instance.setPort(((URIEndpointObject) temp.getAddress()).getPort());\n        break;\n      }\n    }\n\n    instance.addMetadata(NacosConst.PROPERTY_ENDPOINT, String.join(NacosConst.ENDPOINT_PROPERTY_SEPARATOR, endpoints));\n  }\n\n  @Override\n  public void destroy() {\n    try {\n      namingService.deregisterInstance(nacosRegistrationInstance.getServiceName(),\n          nacosRegistrationInstance.getApplication(), instance);\n      namingService.shutDown();\n    } catch (NacosException e) {\n      throw new IllegalStateException(\"destroy process is interrupted.\");\n    }\n  }\n\n  @Override\n  public String name() {\n    return NacosConst.NACOS_REGISTRY_NAME;\n  }\n\n  @Override\n  public NacosRegistrationInstance getMicroserviceInstance() {\n    return this.nacosRegistrationInstance;\n  }\n\n  @Override\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    try {\n      instance.getMetadata().put(NacosConst.NACOS_STATUS, status.name());\n      namingService.registerInstance(nacosRegistrationInstance.getServiceName(),\n          nacosRegistrationInstance.getApplication(), instance);\n      return true;\n    } catch (Exception e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  @Override\n  public void addSchema(String schemaId, String content) {\n    if (nacosDiscoveryProperties.isEnableSwaggerRegistration()) {\n      nacosRegistrationInstance.addSchema(schemaId, content);\n    }\n  }\n\n  @Override\n  public void addEndpoint(String endpoint) {\n    nacosRegistrationInstance.addEndpoint(endpoint);\n  }\n\n  @Override\n  public void addProperty(String key, String value) {\n    instance.addMetadata(key, value);\n  }\n\n  @Override\n  public boolean enabled() {\n    return nacosDiscoveryProperties.isEnabled();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\nimport org.springframework.core.env.Environment;\n\nimport com.alibaba.nacos.api.naming.pojo.Instance;\n\npublic class NacosRegistrationInstance implements RegistrationInstance {\n  private final Instance instance;\n\n  private final Map<String, String> schemas = new HashMap<>();\n\n  private final List<String> endpoints = new ArrayList<>();\n\n  private final Environment environment;\n\n  public NacosRegistrationInstance(Instance instance,\n      Environment environment) {\n    this.instance = instance;\n    this.environment = environment;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return BootStrapProperties.readServiceEnvironment(environment);\n  }\n\n  @Override\n  public String getApplication() {\n    return BootStrapProperties.readApplication(environment);\n  }\n\n  @Override\n  public String getServiceName() {\n    return BootStrapProperties.readServiceName(environment);\n  }\n\n  @Override\n  public String getAlias() {\n    return BootStrapProperties.readServiceAlias(environment);\n  }\n\n  @Override\n  public String getVersion() {\n    return instance.getMetadata().get(NacosConst.PROPERTY_VERSION);\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    DataCenterInfo dataCenterInfo = new DataCenterInfo();\n    dataCenterInfo.setRegion(instance.getMetadata().get(NacosConst.PROPERTY_REGION));\n    dataCenterInfo.setAvailableZone(instance.getMetadata().get(NacosConst.PROPERTY_ZONE));\n    return dataCenterInfo;\n  }\n\n  @Override\n  public String getDescription() {\n    return BootStrapProperties.readServiceDescription(environment);\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return instance.getMetadata();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return schemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  @Override\n  public String getInstanceId() {\n    return instance.getInstanceId();\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return MicroserviceInstanceStatus.valueOf(instance.getMetadata().get(NacosConst.NACOS_STATUS));\n  }\n\n  public void addSchema(String schemaId, String content) {\n    this.schemas.put(schemaId, content);\n  }\n\n  public void addEndpoint(String endpoint) {\n    this.endpoints.add(endpoint);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NamingServiceManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.nacos;\n\nimport java.util.Objects;\nimport java.util.Properties;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.springframework.core.env.Environment;\n\nimport com.alibaba.nacos.api.exception.NacosException;\nimport com.alibaba.nacos.api.naming.NamingService;\nimport com.alibaba.nacos.client.naming.NacosNamingService;\n\npublic class NamingServiceManager {\n  private static volatile NamingService namingService;\n\n  public static NamingService buildNamingService(Environment environment, NacosDiscoveryProperties properties) {\n    if (Objects.isNull(namingService)) {\n      synchronized (NamingServiceManager.class) {\n        if (Objects.isNull(namingService)) {\n          try {\n            namingService = new NacosNamingService(getProperties(environment, properties));\n          } catch (NacosException e) {\n            throw new IllegalStateException(\"build namingService failed.\");\n          }\n        }\n      }\n    }\n    return namingService;\n  }\n\n  private static Properties getProperties(Environment environment,\n      NacosDiscoveryProperties nacosDiscoveryProperties) {\n    Properties properties = new Properties();\n    properties.put(NacosConst.NAMESPACE, BootStrapProperties.readServiceEnvironment(environment));\n    properties.put(NacosConst.SERVER_ADDR, nacosDiscoveryProperties.getServerAddr());\n    if (nacosDiscoveryProperties.getUsername() != null) {\n      properties.put(NacosConst.USERNAME, nacosDiscoveryProperties.getUsername());\n    }\n    if (nacosDiscoveryProperties.getPassword() != null) {\n      properties.put(NacosConst.PASSWORD, nacosDiscoveryProperties.getPassword());\n    }\n    if (nacosDiscoveryProperties.getAccessKey() != null) {\n      properties.put(NacosConst.ACCESS_KEY, nacosDiscoveryProperties.getAccessKey());\n    }\n    if (nacosDiscoveryProperties.getSecretKey() != null) {\n      properties.put(NacosConst.SECRET_KEY, nacosDiscoveryProperties.getSecretKey());\n    }\n    if (nacosDiscoveryProperties.getLogName() != null) {\n      properties.put(NacosConst.NACOS_NAMING_LOG_NAME, nacosDiscoveryProperties.getLogName());\n    }\n\n    properties.put(NacosConst.CLUSTER_NAME, nacosDiscoveryProperties.getClusterName());\n    properties.put(NacosConst.NAMING_LOAD_CACHE_AT_START, nacosDiscoveryProperties.getNamingLoadCacheAtStart());\n    return properties;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-nacos/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.nacos.NacosConfiguration\n"
  },
  {
    "path": "service-registry/registry-service-center/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>service-registry-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-service-center</artifactId>\n  <name>Java Chassis::Service Registry::Service Center</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>service-center-client</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-lang3</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/MicroserviceHandler.java",
    "content": "/*\n\n * Copyright (C) 2020-2022 Huawei Technologies Co., Ltd. All rights reserved.\n\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.service.center.client.model.DataCenterInfo;\nimport org.apache.servicecomb.service.center.client.model.Framework;\nimport org.apache.servicecomb.service.center.client.model.HealthCheck;\nimport org.apache.servicecomb.service.center.client.model.HealthCheckMode;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceStatus;\nimport org.springframework.core.env.Environment;\n\npublic class MicroserviceHandler {\n  private static final String SERVICE_MAPPING = \"SERVICE_MAPPING\";\n\n  private static final String VERSION_MAPPING = \"VERSION_MAPPING\";\n\n  private static final String APP_MAPPING = \"APP_MAPPING\";\n\n  private static final String CAS_APPLICATION_ID = \"CAS_APPLICATION_ID\";\n\n  private static final String CAS_COMPONENT_NAME = \"CAS_COMPONENT_NAME\";\n\n  private static final String CAS_INSTANCE_VERSION = \"CAS_INSTANCE_VERSION\";\n\n  private static final String CAS_INSTANCE_ID = \"CAS_INSTANCE_ID\";\n\n  private static final String CAS_ENVIRONMENT_ID = \"CAS_ENVIRONMENT_ID\";\n\n  private static final String SERVICE_PROPS = \"SERVICECOMB_SERVICE_PROPS\";\n\n  private static final String INSTANCE_PROPS = \"SERVICECOMB_INSTANCE_PROPS\";\n\n  public static Microservice createMicroservice(\n      Environment environment) {\n    Microservice microservice = new Microservice();\n    microservice.setProperties(BootStrapProperties.readServiceProperties(environment));\n    if (!StringUtils.isEmpty(environment.getProperty(APP_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(APP_MAPPING)))) {\n      microservice.setAppId(environment.getProperty(environment.getProperty(APP_MAPPING)));\n    } else {\n      microservice.setAppId(BootStrapProperties.readApplication(environment));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(SERVICE_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(SERVICE_MAPPING)))) {\n      microservice.setServiceName(environment.getProperty(environment.getProperty(SERVICE_MAPPING)));\n    } else {\n      microservice.setServiceName(BootStrapProperties.readServiceName(environment));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(VERSION_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(VERSION_MAPPING)))) {\n      microservice.setVersion(environment.getProperty(environment.getProperty(VERSION_MAPPING)));\n    } else {\n      microservice.setVersion(BootStrapProperties.readServiceVersion(environment));\n    }\n    microservice.setEnvironment(BootStrapProperties.readServiceEnvironment(environment));\n\n    Framework framework = createFramework();\n    microservice.setFramework(framework);\n    String[] servicePropArray = ConfigUtil.parseArrayValue(environment.getProperty(SERVICE_PROPS))\n        .toArray(new String[0]);\n    if (servicePropArray.length != 0) {\n      microservice.getProperties().putAll(parseProps(servicePropArray));\n    }\n\n    microservice.setStatus(MicroserviceStatus.UP);\n    return microservice;\n  }\n\n  private static Framework createFramework() {\n    Framework framework = new Framework();\n    framework.setName(\"ServiceComb\");\n    framework.setVersion(MicroserviceHandler.class.getPackage().getImplementationVersion());\n    return framework;\n  }\n\n  public static MicroserviceInstance createMicroserviceInstance(\n      Environment environment,\n      SCConfigurationProperties scConfigurationProperties,\n      DataCenterProperties dataCenterProperties) {\n    MicroserviceInstance microserviceInstance = new MicroserviceInstance();\n    String hostName = StringUtils.isEmpty(scConfigurationProperties.getHostname()) ? NetUtils.getHostName()\n        : scConfigurationProperties.getHostname();\n    if (hostName.length() > 64) {\n      hostName = hostName.substring(0, 64);\n    }\n    microserviceInstance.setHostName(hostName);\n\n    if (StringUtils.isNotEmpty(dataCenterProperties.getName())) {\n      DataCenterInfo dataCenterInfo = new DataCenterInfo();\n      dataCenterInfo.setName(dataCenterProperties.getName());\n      dataCenterInfo.setRegion(dataCenterProperties.getRegion());\n      dataCenterInfo.setAvailableZone(dataCenterProperties.getAvailableZone());\n      microserviceInstance.setDataCenterInfo(dataCenterInfo);\n    }\n\n    HealthCheck healthCheck = new HealthCheck();\n    healthCheck.setMode(HealthCheckMode.push);\n    healthCheck.setInterval(scConfigurationProperties.getHealthCheckIntervalInSeconds());\n    healthCheck.setTimes(scConfigurationProperties.getHealthCheckTimes());\n    microserviceInstance.setHealthCheck(healthCheck);\n    String currTime = String.valueOf(System.currentTimeMillis());\n    microserviceInstance.setTimestamp(currTime);\n    microserviceInstance.setModTimestamp(currTime);\n\n    // what's MicroserviceInstance doing? same sa Microservice?\n    if (!StringUtils.isEmpty(environment.getProperty(VERSION_MAPPING)) &&\n        !StringUtils.isEmpty(environment.getProperty(environment.getProperty(VERSION_MAPPING)))) {\n      microserviceInstance.setVersion(environment.getProperty(environment.getProperty(VERSION_MAPPING)));\n    } else {\n      microserviceInstance.setVersion(BootStrapProperties.readServiceVersion(environment));\n    }\n\n    Map<String, String> properties = new HashMap<>();\n    properties.putAll(BootStrapProperties.readServiceProperties(environment));\n    properties.putAll(genCasProperties(environment));\n    microserviceInstance.setProperties(properties);\n    microserviceInstance.setStatus(\n        MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment)));\n    return microserviceInstance;\n  }\n\n  private static Map<String, String> genCasProperties(Environment environment) {\n    Map<String, String> properties = new HashMap<>();\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_APPLICATION_ID))) {\n      properties.put(CAS_APPLICATION_ID, environment.getProperty(CAS_APPLICATION_ID));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_COMPONENT_NAME))) {\n      properties.put(CAS_COMPONENT_NAME, environment.getProperty(CAS_COMPONENT_NAME));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_INSTANCE_VERSION))) {\n      properties.put(CAS_INSTANCE_VERSION, environment.getProperty(CAS_INSTANCE_VERSION));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_INSTANCE_ID))) {\n      properties.put(CAS_INSTANCE_ID, environment.getProperty(CAS_INSTANCE_ID));\n    }\n    if (!StringUtils.isEmpty(environment.getProperty(CAS_ENVIRONMENT_ID))) {\n      properties.put(CAS_ENVIRONMENT_ID, environment.getProperty(CAS_ENVIRONMENT_ID));\n    }\n\n    String[] instancePropArray = ConfigUtil.parseArrayValue(environment.getProperty(INSTANCE_PROPS))\n        .toArray(new String[0]);\n    if (instancePropArray.length != 0) {\n      properties.putAll(parseProps(instancePropArray));\n    }\n\n    return properties;\n  }\n\n  private static Map<String, String> parseProps(String... value) {\n    return Arrays.stream(value).map(v -> v.split(\":\"))\n        .filter(v -> v.length == 2)\n        .collect(Collectors.toMap(v -> v[0], v -> v[1]));\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.http.client.event.RefreshEndpointEvent;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.HeartBeatEvent;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.exception.OperationException;\nimport org.apache.servicecomb.service.center.client.model.DataCenterInfo;\nimport org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.eventbus.Subscribe;\n\n/**\n * Support auto discovery of service center addresses.\n */\npublic class SCAddressManager {\n  public enum Type {\n    SERVICECENTER,\n    KIE,\n    CseConfigCenter,\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(SCAddressManager.class);\n\n  private final ServiceCenterClient serviceCenterClient;\n\n  private final SCRegistration scRegistration;\n\n  private final SCConfigurationProperties configurationProperties;\n\n  private final Map<String, HashSet<String>> lastEngineEndpointsCache = new HashMap<>();\n\n  public SCAddressManager(SCConfigurationProperties configurationProperties,\n      ServiceCenterClient serviceCenterClient,\n      SCRegistration scRegistration) {\n    this.configurationProperties = configurationProperties;\n    this.serviceCenterClient = serviceCenterClient;\n    this.scRegistration = scRegistration;\n    scRegistration.getEventBus().register(this);\n  }\n\n  @Subscribe\n  public void onHeartBeatEvent(HeartBeatEvent event) {\n    if (event.isSuccess() && configurationProperties.isAutoDiscovery()) {\n      for (Type type : Type.values()) {\n        initEndPort(type.name());\n      }\n    }\n  }\n\n  private void initEndPort(String key) {\n    List<MicroserviceInstance> instances = findServiceInstance(\"default\", key, \"0+\");\n    HashSet<String> currentEngineEndpoints = new HashSet<>();\n    Map<String, List<String>> zoneAndRegion = generateZoneAndRegionAddress(instances, currentEngineEndpoints);\n    if (zoneAndRegion == null) {\n      return;\n    }\n    if (isEngineEndpointsChanged(lastEngineEndpointsCache.get(key), currentEngineEndpoints)) {\n      LOGGER.info(\"auto discovery service [{}] addresses: [{}]\", key, zoneAndRegion);\n      lastEngineEndpointsCache.put(key, currentEngineEndpoints);\n      EventManager.post(new RefreshEndpointEvent(zoneAndRegion, key));\n    }\n  }\n\n  private boolean isEngineEndpointsChanged(Set<String> lastEngineEndpoints, Set<String> currentEngineEndpoints) {\n    if (lastEngineEndpoints == null || lastEngineEndpoints.isEmpty()) {\n      return true;\n    }\n    HashSet<String> compareTemp = new HashSet<>(lastEngineEndpoints);\n    compareTemp.removeAll(currentEngineEndpoints);\n    return !compareTemp.isEmpty() || lastEngineEndpoints.size() != currentEngineEndpoints.size();\n  }\n\n  private Map<String, List<String>> generateZoneAndRegionAddress(List<MicroserviceInstance> instances,\n      HashSet<String> currentEngineEndpoints) {\n    if (instances.isEmpty()) {\n      return null;\n    }\n\n    Map<String, List<String>> zoneAndRegion = new HashMap<>();\n    DataCenterInfo dataCenterInfo = findRegion(instances);\n\n    Set<String> sameZone = new HashSet<>();\n    Set<String> sameRegion = new HashSet<>();\n    for (MicroserviceInstance microserviceInstance : instances) {\n      if (regionAndAZMatch(dataCenterInfo, microserviceInstance)) {\n        sameZone.addAll(microserviceInstance.getEndpoints());\n      } else {\n        sameRegion.addAll(microserviceInstance.getEndpoints());\n      }\n      currentEngineEndpoints.addAll(microserviceInstance.getEndpoints());\n    }\n    zoneAndRegion.put(\"sameZone\", new ArrayList<>(sameZone));\n    zoneAndRegion.put(\"sameRegion\", new ArrayList<>(sameRegion));\n    return zoneAndRegion;\n  }\n\n  private DataCenterInfo findRegion(List<MicroserviceInstance> microserviceInstances) {\n    for (MicroserviceInstance microserviceInstance : microserviceInstances) {\n      boolean isMatch = microserviceInstance.getEndpoints().get(0)\n          .contains(scRegistration.getBackendMicroserviceInstance()\n              .getEndpoints().get(0));\n      if (isMatch && microserviceInstance.getDataCenterInfo() != null) {\n        return microserviceInstance.getDataCenterInfo();\n      }\n    }\n\n    if (scRegistration.getBackendMicroserviceInstance().getDataCenterInfo() == null) {\n      return null;\n    }\n    return scRegistration.getBackendMicroserviceInstance().getDataCenterInfo();\n  }\n\n  private List<MicroserviceInstance> findServiceInstance(String appId, String serviceName, String versionRule) {\n    try {\n      FindMicroserviceInstancesResponse instancesResponse = serviceCenterClient\n          .findMicroserviceInstance(scRegistration.getBackendMicroserviceInstance().getServiceId(),\n              appId, serviceName, versionRule, null);\n      return instancesResponse.getMicroserviceInstancesResponse().getInstances();\n    } catch (OperationException operationException) {\n      LOGGER.warn(\"not find the Microservice instance of {}\", serviceName);\n      return new ArrayList<>();\n    }\n  }\n\n  private boolean regionAndAZMatch(DataCenterInfo myself, MicroserviceInstance target) {\n    if (myself == null) {\n      return true;\n    }\n    if (target.getDataCenterInfo() != null) {\n      return myself.getRegion().equals(target.getDataCenterInfo().getRegion()) &&\n          myself.getAvailableZone().equals(target.getDataCenterInfo().getAvailableZone());\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.http.HttpHost;\nimport org.apache.http.auth.AuthScope;\nimport org.apache.http.auth.UsernamePasswordCredentials;\nimport org.apache.http.client.CredentialsProvider;\nimport org.apache.http.impl.client.BasicCredentialsProvider;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.apache.servicecomb.config.ConfigUtil;\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.ssl.SSLOptionFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxConst;\nimport org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;\nimport org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;\nimport org.apache.servicecomb.http.client.common.HttpTransport;\nimport org.apache.servicecomb.http.client.common.HttpTransportFactory;\nimport org.apache.servicecomb.service.center.client.ServiceCenterAddressManager;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterRawClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterWatch;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\npublic class SCClientUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SCClientUtils.class);\n\n  // Compatible chassis multi-registration center\n  private static final Map<String, ServiceCenterAddressManager> serviceAddressManagers = new ConcurrentHashMap<>();\n\n  public static ServiceCenterAddressManager createAddressManager(SCConfigurationProperties discoveryProperties,\n      Environment environment) {\n    List<String> addresses = ConfigUtil.parseArrayValue(discoveryProperties.getAddress());\n    return createAddressManager(\"default\", addresses, environment);\n  }\n\n  /**\n   * Ensure that the ServiceCenterAddressManager in the client created for RBAC authentication and registry discovery\n   * is the same. This ensures that when an error is reported due to the registry center address being unavailable,\n   * the authentication and registry discovery remain consistent.\n   *\n   * @param projectName projectName\n   * @param addresses   engine address\n   * @param environment environment\n   * @return Service Center Address Manager\n   */\n  public static ServiceCenterAddressManager createAddressManager(String projectName, List<String> addresses,\n      Environment environment) {\n    if (getServiceCenterAddressManager(addresses) == null) {\n      synchronized (SCClientUtils.class) {\n        if (getServiceCenterAddressManager(addresses) == null) {\n          String key = String.join(\",\", addresses);\n          LOGGER.info(\"initialize discovery server={}\", addresses);\n          String region = environment.getProperty(\"servicecomb.datacenter.region\");\n          String availableZone = environment.getProperty(\"servicecomb.datacenter.availableZone\");\n          ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(projectName, addresses,\n              EventManager.getEventBus(), region, availableZone);\n          serviceAddressManagers.put(key, addressManager);\n          return addressManager;\n        }\n      }\n    }\n    return getServiceCenterAddressManager(addresses);\n  }\n\n  private static ServiceCenterAddressManager getServiceCenterAddressManager(List<String> addresses) {\n    String forwardKey = String.join(\",\", addresses);\n    List<String> tempAddr = new ArrayList<>(addresses);\n    Collections.reverse(tempAddr);\n    String reverseKey = String.join(\",\", tempAddr);\n    if (serviceAddressManagers.get(forwardKey) != null) {\n      return serviceAddressManagers.get(forwardKey);\n    }\n    if (serviceAddressManagers.get(reverseKey) != null) {\n      return serviceAddressManagers.get(reverseKey);\n    }\n    return null;\n  }\n\n  // add other headers needed for registration by new ServiceCenterClient(...)\n  public static ServiceCenterClient serviceCenterClient(SCConfigurationProperties discoveryProperties,\n      Environment environment) {\n    ServiceCenterAddressManager addressManager = createAddressManager(discoveryProperties, environment);\n\n    SSLProperties sslProperties = buildSslProperties(addressManager, environment);\n\n    return new ServiceCenterClient(new ServiceCenterRawClient.Builder()\n        .setTenantName(\"default\")\n        .setAddressManager(addressManager)\n        .setHttpTransport(createHttpTransport(environment, sslProperties)).build(), addressManager);\n  }\n\n  private static HttpTransport createHttpTransport(Environment environment, SSLProperties sslProperties) {\n    List<AuthHeaderProvider> authHeaderProviders = SPIServiceUtils.getOrLoadSortedService(AuthHeaderProvider.class);\n\n    if (isProxyEnable(environment)) {\n      HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().\n          setDefaultRequestConfig(HttpTransportFactory.defaultRequestConfig().build());\n      HttpHost proxy = new HttpHost(getProxyHost(environment),\n          getProxyPort(environment), \"http\");  // now only support http proxy\n      httpClientBuilder.setProxy(proxy);\n      CredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n      credentialsProvider.setCredentials(new AuthScope(proxy),\n          new UsernamePasswordCredentials(getProxyUsername(environment),\n              getProxyPasswd(environment)));\n      httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n\n      return HttpTransportFactory\n          .createHttpTransport(sslProperties,\n              getRequestAuthHeaderProvider(authHeaderProviders), httpClientBuilder);\n    }\n\n    return HttpTransportFactory\n        .createHttpTransport(sslProperties,\n            getRequestAuthHeaderProvider(authHeaderProviders), HttpTransportFactory.defaultRequestConfig().build());\n  }\n\n  public static Boolean isProxyEnable(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_ENABLE, boolean.class, false);\n  }\n\n  public static String getProxyHost(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_HOST, \"127.0.0.1\");\n  }\n\n  public static int getProxyPort(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_PORT, int.class, 8080);\n  }\n\n  public static String getProxyUsername(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_USERNAME);\n  }\n\n  public static String getProxyPasswd(Environment environment) {\n    return environment.getProperty(VertxConst.PROXY_PASSWD);\n  }\n\n  private static SSLProperties buildSslProperties(ServiceCenterAddressManager addressManager,\n      Environment environment) {\n    SSLOptionFactory factory = SSLOptionFactory.createSSLOptionFactory(SCConst.SC_SSL_TAG,\n        environment);\n    SSLOption sslOption;\n    if (factory == null) {\n      sslOption = SSLOption.build(SCConst.SC_SSL_TAG, environment);\n    } else {\n      sslOption = factory.createSSLOption();\n    }\n    SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass());\n\n    SSLProperties sslProperties = new SSLProperties();\n    sslProperties.setSslCustom(sslCustom);\n    sslProperties.setSslOption(sslOption);\n    sslProperties.setEnabled(addressManager.sslEnabled());\n    return sslProperties;\n  }\n\n  public static ServiceCenterWatch serviceCenterWatch(SCConfigurationProperties discoveryProperties,\n      List<AuthHeaderProvider> authHeaderProviders, Environment environment) {\n    ServiceCenterAddressManager addressManager = createAddressManager(discoveryProperties, environment);\n    SSLProperties sslProperties = buildSslProperties(addressManager, environment);\n    return new ServiceCenterWatch(addressManager, sslProperties, getRequestAuthHeaderProvider(authHeaderProviders),\n        \"default\", new HashMap<>(), EventManager.getEventBus());\n  }\n\n  private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {\n    return signRequest -> {\n      String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : \"\";\n      Map<String, String> headers = new HashMap<>();\n      authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host)));\n      return headers;\n    };\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.auth.AuthHeaderProvider;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterWatch;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\n@Configuration\n@SuppressWarnings(\"unused\")\npublic class SCConfiguration {\n  @Bean\n  @ConfigurationProperties(prefix = SCConst.SC_REGISTRY_PREFIX)\n  public SCConfigurationProperties scConfigurationProperties() {\n    return new SCConfigurationProperties();\n  }\n\n  @Bean\n  public ServiceCenterClient serviceCenterClient(\n      @Qualifier(\"scConfigurationProperties\") SCConfigurationProperties scConfigurationProperties,\n      Environment environment) {\n    return SCClientUtils.serviceCenterClient(scConfigurationProperties, environment);\n  }\n\n  @Bean\n  public ServiceCenterWatch serviceCenterWatch(\n      @Qualifier(\"scConfigurationProperties\") SCConfigurationProperties scConfigurationProperties,\n      List<AuthHeaderProvider> authHeaderProviders, Environment environment) {\n    return SCClientUtils.serviceCenterWatch(scConfigurationProperties, authHeaderProviders, environment);\n  }\n\n  @Bean\n  public SCRegistration scRegistration(\n      @Qualifier(\"scConfigurationProperties\") SCConfigurationProperties scConfigurationProperties,\n      @Qualifier(\"serviceCenterClient\") ServiceCenterClient serviceCenterClient,\n      @Qualifier(\"serviceCenterWatch\") ServiceCenterWatch serviceCenterWatch) {\n    return new SCRegistration(scConfigurationProperties, serviceCenterClient, serviceCenterWatch);\n  }\n\n  @Bean\n  public SCDiscovery scDiscovery(\n      @Qualifier(\"scConfigurationProperties\") SCConfigurationProperties scConfigurationProperties,\n      @Qualifier(\"serviceCenterClient\") ServiceCenterClient serviceCenterClient) {\n    return new SCDiscovery(scConfigurationProperties, serviceCenterClient);\n  }\n\n  @Bean\n  public SCAddressManager scAddressManager(\n      @Qualifier(\"scConfigurationProperties\") SCConfigurationProperties scConfigurationProperties,\n      SCRegistration scRegistration,\n      @Qualifier(\"serviceCenterClient\") ServiceCenterClient serviceCenterClient) {\n    return new SCAddressManager(scConfigurationProperties,\n        serviceCenterClient, scRegistration);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConfigurationProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * Configurations for Service Center registration and discovery.\n */\npublic class SCConfigurationProperties {\n  private boolean enabled = true;\n\n  private String address = null;\n\n  private boolean enableSwaggerRegistration = false;\n\n  /**\n   * for registration service\n   * when swagger is different between local with remote serviceCenter. if ignoreSwaggerDifferent is true.\n   * it will ignore the different and continue the program. otherwise, the program will stop.\n   */\n  private boolean ignoreSwaggerDifferent = true;\n\n  private boolean canOverwriteSwagger = true;\n\n  private String hostname;\n\n  private int healthCheckIntervalInSeconds = 15;\n\n  private int healthCheckTimes = 3;\n\n  private int healthCheckRequestTimeoutInMillis = 5000;\n\n  private int pollIntervalInMillis = 15000;\n\n  private boolean autoDiscovery = false;\n\n  private boolean watch = false;\n\n  private long registrationWaitTimeInMillis = 30000;\n\n  public String getAddress() {\n    if (StringUtils.isEmpty(address)) {\n      throw new IllegalStateException(\n          \"Address is required in configuration. NOTICE: since 3.0.0, only support \"\n              + SCConst.SC_REGISTRY_PREFIX + \".address to configure service center address.\");\n    }\n    return address;\n  }\n\n  public void setAddress(String address) {\n    this.address = address;\n  }\n\n  public boolean isEnabled() {\n    return enabled;\n  }\n\n  public void setEnabled(boolean enabled) {\n    this.enabled = enabled;\n  }\n\n  public boolean isIgnoreSwaggerDifferent() {\n    return ignoreSwaggerDifferent;\n  }\n\n  public void setIgnoreSwaggerDifferent(boolean ignoreSwaggerDifferent) {\n    this.ignoreSwaggerDifferent = ignoreSwaggerDifferent;\n  }\n\n  public boolean isCanOverwriteSwagger() {\n    return canOverwriteSwagger;\n  }\n\n  public void setCanOverwriteSwagger(boolean canOverwriteSwagger) {\n    this.canOverwriteSwagger = canOverwriteSwagger;\n  }\n\n  public String getHostname() {\n    return hostname;\n  }\n\n  public void setHostname(String hostname) {\n    this.hostname = hostname;\n  }\n\n  public int getHealthCheckIntervalInSeconds() {\n    return healthCheckIntervalInSeconds;\n  }\n\n  public void setHealthCheckIntervalInSeconds(int healthCheckIntervalInSeconds) {\n    this.healthCheckIntervalInSeconds = healthCheckIntervalInSeconds;\n  }\n\n  public int getHealthCheckRequestTimeoutInMillis() {\n    return healthCheckRequestTimeoutInMillis;\n  }\n\n  public void setHealthCheckRequestTimeoutInMillis(int healthCheckRequestTimeoutInMillis) {\n    this.healthCheckRequestTimeoutInMillis = healthCheckRequestTimeoutInMillis;\n  }\n\n  public int getPollIntervalInMillis() {\n    return pollIntervalInMillis;\n  }\n\n  public void setPollIntervalInMillis(int pollIntervalInMillis) {\n    this.pollIntervalInMillis = pollIntervalInMillis;\n  }\n\n  public boolean isAutoDiscovery() {\n    return autoDiscovery;\n  }\n\n  public void setAutoDiscovery(boolean autoDiscovery) {\n    this.autoDiscovery = autoDiscovery;\n  }\n\n  public int getHealthCheckTimes() {\n    return healthCheckTimes;\n  }\n\n  public void setHealthCheckTimes(int healthCheckTimes) {\n    this.healthCheckTimes = healthCheckTimes;\n  }\n\n  public boolean isWatch() {\n    return watch;\n  }\n\n  public void setWatch(boolean watch) {\n    this.watch = watch;\n  }\n\n  public long getRegistrationWaitTimeInMillis() {\n    return registrationWaitTimeInMillis;\n  }\n\n  public void setRegistrationWaitTimeInMillis(long registrationWaitTimeInMillis) {\n    this.registrationWaitTimeInMillis = registrationWaitTimeInMillis;\n  }\n\n  public boolean isEnableSwaggerRegistration() {\n    return enableSwaggerRegistration;\n  }\n\n  public void setEnableSwaggerRegistration(boolean enableSwaggerRegistration) {\n    this.enableSwaggerRegistration = enableSwaggerRegistration;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\npublic class SCConst {\n  public static final String SC_REGISTRY_NAME = \"sc-registry\";\n\n  public static final String SC_REGISTRY_PREFIX = \"servicecomb.registry.sc\";\n\n  public static final String SC_SSL_TAG = \"sc.consumer\";\n\n  public static final String SC_ALLOW_CROSS_APP = \"allowCrossApp\";\n\n  public static final String SC_DEFAULT_PROJECT = \"default\";\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.foundation.common.event.SimpleEventBus;\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.apache.servicecomb.service.center.client.DiscoveryEvents.InstanceChangedEvent;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterDiscovery;\nimport org.apache.servicecomb.service.center.client.ServiceCenterDiscovery.SubscriptionKey;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\n\npublic class SCDiscovery implements Discovery<SCDiscoveryInstance> {\n  public static final String SC_DISCOVERY_ENABLED = \"servicecomb.registry.sc.%s.%s.enabled\";\n\n  private final EventBus eventBus = new SimpleEventBus();\n\n  private final SCConfigurationProperties configurationProperties;\n\n  private final ServiceCenterClient serviceCenterClient;\n\n  private SCRegistration scRegistration;\n\n  private ServiceCenterDiscovery serviceCenterDiscovery;\n\n  private InstanceChangedListener<SCDiscoveryInstance> instanceChangedListener;\n\n  private Environment environment;\n\n  @Autowired\n  public SCDiscovery(SCConfigurationProperties configurationProperties,\n      ServiceCenterClient serviceCenterClient) {\n    this.configurationProperties = configurationProperties;\n    this.serviceCenterClient = serviceCenterClient;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setScRegistration(SCRegistration scRegistration) {\n    this.scRegistration = scRegistration;\n  }\n\n  @Override\n  public String name() {\n    return SCConst.SC_REGISTRY_NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    return -9000;\n  }\n\n  @Override\n  public boolean enabled(String application, String serviceName) {\n    return environment.getProperty(String.format(SC_DISCOVERY_ENABLED, application, serviceName),\n        boolean.class, true);\n  }\n\n  @Override\n  public List<SCDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    SubscriptionKey subscriptionKey = new SubscriptionKey(application, serviceName);\n    serviceCenterDiscovery.registerIfNotPresent(subscriptionKey);\n    List<MicroserviceInstance> instances = serviceCenterDiscovery.getInstanceCache(subscriptionKey);\n\n    return toDiscoveryInstances(instances);\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n    return serviceCenterClient.getMicroserviceList().getServices().stream()\n        .filter(e -> e.getAppId().equals(application)).map(Microservice::getServiceName)\n        .collect(Collectors.toList());\n  }\n\n  private List<SCDiscoveryInstance> toDiscoveryInstances(List<MicroserviceInstance> instances) {\n    if (CollectionUtils.isEmpty(instances)) {\n      return Collections.emptyList();\n    }\n\n    Map<String, String> schemaResult;\n    if (configurationProperties.isEnableSwaggerRegistration()) {\n      List<SchemaInfo> schemas = serviceCenterClient.getServiceSchemasList(instances.get(0).getServiceId(), true);\n      if (schemas == null) {\n        schemaResult = Collections.emptyMap();\n      } else {\n        schemaResult = new HashMap<>(schemas.size());\n        schemas.forEach(info -> schemaResult.put(info.getSchemaId(), info.getSchema()));\n      }\n    } else {\n      schemaResult = new HashMap<>();\n    }\n    List<SCDiscoveryInstance> result = new ArrayList<>(instances.size());\n    instances.forEach(instance -> result.add(new SCDiscoveryInstance(instance, schemaResult)));\n    return result;\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<SCDiscoveryInstance> instanceChangedListener) {\n    this.instanceChangedListener = instanceChangedListener;\n  }\n\n  @Subscribe\n  @SuppressWarnings(\"unused\")\n  public void onInstanceChangedEvent(InstanceChangedEvent event) {\n    this.instanceChangedListener.onInstanceChanged(name(), event.getAppName(), event.getServiceName(),\n        toDiscoveryInstances(event.getInstances()));\n  }\n\n  @Override\n  public void init() {\n    serviceCenterDiscovery = new ServiceCenterDiscovery(serviceCenterClient, eventBus);\n    serviceCenterDiscovery.setPollInterval(configurationProperties.getPollIntervalInMillis());\n\n    eventBus.register(this);\n  }\n\n  @Override\n  public void run() {\n    // SCDiscovery.run is called after SCRegistration.run\n    serviceCenterDiscovery.updateMyselfServiceId(scRegistration.getBackendMicroservice().getServiceId());\n    // startDiscovery will check if already started, can call several times\n    serviceCenterDiscovery.startDiscovery();\n  }\n\n  @Override\n  public void destroy() {\n    if (serviceCenterDiscovery != null) {\n      serviceCenterDiscovery.stop();\n    }\n  }\n\n  @Override\n  public boolean enabled() {\n    return this.configurationProperties.isEnabled();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.AbstractDiscoveryInstance;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\n\npublic class SCDiscoveryInstance extends AbstractDiscoveryInstance {\n  private final Microservice microservice;\n\n  private final MicroserviceInstance microserviceInstance;\n\n  private final Map<String, String> schemas;\n\n  public SCDiscoveryInstance(MicroserviceInstance microserviceInstance,\n      Map<String, String> schemas) {\n    this.microservice = microserviceInstance.getMicroservice();\n    this.microserviceInstance = microserviceInstance;\n    this.schemas = schemas;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return MicroserviceInstanceStatus.valueOf(microserviceInstance.getStatus().name());\n  }\n\n  @Override\n  public String getRegistryName() {\n    return SCConst.SC_REGISTRY_NAME;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return microservice.getEnvironment();\n  }\n\n  @Override\n  public String getApplication() {\n    return microservice.getAppId();\n  }\n\n  @Override\n  public String getServiceName() {\n    return microservice.getServiceName();\n  }\n\n  @Override\n  public String getAlias() {\n    return microservice.getAlias();\n  }\n\n  @Override\n  public String getVersion() {\n    return microservice.getVersion();\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    if (microserviceInstance.getDataCenterInfo() != null) {\n      return new DataCenterInfo(microserviceInstance.getDataCenterInfo().getName(),\n          microserviceInstance.getDataCenterInfo().getRegion(),\n          microserviceInstance.getDataCenterInfo().getAvailableZone());\n    }\n    return new DataCenterInfo();\n  }\n\n  @Override\n  public String getDescription() {\n    return microservice.getDescription();\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return microserviceInstance.getProperties();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return schemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return microserviceInstance.getEndpoints();\n  }\n\n  @Override\n  public String getInstanceId() {\n    return microserviceInstance.getInstanceId();\n  }\n\n  @Override\n  public String getServiceId() {\n    return microservice.getServiceId();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.foundation.common.event.SimpleEventBus;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.apache.servicecomb.service.center.client.RegistrationEvents.MicroserviceInstanceRegistrationEvent;\nimport org.apache.servicecomb.service.center.client.ServiceCenterClient;\nimport org.apache.servicecomb.service.center.client.ServiceCenterRegistration;\nimport org.apache.servicecomb.service.center.client.ServiceCenterWatch;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\nimport org.apache.servicecomb.service.center.client.model.SchemaInfo;\nimport org.apache.servicecomb.service.center.client.model.ServiceCenterConfiguration;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.base.Charsets;\nimport com.google.common.eventbus.EventBus;\nimport com.google.common.eventbus.Subscribe;\nimport com.google.common.hash.Hashing;\n\npublic class SCRegistration implements Registration<SCRegistrationInstance> {\n  private final EventBus eventBus = new SimpleEventBus();\n\n  private Microservice microservice;\n\n  private MicroserviceInstance microserviceInstance;\n\n  private ServiceCenterRegistration serviceCenterRegistration;\n\n  private final ServiceCenterClient serviceCenterClient;\n\n  private final ServiceCenterWatch serviceCenterWatch;\n\n  private final SCConfigurationProperties configurationProperties;\n\n  private SCRegistrationInstance registrationInstance;\n\n  private DataCenterProperties dataCenterProperties;\n\n  private Environment environment;\n\n  private RegistrationId registrationId;\n\n  private CountDownLatch readyWaiter = new CountDownLatch(1);\n\n  @Autowired\n  public SCRegistration(SCConfigurationProperties configurationProperties,\n      ServiceCenterClient serviceCenterClient, ServiceCenterWatch serviceCenterWatch) {\n    this.configurationProperties = configurationProperties;\n    this.serviceCenterClient = serviceCenterClient;\n    this.serviceCenterWatch = serviceCenterWatch;\n  }\n\n  @Autowired\n  public void setDataCenterProperties(DataCenterProperties dataCenterProperties) {\n    this.dataCenterProperties = dataCenterProperties;\n  }\n\n  @Autowired\n  public void setRegistrationId(RegistrationId registrationId) {\n    this.registrationId = registrationId;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void init() {\n    microservice = MicroserviceHandler.createMicroservice(\n        environment);\n    microserviceInstance = MicroserviceHandler.createMicroserviceInstance(\n        environment,\n        configurationProperties,\n        dataCenterProperties);\n    microserviceInstance.setInstanceId(registrationId.getInstanceId());\n    serviceCenterRegistration = new ServiceCenterRegistration(serviceCenterClient,\n        new ServiceCenterConfiguration().setCanOverwriteSwagger(\n                this.configurationProperties.isCanOverwriteSwagger())\n            .setCanOverwriteSwagger(this.configurationProperties.isCanOverwriteSwagger()),\n        eventBus);\n    serviceCenterRegistration.setMicroservice(microservice);\n    serviceCenterRegistration.setMicroserviceInstance(microserviceInstance);\n    serviceCenterRegistration.setHeartBeatInterval(\n        TimeUnit.SECONDS.toMillis(configurationProperties.getHealthCheckIntervalInSeconds()));\n    serviceCenterRegistration.setHeartBeatRequestTimeout(\n        configurationProperties.getHealthCheckRequestTimeoutInMillis());\n    registrationInstance = new SCRegistrationInstance(microservice, microserviceInstance, serviceCenterRegistration);\n    eventBus.register(this);\n  }\n\n  @Override\n  public void run() {\n    try {\n      serviceCenterRegistration.startRegistration();\n      if (!readyWaiter.await(configurationProperties.getRegistrationWaitTimeInMillis(), TimeUnit.MILLISECONDS)) {\n        throw new IllegalStateException(\n            String.format(\"registration timeout after %s milli seconds.\",\n                configurationProperties.getRegistrationWaitTimeInMillis()));\n      }\n    } catch (InterruptedException e) {\n      throw new IllegalStateException(\"registration process is interrupted.\");\n    }\n  }\n\n  @Subscribe\n  public void onMicroserviceInstanceRegistrationEvent(MicroserviceInstanceRegistrationEvent event) {\n    if (!event.isSuccess()) {\n      return;\n    }\n    readyWaiter.countDown();\n    if (configurationProperties.isWatch()) {\n      serviceCenterWatch.startWatch(SCConst.SC_DEFAULT_PROJECT, microservice.getServiceId());\n    }\n  }\n\n  @Override\n  public void destroy() {\n    if (serviceCenterRegistration != null) {\n      serviceCenterRegistration.stop();\n    }\n  }\n\n  @Override\n  public String name() {\n    return SCConst.SC_REGISTRY_NAME;\n  }\n\n  @Override\n  public SCRegistrationInstance getMicroserviceInstance() {\n    return registrationInstance;\n  }\n\n  @Override\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    return serviceCenterClient.updateMicroserviceInstanceStatus(microservice.getServiceId(),\n        microserviceInstance.getInstanceId(),\n        org.apache.servicecomb.service.center.client.model.MicroserviceInstanceStatus.valueOf(status.name()));\n  }\n\n  @Override\n  public void addSchema(String schemaId, String content) {\n    if (configurationProperties.isEnableSwaggerRegistration()) {\n      this.microservice.addSchema(schemaId);\n\n      this.serviceCenterRegistration.addSchemaInfo(\n          new SchemaInfo(schemaId, content, calcSchemaSummary(content)));\n    }\n  }\n\n  @SuppressWarnings(\"UnstableApiUsage\")\n  public static String calcSchemaSummary(String schemaContent) {\n    return Hashing.sha256().newHasher().putString(schemaContent, Charsets.UTF_8).hash().toString();\n  }\n\n  @Override\n  public void addEndpoint(String endpoint) {\n    this.microserviceInstance.addEndpoint(endpoint);\n  }\n\n  @Override\n  public void addProperty(String key, String value) {\n    this.microserviceInstance.addProperty(key, value);\n  }\n\n  @Override\n  public boolean enabled() {\n    return this.configurationProperties.isEnabled();\n  }\n\n  public Microservice getBackendMicroservice() {\n    return microservice;\n  }\n\n  public MicroserviceInstance getBackendMicroserviceInstance() {\n    return microserviceInstance;\n  }\n\n  EventBus getEventBus() {\n    return eventBus;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.sc;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\nimport org.apache.servicecomb.service.center.client.ServiceCenterRegistration;\nimport org.apache.servicecomb.service.center.client.model.Microservice;\nimport org.apache.servicecomb.service.center.client.model.MicroserviceInstance;\n\npublic class SCRegistrationInstance implements RegistrationInstance {\n  private final Microservice microservice;\n\n  private final MicroserviceInstance microserviceInstance;\n\n  private final ServiceCenterRegistration serviceCenterRegistration;\n\n  public SCRegistrationInstance(Microservice microservice, MicroserviceInstance microserviceInstance,\n      ServiceCenterRegistration serviceCenterRegistration) {\n    this.microservice = microservice;\n    this.microserviceInstance = microserviceInstance;\n    this.serviceCenterRegistration = serviceCenterRegistration;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return microservice.getEnvironment();\n  }\n\n  @Override\n  public String getApplication() {\n    return microservice.getAppId();\n  }\n\n  @Override\n  public String getServiceName() {\n    return microservice.getServiceName();\n  }\n\n  @Override\n  public String getAlias() {\n    return microservice.getAlias();\n  }\n\n  @Override\n  public String getVersion() {\n    return microservice.getVersion();\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return new DataCenterInfo(microserviceInstance.getDataCenterInfo().getName(),\n        microserviceInstance.getDataCenterInfo().getRegion(),\n        microserviceInstance.getDataCenterInfo().getAvailableZone());\n  }\n\n  @Override\n  public String getDescription() {\n    return microservice.getDescription();\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return microserviceInstance.getProperties();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    Map<String, String> result = new HashMap<>();\n    serviceCenterRegistration.getSchemaInfos().forEach(info -> result.put(info.getSchemaId(), info.getSchema()));\n    return result;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return microserviceInstance.getEndpoints();\n  }\n\n  @Override\n  public String getInstanceId() {\n    return microserviceInstance.getInstanceId();\n  }\n\n  @Override\n  public String getServiceId() {\n    return microservice.getServiceId();\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return MicroserviceInstanceStatus.valueOf(microserviceInstance.getStatus().name());\n  }\n\n  public Microservice getBackendMicroservice() {\n    return microservice;\n  }\n\n  public MicroserviceInstance getBackendMicroserviceInstance() {\n    return microserviceInstance;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-service-center/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.sc.SCConfiguration\n"
  },
  {
    "path": "service-registry/registry-zero-config/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>service-registry-parent</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-zero-config</artifactId>\n  <name>Java Chassis::Service Registry::Zero Config</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-lightweight</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/AbstractZeroConfigRegistration.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.zeroconfig;\r\n\r\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.ORDER;\r\n\r\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\r\nimport org.apache.servicecomb.registry.lightweight.AbstractLightweightRegistration;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\n\r\npublic abstract class AbstractZeroConfigRegistration<R extends RegistrationInstance>\r\n    extends AbstractLightweightRegistration<R> {\r\n  protected Config config;\r\n\r\n  @Autowired\r\n  public AbstractZeroConfigRegistration<R> setConfig(Config config) {\r\n    this.config = config;\r\n    return this;\r\n  }\r\n\r\n  @Override\r\n  public int getOrder() {\r\n    return ORDER;\r\n  }\r\n\r\n  @Override\r\n  public boolean enabled() {\r\n    return config.isEnabled();\r\n  }\r\n\r\n  @Override\r\n  public void run() {\r\n    super.run();\r\n\r\n    startRegister(config.getHeartbeatInterval());\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/Config.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.zeroconfig;\n\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.CFG_ENABLED;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.CFG_HEARTBEAT_INTERVAL;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.CFG_HEARTBEAT_LOST_TIMES;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.CFG_MULTICAST_ADDRESS;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.CFG_MULTICAST_GROUP;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.CFG_PULL_INTERVAL;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.DEFAULT_ADDRESS;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.DEFAULT_GROUP;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.DEFAULT_HEARTBEAT_INTERVAL;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.DEFAULT_HEARTBEAT_LOST_TIMES;\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.DEFAULT_PULL_INTERVAL;\n\nimport java.time.Duration;\n\nimport org.apache.servicecomb.config.DynamicProperties;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class Config {\n  private DynamicProperties dynamicProperties;\n\n  @Autowired\n  public Config setDynamicProperties(DynamicProperties dynamicProperties) {\n    this.dynamicProperties = dynamicProperties;\n    return this;\n  }\n\n  public boolean isEnabled() {\n    return dynamicProperties.getBooleanProperty(CFG_ENABLED, true);\n  }\n\n  public String getMulticastAddress() {\n    return dynamicProperties.getStringProperty(CFG_MULTICAST_ADDRESS, DEFAULT_ADDRESS);\n  }\n\n  // (224.0.0.0, 239.255.255.255]\n  public String getMulticastGroup() {\n    return dynamicProperties.getStringProperty(CFG_MULTICAST_GROUP, DEFAULT_GROUP);\n  }\n\n  public Duration getHeartbeatInterval() {\n    String interval = dynamicProperties.getStringProperty(CFG_HEARTBEAT_INTERVAL, DEFAULT_HEARTBEAT_INTERVAL);\n    return toDuration(interval);\n  }\n\n  public Duration getCheckDeadInstancesInterval() {\n    int lostTimes = dynamicProperties.getIntProperty(CFG_HEARTBEAT_LOST_TIMES, DEFAULT_HEARTBEAT_LOST_TIMES);\n    return getHeartbeatInterval().multipliedBy(lostTimes);\n  }\n\n  public Duration getPullInterval() {\n    String interval = dynamicProperties.getStringProperty(CFG_PULL_INTERVAL, DEFAULT_PULL_INTERVAL);\n    return toDuration(interval);\n  }\n\n  private Duration toDuration(String interval) {\n    return Duration.parse(\"PT\" + interval);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.zeroconfig;\n\npublic interface ZeroConfigConst {\n  String ZERO_CONFIG_REGISTRY_NAME = \"zero-config-registry\";\n\n  int MAX_PACKET_SIZE = 1024;\n\n  String PREFIX = \"servicecomb.registry.zero-config.\";\n\n  String CFG_ENABLED = PREFIX + \"enabled\";\n\n  String CFG_MULTICAST_GROUP = PREFIX + \"multicast.group\";\n\n  String CFG_MULTICAST_ADDRESS = PREFIX + \"multicast.address\";\n\n  String CFG_HEARTBEAT_INTERVAL = PREFIX + \"heartbeat.interval\";\n\n  String CFG_HEARTBEAT_LOST_TIMES = PREFIX + \"heartbeat.lost-times\";\n\n  String CFG_PULL_INTERVAL = PREFIX + \"pull-interval\";\n\n  String DEFAULT_GROUP = \"225.6.7.8\";\n\n  String DEFAULT_ADDRESS = \"0.0.0.0:6666\";\n\n  String DEFAULT_HEARTBEAT_INTERVAL = \"30s\";\n\n  int DEFAULT_HEARTBEAT_LOST_TIMES = 3;\n\n  String DEFAULT_PULL_INTERVAL = \"3s\";\n\n  int ORDER = -8000;\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.zeroconfig;\n\nimport static org.apache.servicecomb.zeroconfig.ZeroConfigConst.ORDER;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.registry.lightweight.AbstractLightweightDiscovery;\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstances;\nimport org.springframework.beans.factory.annotation.Autowired;\n\npublic class ZeroConfigDiscovery extends AbstractLightweightDiscovery<ZeroConfigDiscoveryInstance> {\n  private Config config;\n\n  @Autowired\n  public ZeroConfigDiscovery setConfig(Config config) {\n    this.config = config;\n    return this;\n  }\n\n  @Override\n  public String name() {\n    return ZeroConfigConst.ZERO_CONFIG_REGISTRY_NAME;\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<ZeroConfigDiscoveryInstance> instanceChangedListener) {\n\n  }\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean enabled() {\n    return config.isEnabled();\n  }\n\n  @Override\n  public void run() {\n\n  }\n\n  @Override\n  public List<ZeroConfigDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    MicroserviceInstances microserviceInstances =\n        store.findServiceInstances(application, serviceName, \"0\");\n    if (microserviceInstances.isMicroserviceNotExist() || microserviceInstances.getInstancesResponse() == null) {\n      return Collections.emptyList();\n    }\n    List<ZeroConfigDiscoveryInstance> result = new ArrayList<>();\n    for (MicroserviceInstance instance : microserviceInstances.getInstancesResponse().getInstances()) {\n      result.add(new ZeroConfigDiscoveryInstance(store.getMicroservice(instance.getServiceId()).get(), instance));\n    }\n    return result;\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n    List<Microservice> microservices = store.getAllMicroservices();\n    return microservices.stream().filter(e -> e.getAppId().equals(application))\n        .map(Microservice::getServiceName).collect(Collectors.toList());\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.zeroconfig;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.AbstractDiscoveryInstance;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.lightweight.model.Microservice;\nimport org.apache.servicecomb.registry.lightweight.model.MicroserviceInstance;\n\npublic class ZeroConfigDiscoveryInstance extends AbstractDiscoveryInstance {\n  private final Microservice microservice;\n\n  private final MicroserviceInstance microserviceInstance;\n\n  public ZeroConfigDiscoveryInstance(Microservice microservice,\n      MicroserviceInstance microserviceInstance) {\n    this.microservice = microservice;\n    this.microserviceInstance = microserviceInstance;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return microserviceInstance.getStatus();\n  }\n\n  @Override\n  public String getRegistryName() {\n    return ZeroConfigConst.ZERO_CONFIG_REGISTRY_NAME;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return microservice.getEnvironment();\n  }\n\n  @Override\n  public String getApplication() {\n    return microservice.getAppId();\n  }\n\n  @Override\n  public String getServiceName() {\n    return microservice.getServiceName();\n  }\n\n  @Override\n  public String getAlias() {\n    return microservice.getAlias();\n  }\n\n  @Override\n  public String getVersion() {\n    return microservice.getVersion();\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return microserviceInstance.getDataCenterInfo();\n  }\n\n  @Override\n  public String getDescription() {\n    return microservice.getDescription();\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return microserviceInstance.getProperties();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return microservice.getSchemaMap();\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return microserviceInstance.getEndpoints();\n  }\n\n  @Override\n  public String getInstanceId() {\n    return microserviceInstance.getInstanceId();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.zeroconfig;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.registry.lightweight.MessageType;\nimport org.apache.servicecomb.registry.lightweight.RegisterInstanceEvent;\nimport org.apache.servicecomb.zeroconfig.multicast.Multicast;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport com.google.common.eventbus.Subscribe;\n\n@SuppressWarnings(\"UnstableApiUsage\")\npublic class ZeroConfigRegistration extends AbstractZeroConfigRegistration<ZeroConfigRegistrationInstance> implements\n    InitializingBean {\n  protected Multicast multicast;\n\n  @Autowired\n  public ZeroConfigRegistration setMulticast(Multicast multicast) {\n    this.multicast = multicast;\n    return this;\n  }\n\n  @Override\n  public String name() {\n    return ZeroConfigConst.ZERO_CONFIG_REGISTRY_NAME;\n  }\n\n  // delete after support @Conditional\n  @Override\n  public boolean enabled() {\n    return true;\n  }\n\n  @Override\n  public void afterPropertiesSet() {\n    eventBus.register(this);\n  }\n\n  @Override\n  protected void doSendRegister() throws IOException {\n    multicast.send(MessageType.REGISTER, self.buildRegisterRequest());\n  }\n\n  @Override\n  protected void doSendUnregister() throws IOException {\n    multicast.send(MessageType.UNREGISTER, self.buildUnregisterRequest());\n  }\n\n  @Override\n  public ZeroConfigRegistrationInstance getMicroserviceInstance() {\n    return new ZeroConfigRegistrationInstance(self);\n  }\n\n  @SuppressWarnings(\"unused\")\n  @Subscribe\n  public void onRegisterInstance(RegisterInstanceEvent event) {\n    if (event.getInstance().getInstanceId().equals(self.getInstance().getInstanceId())) {\n      return;\n    }\n\n    sendRegister();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.zeroconfig;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\nimport org.apache.servicecomb.registry.lightweight.Self;\n\npublic class ZeroConfigRegistrationInstance implements RegistrationInstance {\n  private final Self self;\n\n  public ZeroConfigRegistrationInstance(Self self) {\n    this.self = self;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return self.getMicroservice().getEnvironment();\n  }\n\n  @Override\n  public String getApplication() {\n    return self.getMicroservice().getAppId();\n  }\n\n  @Override\n  public String getServiceName() {\n    return self.getMicroservice().getServiceName();\n  }\n\n  @Override\n  public String getAlias() {\n    return self.getMicroservice().getAlias();\n  }\n\n  @Override\n  public String getVersion() {\n    return self.getMicroservice().getVersion();\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return self.getInstance().getDataCenterInfo();\n  }\n\n  @Override\n  public String getDescription() {\n    return self.getMicroservice().getDescription();\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return self.getInstance().getProperties();\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return this.self.getMicroservice().getSchemaMap();\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return this.self.getInstance().getEndpoints();\n  }\n\n  @Override\n  public String getInstanceId() {\n    return this.self.getInstanceId();\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return MicroserviceInstanceStatus.UP;\n  }\n\n  public void addSchema(String schemaId, String content) {\n    this.self.getMicroservice().addSchema(schemaId, content);\n  }\n\n  public void addEndpoint(String endpoint) {\n    this.self.getInstance().getEndpoints().add(endpoint);\n  }\n\n  public void addProperty(String key, String value) {\n    this.self.getInstance().getProperties().put(key, value);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistryConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.zeroconfig;\n\nimport java.io.IOException;\n\nimport org.apache.servicecomb.registry.lightweight.MessageExecutor;\nimport org.apache.servicecomb.zeroconfig.multicast.Multicast;\nimport org.apache.servicecomb.zeroconfig.multicast.MulticastServer;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ZeroConfigRegistryConfiguration {\n  @Bean\n  public ZeroConfigRegistration zeroConfigRegistration() {\n    return new ZeroConfigRegistration();\n  }\n\n  @Bean\n  public MulticastServer multicastServer(Config config, Multicast multicast, MessageExecutor messageExecutor) {\n    return new MulticastServer(config, multicast, messageExecutor);\n  }\n\n  @Bean\n  public ZeroConfigDiscovery zeroConfigDiscovery() {\n    return new ZeroConfigDiscovery();\n  }\n\n  @Bean\n  public Multicast zeroConfigMulticast(Config config) throws IOException {\n    return new Multicast(config);\n  }\n\n  @Bean\n  public Config zeroConfigModel() {\n    return new Config();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/multicast/Multicast.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.zeroconfig.multicast;\r\n\r\nimport java.io.IOException;\r\nimport java.net.DatagramPacket;\r\nimport java.net.InetAddress;\r\nimport java.net.InetSocketAddress;\r\nimport java.net.MulticastSocket;\r\nimport java.net.SocketException;\r\nimport java.net.UnknownHostException;\r\nimport java.util.concurrent.TimeUnit;\r\n\r\nimport org.apache.servicecomb.registry.lightweight.Message;\r\nimport org.apache.servicecomb.registry.lightweight.MessageType;\r\nimport org.apache.servicecomb.zeroconfig.Config;\r\nimport org.apache.servicecomb.zeroconfig.ZeroConfigConst;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport com.google.common.net.HostAndPort;\r\n\r\npublic class Multicast {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(Multicast.class);\r\n\r\n  private final InetSocketAddress bindAddress;\r\n\r\n  // (224.0.0.0, 239.255.255.255]\r\n  private final InetAddress group;\r\n\r\n  private final MulticastSocket multicastSocket;\r\n\r\n  private final byte[] recvBuffer = new byte[ZeroConfigConst.MAX_PACKET_SIZE];\r\n\r\n  private final DatagramPacket recvPacket = new DatagramPacket(recvBuffer, recvBuffer.length);\r\n\r\n  @SuppressWarnings(\"deprecation\")\r\n  public Multicast(Config config) throws IOException {\r\n    this.bindAddress = initBindAddress(config);\r\n    this.group = initGroup(config);\r\n    LOGGER.info(\"zero config, address: {}\", bindAddress);\r\n    LOGGER.info(\"zero config, group: {}\", group);\r\n\r\n    this.multicastSocket = new MulticastSocket(bindAddress);\r\n    this.multicastSocket.joinGroup(group);\r\n    this.multicastSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(5));\r\n  }\r\n\r\n  public Multicast setSendBufferSize(int size) throws SocketException {\r\n    multicastSocket.setSendBufferSize(size);\r\n    return this;\r\n  }\r\n\r\n  public Multicast setReceiveBufferSize(int size) throws SocketException {\r\n    multicastSocket.setReceiveBufferSize(size);\r\n    return this;\r\n  }\r\n\r\n  @SuppressWarnings(\"UnstableApiUsage\")\r\n  private InetSocketAddress initBindAddress(Config config) {\r\n    HostAndPort hostAndPort = HostAndPort.fromString(config.getMulticastAddress());\r\n    return new InetSocketAddress(hostAndPort.getHost(), hostAndPort.getPort());\r\n  }\r\n\r\n  private InetAddress initGroup(Config config) throws UnknownHostException {\r\n    return InetAddress.getByName(config.getMulticastGroup());\r\n  }\r\n\r\n  public <T> void send(MessageType type, T body) throws IOException {\r\n    byte[] buffer = Message.of(type, body).encode();\r\n    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group, bindAddress.getPort());\r\n    multicastSocket.send(packet);\r\n  }\r\n\r\n  public Message<?> recv() throws IOException {\r\n    multicastSocket.receive(recvPacket);\r\n\r\n    return Message.decode(recvPacket.getData(), recvPacket.getLength());\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/multicast/MulticastServer.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one or more\r\n * contributor license agreements.  See the NOTICE file distributed with\r\n * this work for additional information regarding copyright ownership.\r\n * The ASF licenses this file to You under the Apache License, Version 2.0\r\n * (the \"License\"); you may not use this file except in compliance with\r\n * the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage org.apache.servicecomb.zeroconfig.multicast;\r\n\r\nimport java.net.SocketTimeoutException;\r\nimport java.util.concurrent.Executors;\r\n\r\nimport org.apache.servicecomb.registry.lightweight.Message;\r\nimport org.apache.servicecomb.registry.lightweight.MessageExecutor;\r\nimport org.apache.servicecomb.zeroconfig.Config;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n@SuppressWarnings(\"unused\")\r\npublic class MulticastServer {\r\n  private static final Logger LOGGER = LoggerFactory.getLogger(MulticastServer.class);\r\n\r\n  private final Multicast multicast;\r\n\r\n  private final MessageExecutor messageExecutor;\r\n\r\n  public MulticastServer(Config config, Multicast multicast, MessageExecutor messageExecutor) {\r\n    this.multicast = multicast;\r\n    this.messageExecutor = messageExecutor;\r\n\r\n    Executors\r\n        .newSingleThreadExecutor(runnable -> new Thread(runnable, \"multicast-server-recv\"))\r\n        .execute(this::recv);\r\n    messageExecutor.startCheckDeadInstances(config.getCheckDeadInstancesInterval());\r\n  }\r\n\r\n  @SuppressWarnings(\"InfiniteLoopStatement\")\r\n  private void recv() {\r\n    for (; ; ) {\r\n      Message<?> message = recvMsg();\r\n      if (message == null) {\r\n        continue;\r\n      }\r\n\r\n      messageExecutor.processMessage(message);\r\n    }\r\n  }\r\n\r\n  private Message<?> recvMsg() {\r\n    try {\r\n      return multicast.recv();\r\n    } catch (SocketTimeoutException ignore) {\r\n      return null;\r\n    } catch (Exception e) {\r\n      LOGGER.error(\"failed to receive or decode message.\", e);\r\n      return null;\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "service-registry/registry-zero-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.zeroconfig.ZeroConfigRegistryConfiguration\n"
  },
  {
    "path": "service-registry/registry-zookeeper/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>service-registry-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>registry-zookeeper</artifactId>\n  <name>Java Chassis::Service Registry::Zookeeper</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.curator</groupId>\n      <artifactId>curator-x-discovery</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.curator</groupId>\n      <artifactId>curator-framework</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-registry</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ZookeeperConfiguration {\n  @Bean\n  @ConfigurationProperties(prefix = ZookeeperConst.ZOOKEEPER_REGISTRY_PREFIX)\n  public ZookeeperRegistryProperties zookeeperRegistryProperties() {\n    return new ZookeeperRegistryProperties();\n  }\n\n  @Bean\n  public ZookeeperDiscovery zookeeperDiscovery() {\n    return new ZookeeperDiscovery();\n  }\n\n  @Bean\n  public ZookeeperRegistration zookeeperRegistration() {\n    return new ZookeeperRegistration();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\npublic class ZookeeperConst {\n  public static final String ZOOKEEPER_REGISTRY_NAME = \"zookeeper-registry\";\n\n  public static final String ZOOKEEPER_DISCOVERY_ROOT = \"/servicecomb/registry/%s\";\n\n  public static final String ZOOKEEPER_REGISTRY_PREFIX = \"servicecomb.registry.zk\";\n\n  public static final String ZOOKEEPER_DISCOVERY_ENABLED = ZOOKEEPER_REGISTRY_PREFIX + \".%s.%s.enabled\";\n\n  public static final String ZOOKEEPER_DEFAULT_ENVIRONMENT = \"production\";\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperDiscovery.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.stream.Collectors;\n\nimport javax.security.auth.login.AppConfigurationEntry;\nimport javax.security.auth.login.Configuration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.curator.framework.CuratorFramework;\nimport org.apache.curator.framework.CuratorFrameworkFactory;\nimport org.apache.curator.framework.state.ConnectionState;\nimport org.apache.curator.retry.ExponentialBackoffRetry;\nimport org.apache.curator.utils.CloseableUtils;\nimport org.apache.curator.x.discovery.ServiceCache;\nimport org.apache.curator.x.discovery.ServiceDiscovery;\nimport org.apache.curator.x.discovery.ServiceDiscoveryBuilder;\nimport org.apache.curator.x.discovery.ServiceInstance;\nimport org.apache.curator.x.discovery.details.JsonInstanceSerializer;\nimport org.apache.curator.x.discovery.details.ServiceCacheListener;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\nimport org.apache.servicecomb.registry.api.Discovery;\nimport org.apache.zookeeper.server.auth.DigestLoginModule;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class ZookeeperDiscovery implements Discovery<ZookeeperDiscoveryInstance> {\n  static class ZookeeperSASLConfig extends Configuration {\n    AppConfigurationEntry entry;\n\n    public ZookeeperSASLConfig(String username,\n        String password) {\n      Map<String, String> options = new HashMap<>();\n      options.put(\"username\", username);\n      options.put(\"password\", password);\n      this.entry = new AppConfigurationEntry(\n          DigestLoginModule.class.getName(),\n          AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,\n          options\n      );\n    }\n\n    @Override\n    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {\n      AppConfigurationEntry[] array = new AppConfigurationEntry[1];\n      array[0] = entry;\n      return array;\n    }\n  }\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperDiscovery.class);\n\n  private final Map<String, Map<String, ServiceCache<ZookeeperInstance>>> serviceDiscoveries =\n      new ConcurrentHashMapEx<>();\n\n  private final Map<String, ServiceDiscovery<ZookeeperInstance>> serviceNameDiscoveries =\n      new ConcurrentHashMapEx<>();\n\n  private Environment environment;\n\n  private ZookeeperRegistryProperties zookeeperRegistryProperties;\n\n  private String basePath;\n\n  private CuratorFramework client;\n\n  private InstanceChangedListener<ZookeeperDiscoveryInstance> instanceChangedListener;\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setZookeeperRegistryProperties(ZookeeperRegistryProperties zookeeperRegistryProperties) {\n    this.zookeeperRegistryProperties = zookeeperRegistryProperties;\n  }\n\n  @Override\n  public String name() {\n    return ZookeeperConst.ZOOKEEPER_REGISTRY_NAME;\n  }\n\n  @Override\n  public boolean enabled(String application, String serviceName) {\n    return environment.getProperty(String.format(ZookeeperConst.ZOOKEEPER_DISCOVERY_ENABLED, application, serviceName),\n        boolean.class, true);\n  }\n\n  @Override\n  public List<ZookeeperDiscoveryInstance> findServiceInstances(String application, String serviceName) {\n    try {\n      ServiceCache<ZookeeperInstance> discovery = serviceDiscoveries.computeIfAbsent(application, app ->\n          new ConcurrentHashMapEx<>()).computeIfAbsent(serviceName, name -> {\n        JsonInstanceSerializer<ZookeeperInstance> serializer =\n            new JsonInstanceSerializer<>(ZookeeperInstance.class);\n        ServiceDiscovery<ZookeeperInstance> dis = ServiceDiscoveryBuilder.builder(ZookeeperInstance.class)\n            .client(client)\n            .basePath(basePath + \"/\" + application)\n            .serializer(serializer)\n            .build();\n        ServiceCache<ZookeeperInstance> cache =\n            dis.serviceCacheBuilder().name(serviceName).build();\n        cache.addListener(new ServiceCacheListener() {\n          @Override\n          public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) {\n            LOGGER.warn(\"zookeeper discovery state changed {}\", connectionState);\n          }\n\n          @Override\n          public void cacheChanged() {\n            instanceChangedListener.onInstanceChanged(name(), application, serviceName,\n                toDiscoveryInstances(cache.getInstances()));\n          }\n        });\n        try {\n          CountDownLatch latch = cache.startImmediate();\n          if (!latch.await(5000, TimeUnit.SECONDS)) {\n            throw new IllegalStateException(\"cache start failed.\");\n          }\n        } catch (Exception e) {\n          throw new IllegalStateException(e);\n        }\n        return cache;\n      });\n      List<ServiceInstance<ZookeeperInstance>> instances = discovery.getInstances();\n      return toDiscoveryInstances(instances);\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  @Override\n  public List<String> findServices(String application) {\n    try {\n      ServiceDiscovery<ZookeeperInstance> discovery = serviceNameDiscoveries\n          .computeIfAbsent(application, app -> {\n            JsonInstanceSerializer<ZookeeperInstance> serializer =\n                new JsonInstanceSerializer<>(ZookeeperInstance.class);\n            ServiceDiscovery<ZookeeperInstance> dis = ServiceDiscoveryBuilder.builder(ZookeeperInstance.class)\n                .client(client)\n                .basePath(basePath + \"/\" + application)\n                .serializer(serializer)\n                .build();\n            try {\n              dis.start();\n            } catch (Exception e) {\n              throw new IllegalStateException(e);\n            }\n            return dis;\n          });\n      return discovery.queryForNames().stream().toList();\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  private List<ZookeeperDiscoveryInstance> toDiscoveryInstances(\n      List<ServiceInstance<ZookeeperInstance>> instances) {\n    return instances.stream().map(instance ->\n        new ZookeeperDiscoveryInstance(instance.getPayload())).collect(Collectors.toList());\n  }\n\n  @Override\n  public void setInstanceChangedListener(InstanceChangedListener<ZookeeperDiscoveryInstance> instanceChangedListener) {\n    this.instanceChangedListener = instanceChangedListener;\n  }\n\n  @Override\n  public void init() {\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = ZookeeperConst.ZOOKEEPER_DEFAULT_ENVIRONMENT;\n    }\n    basePath = String.format(ZookeeperConst.ZOOKEEPER_DISCOVERY_ROOT, env);\n  }\n\n  @Override\n  public void run() {\n    CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()\n        .connectString(zookeeperRegistryProperties.getConnectString())\n        .sessionTimeoutMs(zookeeperRegistryProperties.getSessionTimeoutMillis())\n        .retryPolicy(new ExponentialBackoffRetry(1000, 3));\n    String authSchema = zookeeperRegistryProperties.getAuthenticationSchema();\n    if (StringUtils.isNotEmpty(authSchema)) {\n      if (!\"digest\".equals(authSchema)) {\n        throw new IllegalStateException(\"Not supported schema now. \" + authSchema);\n      }\n      if (zookeeperRegistryProperties.getAuthenticationInfo() == null) {\n        throw new IllegalStateException(\"Auth info can not be empty. \");\n      }\n\n      String[] authInfo = zookeeperRegistryProperties.getAuthenticationInfo().split(\":\");\n      Configuration.setConfiguration(new ZookeeperSASLConfig(authInfo[0], authInfo[1]));\n    }\n    client = builder.build();\n    client.start();\n  }\n\n  @Override\n  public void destroy() {\n    if (client != null) {\n      CloseableUtils.closeQuietly(client);\n    }\n  }\n\n  @Override\n  public boolean enabled() {\n    return zookeeperRegistryProperties.isEnabled();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperDiscoveryInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\n\npublic class ZookeeperDiscoveryInstance extends ZookeeperInstance implements DiscoveryInstance {\n  public ZookeeperDiscoveryInstance(ZookeeperInstance other) {\n    super(other);\n  }\n\n  @Override\n  public String getRegistryName() {\n    return ZookeeperConst.ZOOKEEPER_REGISTRY_NAME;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstance;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\n\npublic class ZookeeperInstance implements MicroserviceInstance {\n  private String serviceId;\n\n  private String instanceId;\n\n  private String environment;\n\n  private String application;\n\n  private String serviceName;\n\n  private String alias;\n\n  private String version;\n\n  private String description;\n\n  private DataCenterInfo dataCenterInfo;\n\n  private List<String> endpoints = new ArrayList<>();\n\n  private Map<String, String> schemas = new HashMap<>();\n\n  private Map<String, String> properties = new HashMap<>();\n\n  private MicroserviceInstanceStatus status;\n\n  public ZookeeperInstance() {\n\n  }\n\n  public ZookeeperInstance(ZookeeperInstance other) {\n    this.serviceId = other.serviceId;\n    this.instanceId = other.instanceId;\n    this.environment = other.environment;\n    this.application = other.application;\n    this.serviceName = other.serviceName;\n    this.alias = other.alias;\n    this.version = other.version;\n    this.description = other.description;\n    this.dataCenterInfo = other.dataCenterInfo;\n    this.endpoints = other.endpoints;\n    this.schemas = other.schemas;\n    this.properties = other.properties;\n    this.status = other.status;\n  }\n\n  public void setServiceId(String serviceId) {\n    this.serviceId = serviceId;\n  }\n\n  public void setInstanceId(String instanceId) {\n    this.instanceId = instanceId;\n  }\n\n  public void setEnvironment(String environment) {\n    this.environment = environment;\n  }\n\n  public void setApplication(String application) {\n    this.application = application;\n  }\n\n  public void setServiceName(String serviceName) {\n    this.serviceName = serviceName;\n  }\n\n  public void setAlias(String alias) {\n    this.alias = alias;\n  }\n\n  public void setVersion(String version) {\n    this.version = version;\n  }\n\n  public void setDescription(String description) {\n    this.description = description;\n  }\n\n  public void setDataCenterInfo(DataCenterInfo dataCenterInfo) {\n    this.dataCenterInfo = dataCenterInfo;\n  }\n\n  public void setEndpoints(List<String> endpoints) {\n    this.endpoints = endpoints;\n  }\n\n  public void setSchemas(Map<String, String> schemas) {\n    this.schemas = schemas;\n  }\n\n  public void setProperties(Map<String, String> properties) {\n    this.properties = properties;\n  }\n\n  public void setStatus(MicroserviceInstanceStatus status) {\n    this.status = status;\n  }\n\n  @Override\n  public String getEnvironment() {\n    return this.environment;\n  }\n\n  @Override\n  public String getApplication() {\n    return this.application;\n  }\n\n  @Override\n  public String getServiceName() {\n    return this.serviceName;\n  }\n\n  @Override\n  public String getAlias() {\n    return alias;\n  }\n\n  @Override\n  public String getVersion() {\n    return version;\n  }\n\n  @Override\n  public DataCenterInfo getDataCenterInfo() {\n    return dataCenterInfo == null ? new DataCenterInfo() : dataCenterInfo;\n  }\n\n  @Override\n  public String getDescription() {\n    return description;\n  }\n\n  @Override\n  public Map<String, String> getProperties() {\n    return properties;\n  }\n\n  @Override\n  public Map<String, String> getSchemas() {\n    return schemas;\n  }\n\n  @Override\n  public List<String> getEndpoints() {\n    return endpoints;\n  }\n\n  public void addSchema(String schemaId, String content) {\n    this.schemas.put(schemaId, content);\n  }\n\n  public void addEndpoint(String endpoint) {\n    this.endpoints.add(endpoint);\n  }\n\n  public void addProperty(String key, String value) {\n    this.properties.put(key, value);\n  }\n\n  @Override\n  public String getInstanceId() {\n    return instanceId;\n  }\n\n  @Override\n  public String getServiceId() {\n    return serviceId;\n  }\n\n  @Override\n  public MicroserviceInstanceStatus getStatus() {\n    return this.status;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport javax.security.auth.login.AppConfigurationEntry;\nimport javax.security.auth.login.Configuration;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.curator.framework.CuratorFramework;\nimport org.apache.curator.framework.CuratorFrameworkFactory;\nimport org.apache.curator.retry.ExponentialBackoffRetry;\nimport org.apache.curator.utils.CloseableUtils;\nimport org.apache.curator.x.discovery.ServiceDiscovery;\nimport org.apache.curator.x.discovery.ServiceDiscoveryBuilder;\nimport org.apache.curator.x.discovery.ServiceInstance;\nimport org.apache.curator.x.discovery.details.JsonInstanceSerializer;\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.config.DataCenterProperties;\nimport org.apache.servicecomb.registry.RegistrationId;\nimport org.apache.servicecomb.registry.api.DataCenterInfo;\nimport org.apache.servicecomb.registry.api.MicroserviceInstanceStatus;\nimport org.apache.servicecomb.registry.api.Registration;\nimport org.apache.zookeeper.server.auth.DigestLoginModule;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\n\npublic class ZookeeperRegistration implements Registration<ZookeeperRegistrationInstance> {\n  static class ZookeeperSASLConfig extends Configuration {\n    AppConfigurationEntry entry;\n\n    public ZookeeperSASLConfig(String username,\n        String password) {\n      Map<String, String> options = new HashMap<>();\n      options.put(\"username\", username);\n      options.put(\"password\", password);\n      this.entry = new AppConfigurationEntry(\n          DigestLoginModule.class.getName(),\n          AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,\n          options\n      );\n    }\n\n    @Override\n    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {\n      AppConfigurationEntry[] array = new AppConfigurationEntry[1];\n      array[0] = entry;\n      return array;\n    }\n  }\n\n  private Environment environment;\n\n  private ZookeeperRegistryProperties zookeeperRegistryProperties;\n\n  private DataCenterProperties dataCenterProperties;\n\n  private String basePath;\n\n  private CuratorFramework client;\n\n  private ServiceInstance<ZookeeperInstance> instance;\n\n  private RegistrationId registrationId;\n\n  private ServiceDiscovery<ZookeeperInstance> dis;\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setZookeeperRegistryProperties(ZookeeperRegistryProperties zookeeperRegistryProperties) {\n    this.zookeeperRegistryProperties = zookeeperRegistryProperties;\n  }\n\n  @Autowired\n  public void setRegistrationId(RegistrationId registrationId) {\n    this.registrationId = registrationId;\n  }\n\n  @Autowired\n  @SuppressWarnings(\"unused\")\n  public void setDataCenterProperties(DataCenterProperties dataCenterProperties) {\n    this.dataCenterProperties = dataCenterProperties;\n  }\n\n  @Override\n  public void init() {\n    String env = BootStrapProperties.readServiceEnvironment(environment);\n    if (StringUtils.isEmpty(env)) {\n      env = ZookeeperConst.ZOOKEEPER_DEFAULT_ENVIRONMENT;\n    }\n    basePath = String.format(ZookeeperConst.ZOOKEEPER_DISCOVERY_ROOT, env);\n    ZookeeperInstance zookeeperInstance = new ZookeeperInstance();\n    zookeeperInstance.setInstanceId(registrationId.getInstanceId());\n    zookeeperInstance.setEnvironment(env);\n    zookeeperInstance.setApplication(BootStrapProperties.readApplication(environment));\n    zookeeperInstance.setServiceName(BootStrapProperties.readServiceName(environment));\n    zookeeperInstance.setAlias(BootStrapProperties.readServiceAlias(environment));\n    zookeeperInstance.setDescription(BootStrapProperties.readServiceDescription(environment));\n    if (StringUtils.isNotEmpty(dataCenterProperties.getName())) {\n      DataCenterInfo dataCenterInfo = new DataCenterInfo();\n      dataCenterInfo.setName(dataCenterProperties.getName());\n      dataCenterInfo.setRegion(dataCenterProperties.getRegion());\n      dataCenterInfo.setAvailableZone(dataCenterProperties.getAvailableZone());\n      zookeeperInstance.setDataCenterInfo(dataCenterInfo);\n    }\n    zookeeperInstance.setProperties(BootStrapProperties.readServiceProperties(environment));\n    zookeeperInstance.setVersion(BootStrapProperties.readServiceVersion(environment));\n\n    zookeeperInstance.setStatus(\n        MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment)));\n    try {\n      this.instance = ServiceInstance.<ZookeeperInstance>builder().name(zookeeperInstance.getServiceName())\n          .id(zookeeperInstance.getInstanceId()).payload(zookeeperInstance).build();\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  @Override\n  public void run() {\n    CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()\n        .connectString(zookeeperRegistryProperties.getConnectString())\n        .sessionTimeoutMs(zookeeperRegistryProperties.getSessionTimeoutMillis())\n        .retryPolicy(new ExponentialBackoffRetry(1000, 3));\n    String authSchema = zookeeperRegistryProperties.getAuthenticationSchema();\n    if (StringUtils.isNotEmpty(authSchema)) {\n      if (!\"digest\".equals(authSchema)) {\n        throw new IllegalStateException(\"Not supported schema now. \" + authSchema);\n      }\n      if (zookeeperRegistryProperties.getAuthenticationInfo() == null) {\n        throw new IllegalStateException(\"Auth info can not be empty. \");\n      }\n\n      String[] authInfo = zookeeperRegistryProperties.getAuthenticationInfo().split(\":\");\n      Configuration.setConfiguration(new ZookeeperDiscovery.ZookeeperSASLConfig(authInfo[0], authInfo[1]));\n    }\n    client = builder.build();\n    client.start();\n    JsonInstanceSerializer<ZookeeperInstance> serializer =\n        new JsonInstanceSerializer<>(ZookeeperInstance.class);\n    dis = ServiceDiscoveryBuilder.builder(ZookeeperInstance.class)\n        .client(client)\n        .basePath(basePath + \"/\" + BootStrapProperties.readApplication(environment))\n        .serializer(serializer)\n        .thisInstance(instance)\n        .build();\n    try {\n      dis.start();\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n  }\n\n  @Override\n  public void destroy() {\n    if (client != null) {\n      CloseableUtils.closeQuietly(client);\n    }\n  }\n\n  @Override\n  public String name() {\n    return ZookeeperConst.ZOOKEEPER_REGISTRY_NAME;\n  }\n\n  @Override\n  public ZookeeperRegistrationInstance getMicroserviceInstance() {\n    return new ZookeeperRegistrationInstance(instance.getPayload());\n  }\n\n  @Override\n  public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) {\n    this.instance.getPayload().setStatus(status);\n    try {\n      dis.updateService(instance);\n    } catch (Exception e) {\n      throw new IllegalStateException(e);\n    }\n    return true;\n  }\n\n  @Override\n  public void addSchema(String schemaId, String content) {\n    if (zookeeperRegistryProperties.isEnableSwaggerRegistration()) {\n      instance.getPayload().addSchema(schemaId, content);\n    }\n  }\n\n  @Override\n  public void addEndpoint(String endpoint) {\n    instance.getPayload().addEndpoint(endpoint);\n  }\n\n  @Override\n  public void addProperty(String key, String value) {\n    instance.getPayload().addProperty(key, value);\n  }\n\n  @Override\n  public boolean enabled() {\n    return zookeeperRegistryProperties.isEnabled();\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistrationInstance.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\nimport org.apache.servicecomb.registry.api.RegistrationInstance;\n\npublic class ZookeeperRegistrationInstance extends ZookeeperInstance implements RegistrationInstance {\n  public ZookeeperRegistrationInstance(ZookeeperInstance instance) {\n    super(instance);\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistryProperties.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.registry.zookeeper;\n\npublic class ZookeeperRegistryProperties {\n  private boolean enabled = true;\n\n  private boolean ephemeral = true;\n\n  private String connectString = \"127.0.0.1:2181\";\n\n  private String authenticationSchema;\n\n  private String authenticationInfo;\n\n  private int connectionTimeoutMillis = 1000;\n\n  private int sessionTimeoutMillis = 60000;\n\n  private boolean enableSwaggerRegistration = false;\n\n  public boolean isEnabled() {\n    return enabled;\n  }\n\n  public void setEnabled(boolean enabled) {\n    this.enabled = enabled;\n  }\n\n  public boolean isEphemeral() {\n    return ephemeral;\n  }\n\n  public void setEphemeral(boolean ephemeral) {\n    this.ephemeral = ephemeral;\n  }\n\n  public String getConnectString() {\n    return connectString;\n  }\n\n  public void setConnectString(String connectString) {\n    this.connectString = connectString;\n  }\n\n  public int getConnectionTimeoutMillis() {\n    return connectionTimeoutMillis;\n  }\n\n  public void setConnectionTimeoutMillis(int connectionTimeoutMillis) {\n    this.connectionTimeoutMillis = connectionTimeoutMillis;\n  }\n\n  public int getSessionTimeoutMillis() {\n    return sessionTimeoutMillis;\n  }\n\n  public void setSessionTimeoutMillis(int sessionTimeoutMillis) {\n    this.sessionTimeoutMillis = sessionTimeoutMillis;\n  }\n\n  public boolean isEnableSwaggerRegistration() {\n    return enableSwaggerRegistration;\n  }\n\n  public void setEnableSwaggerRegistration(boolean enableSwaggerRegistration) {\n    this.enableSwaggerRegistration = enableSwaggerRegistration;\n  }\n\n  public String getAuthenticationSchema() {\n    return authenticationSchema;\n  }\n\n  public void setAuthenticationSchema(String authenticationSchema) {\n    this.authenticationSchema = authenticationSchema;\n  }\n\n  public String getAuthenticationInfo() {\n    return authenticationInfo;\n  }\n\n  public void setAuthenticationInfo(String authenticationInfo) {\n    this.authenticationInfo = authenticationInfo;\n  }\n}\n"
  },
  {
    "path": "service-registry/registry-zookeeper/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.registry.zookeeper.ZookeeperConfiguration\n"
  },
  {
    "path": "solutions/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>solutions</artifactId>\n  <name>Java Chassis::Solutions</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>solution-basic</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "solutions/solution-basic/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>solutions</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>solution-basic</artifactId>\n  <name>Java Chassis::Solutions::BASIC</name>\n\n  <dependencies>\n    <!-- transports -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-highway</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-servlet</artifactId>\n    </dependency>\n\n    <!-- providers -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-springmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-pojo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-jaxrs</artifactId>\n    </dependency>\n\n    <!-- handlers -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-fault-injection</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-flowcontrol-qps</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-governance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-publickey-auth</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-router</artifactId>\n    </dependency>\n\n    <!--  validation -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-validator</artifactId>\n    </dependency>\n\n    <!-- metrics -->\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>metrics-core</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/HealthEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.health.HealthCheckResult;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\n/**\n * Java Chassis health check extensions.\n */\n@Path(\"/scb/health\")\npublic interface HealthEndpoint {\n  String NAME = \"scb-health\";\n\n  @Path(\"/\")\n  @GET\n  boolean checkHealth();\n\n  @Path(\"/details\")\n  @GET\n  Map<String, HealthCheckResult> checkHealthDetails();\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/HealthEndpointImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.health.HealthCheckResult;\nimport org.apache.servicecomb.foundation.metrics.health.HealthCheckerManager;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\n@RestSchema(schemaId = HealthEndpoint.NAME, schemaInterface = HealthEndpoint.class)\npublic class HealthEndpointImpl implements HealthEndpoint {\n  @Override\n  public boolean checkHealth() {\n    Map<String, HealthCheckResult> results = HealthCheckerManager.getInstance().check();\n    for (HealthCheckResult result : results.values()) {\n      if (!result.isHealthy()) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  @Override\n  public Map<String, HealthCheckResult> checkHealthDetails() {\n    return HealthCheckerManager.getInstance().check();\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/HealthInstancePing.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.registry.discovery.InstancePing;\nimport org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance;\nimport org.apache.servicecomb.registry.discovery.TelnetInstancePing;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.context.annotation.Lazy;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\npublic class HealthInstancePing implements InstancePing {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HealthInstancePing.class);\n\n  private SCBEngine scbEngine;\n\n  private TelnetInstancePing telnetInstancePing;\n\n  private Environment environment;\n\n  @Autowired\n  @Lazy\n  public void setScbEngine(SCBEngine scbEngine) {\n    this.scbEngine = scbEngine;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  @Lazy\n  public void setTelnetInstancePing(@Qualifier(\"scbTelnetInstancePing\") TelnetInstancePing telnetInstancePing) {\n    this.telnetInstancePing = telnetInstancePing;\n  }\n\n  @Override\n  public boolean ping(StatefulDiscoveryInstance instance) {\n    if (CollectionUtils.isEmpty(instance.getEndpoints())) {\n      return false;\n    }\n\n    // hard coded here, not very nice\n    if (\"local-registry\".equals(instance.getRegistryName())) {\n      return telnetInstancePing.ping(instance);\n    }\n\n    Map<String, Object> args = new HashMap<>(2);\n    args.put(\"instanceId\", instance.getInstanceId());\n    args.put(\"registryName\", instance.getRegistryName());\n\n    for (String endpoint : instance.getEndpoints()) {\n      URI uri = URI.create(endpoint);\n      String transportName = uri.getScheme();\n      Transport transport = scbEngine.getTransportManager().findTransport(transportName);\n      if (transport == null) {\n        continue;\n      }\n      // Use myself service name instead of the target. Because can avoid create\n      // MicroserviceReferenceConfig for the target.\n      Invocation invocation = InvokerUtils.createInvocation(BootStrapProperties.readServiceName(environment),\n          transportName,\n          ManagementEndpoint.NAME, \"health\",\n          args, boolean.class);\n      invocation.setEndpoint(new Endpoint(transport, endpoint, instance));\n      boolean result;\n      try {\n        result = (boolean) InvokerUtils.syncInvoke(invocation);\n      } catch (Exception e) {\n        LOGGER.warn(\"ping instance {}/{}/{}/{} endpoint {} failed. {}\",\n            instance.getApplication(),\n            instance.getServiceName(),\n            instance.getRegistryName(),\n            instance.getInstanceId(), endpoint, e.getMessage());\n        continue;\n      }\n      if (result) {\n        return true;\n      }\n      LOGGER.warn(\"ping instance {}/{}/{}/{} endpoint {} failed\",\n          instance.getApplication(),\n          instance.getServiceName(),\n          instance.getRegistryName(),\n          instance.getInstanceId(), endpoint);\n    }\n\n    return false;\n  }\n\n  @Override\n  public int getOrder() {\n    return -10000;\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/InstanceOpenAPIRegistry.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.net.URI;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.config.BootStrapProperties;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistry;\nimport org.apache.servicecomb.core.provider.OpenAPIRegistryManager.OpenAPIChangeListener;\nimport org.apache.servicecomb.core.provider.consumer.InvokerUtils;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.registry.DiscoveryManager;\nimport org.apache.servicecomb.registry.api.DiscoveryInstance;\nimport org.apache.servicecomb.router.util.VersionCompareUtil;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.CollectionUtils;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class InstanceOpenAPIRegistry implements OpenAPIRegistry {\n  private static final Logger LOGGER = LoggerFactory.getLogger(InstanceOpenAPIRegistry.class);\n\n  private DiscoveryManager discoveryManager;\n\n  private Environment environment;\n\n  private TransportManager transportManager;\n\n  @Autowired\n  public void setDiscoveryManager(DiscoveryManager discoveryManager) {\n    this.discoveryManager = discoveryManager;\n  }\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Autowired\n  public void setTransportManager(TransportManager transportManager) {\n    this.transportManager = transportManager;\n  }\n\n  @Override\n  public boolean enabled() {\n    return environment.getProperty(OpenAPIRegistry.CONFIG_PREFIX + \".instance.enabled\", boolean.class, true);\n  }\n\n  @Override\n  public void registerOpenAPI(String application, String serviceName, String schemaId, OpenAPI api) {\n    // do nothing\n  }\n\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public Map<String, OpenAPI> loadOpenAPI(String application, String serviceName) {\n    List<? extends DiscoveryInstance> discoveryInstances =\n        discoveryManager.getOrCreateVersionedCache(application, serviceName).data();\n\n    if (discoveryInstances.isEmpty()) {\n      throw new InvocationException(Status.INTERNAL_SERVER_ERROR, \"no instances\");\n    }\n    discoveryInstances.sort((a, b) -> VersionCompareUtil.compareVersion(b.getVersion(), a.getVersion()));\n\n    String version = null;\n    for (DiscoveryInstance instance : discoveryInstances) {\n      if (version != null && !version.equals(instance.getVersion())) {\n        break;\n      }\n      version = instance.getVersion();\n      for (String endpoint : instance.getEndpoints()) {\n        URI uri = URI.create(endpoint);\n        String transportName = uri.getScheme();\n        Transport transport = transportManager.findTransport(transportName);\n        if (transport == null) {\n          continue;\n        }\n        // Use myself service name instead of the target. Because can avoid create\n        // MicroserviceReferenceConfig for the target.\n        Invocation invocation = InvokerUtils.createInvocation(BootStrapProperties.readServiceName(environment),\n            transportName,\n            ManagementEndpoint.NAME, \"schemaContents\",\n            new HashMap<>(), new TypeReference<Map<String, String>>() {\n            }.getType());\n        invocation.setEndpoint(new Endpoint(transport, endpoint, discoveryInstances.get(0)));\n        try {\n          Map<String, String> contents = (Map<String, String>) InvokerUtils.syncInvoke(invocation);\n          Map<String, OpenAPI> result = new HashMap<>(contents.size());\n          contents.forEach((k, v) -> result.put(k, SwaggerUtils.parseSwagger(v)));\n          return result;\n        } catch (InvocationException e) {\n          LOGGER.warn(\"Get schema contents {}/{}/{} from endpoint {} failed. {}\",\n              instance.getApplication(),\n              instance.getServiceName(),\n              instance.getInstanceId(), endpoint, e.getMessage());\n        }\n      }\n    }\n    throw new InvocationException(Status.INTERNAL_SERVER_ERROR, \"Get schema contents fail from all latest version.\");\n  }\n\n  @Override\n  public void setOpenAPIChangeListener(OpenAPIChangeListener listener) {\n    this.discoveryManager.addInstanceChangeListener(\n        (registryName, application, serviceName, instances) -> {\n          if (CollectionUtils.isEmpty(instances)) {\n            return;\n          }\n          listener.onOpenAPIChanged(application, serviceName);\n        });\n  }\n\n  @Override\n  public int getOrder() {\n    return -9000;\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/IntegrationConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class IntegrationConfiguration {\n  @Bean\n  public ManagementEndpointImpl managementEndpoint() {\n    return new ManagementEndpointImpl();\n  }\n\n  @Bean\n  public HealthEndpointImpl healthEndpoint() {\n    return new HealthEndpointImpl();\n  }\n\n  @Bean\n  public MetricsEndpointImpl metricsEndpoint() {\n    return new MetricsEndpointImpl();\n  }\n\n  @Bean\n  public HealthInstancePing healthInstancePing() {\n    return new HealthInstancePing();\n  }\n\n  @Bean\n  public InstanceOpenAPIRegistry instanceOpenAPIRegistry() {\n    return new InstanceOpenAPIRegistry();\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/ManagementEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.Map;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\n/**\n * Java Chassis internal management apis.\n */\n@Path(\"/scb/management\")\npublic interface ManagementEndpoint {\n  String NAME = \"scb-management\";\n\n  /**\n   * Health of this instance. If the instanceId match this instance, and this service is ready\n   * to service return true. Otherwise, return false.\n   *\n   * This api is for internal instance status usage. Load balancer will call this api to check if\n   * the target instance is alive.\n   */\n  @GET\n  @Path(\"/health\")\n  boolean health(@QueryParam(\"instanceId\") String instanceId, @QueryParam(\"registryName\") String registryName);\n\n  /**\n   * Schemas of this instance.\n   *\n   * This api is for internal schema loading usage.\n   */\n  @POST\n  @Path(\"/schema/contents\")\n  Map<String, String> schemaContents();\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/ManagementEndpointImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.provider.LocalOpenAPIRegistry;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\nimport org.apache.servicecomb.registry.RegistrationManager;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@RestSchema(schemaId = ManagementEndpoint.NAME, schemaInterface = ManagementEndpoint.class)\npublic class ManagementEndpointImpl implements ManagementEndpoint {\n  private RegistrationManager registrationManager;\n\n  private LocalOpenAPIRegistry localOpenAPIRegistry;\n\n  @Autowired\n  public void setRegistrationManager(RegistrationManager registrationManager) {\n    this.registrationManager = registrationManager;\n  }\n\n  @Autowired\n  public void setLocalOpenAPIRegistry(LocalOpenAPIRegistry localOpenAPIRegistry) {\n    this.localOpenAPIRegistry = localOpenAPIRegistry;\n  }\n\n  @Override\n  public boolean health(String instanceId, String registryName) {\n    if (StringUtils.isEmpty(instanceId) || StringUtils.isEmpty(registryName)) {\n      return false;\n    }\n    String mySelf = registrationManager.getInstanceId(registryName);\n    if (StringUtils.isEmpty(mySelf)) {\n      return false;\n    }\n    return mySelf.equals(instanceId);\n  }\n\n  @Override\n  public Map<String, String> schemaContents() {\n    Map<String, OpenAPI> apis = localOpenAPIRegistry.loadOpenAPI();\n    Map<String, String> result = new HashMap<>(apis.size());\n    apis.forEach((k, v) -> result.put(k, SwaggerUtils.swaggerToString(v)));\n    return result;\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/MetricsEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.Map;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\n/**\n * Java Chassis metrics.\n */\n@Path(\"/scb/metrics\")\npublic interface MetricsEndpoint {\n  String NAME = \"scb-metrics\";\n\n  @GET\n  @Path(\"/\")\n  Map<String, Double> measure();\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/MetricsEndpointImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport java.util.stream.StreamSupport;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.apache.servicecomb.foundation.metrics.MetricsInitializer;\nimport org.apache.servicecomb.metrics.core.meter.vertx.EndpointMeter;\nimport org.apache.servicecomb.provider.rest.common.RestSchema;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.Measurement;\nimport io.micrometer.core.instrument.Meter;\nimport io.micrometer.core.instrument.Meter.Id;\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.Tag;\n\n@RestSchema(schemaId = MetricsEndpoint.NAME, schemaInterface = MetricsEndpoint.class)\npublic class MetricsEndpointImpl implements MetricsInitializer, MetricsEndpoint {\n  private MeterRegistry meterRegistry;\n\n  @Override\n  public void init(MeterRegistry meterRegistry, EventBus eventBus, MetricsBootstrapConfig config) {\n    this.meterRegistry = meterRegistry;\n  }\n\n  @Override\n  public Map<String, Double> measure() {\n    Map<String, Double> measurements = new LinkedHashMap<>();\n    StringBuilder sb = new StringBuilder();\n\n    for (Meter meter : this.meterRegistry.getMeters()) {\n      meter.measure().forEach(measurement -> {\n        String key = idToString(meter.getId(), measurement, sb);\n        measurements.put(key, measurement.getValue());\n      });\n    }\n\n    return measurements;\n  }\n\n  // format id to string:\n  // idName(tag1=value1,tag2=value2)\n  protected String idToString(Id id, Measurement measurement, StringBuilder sb) {\n    sb.setLength(0);\n    sb.append(id.getName()).append(\"(\").append(EndpointMeter.STATISTIC).append(\"=\")\n        .append(measurement.getStatistic().name()).append(\",\");\n    sb.append(StreamSupport\n        .stream(id\n            .getTags()\n            .spliterator(), false)\n        .map(this::tagToString)\n        .collect(\n            Collectors.joining(\",\")));\n    sb.append(')');\n\n    return sb.toString();\n  }\n\n  private String tagToString(Tag tag) {\n    return tag.getKey() + \"=\" + tag.getValue();\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.solution.basic.integration.IntegrationConfiguration\n"
  },
  {
    "path": "solutions/solution-basic/src/main/resources/microservice.yaml",
    "content": "#\n## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n# order of this configure file\nservicecomb-config-order: -100\n\nservicecomb:\n# metrics and access log\n  accesslog:\n    enabled: true\n    pattern: \"|%SCB-traceId|%h|%r|%s|%D\"\n\n  metrics:\n    window_time: 300000\n    invocation:\n      latencyDistribution: 0,10,50,100,1000\n    Consumer.invocation.slow:\n      enabled: true\n      msTime: 1000\n    Provider.invocation.slow:\n      enabled: true\n      msTime: 1000\n    publisher.defaultLog:\n      enabled: true\n      endpoints.client.detail.enabled: true\n"
  },
  {
    "path": "solutions/solution-basic/src/test/java/org/apache/servicecomb/solution/basic/integration/TestHealthEndpointImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.health.HealthCheckResult;\nimport org.apache.servicecomb.foundation.metrics.health.HealthChecker;\nimport org.apache.servicecomb.foundation.metrics.health.HealthCheckerManager;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\npublic class TestHealthEndpointImpl {\n  private final HealthChecker good = new HealthChecker() {\n    @Override\n    public String getName() {\n      return \"test\";\n    }\n\n    @Override\n    public HealthCheckResult check() {\n      return new HealthCheckResult(true, \"info\", \"extra data\");\n    }\n  };\n\n  private final HealthChecker bad = new HealthChecker() {\n    @Override\n    public String getName() {\n      return \"test2\";\n    }\n\n    @Override\n    public HealthCheckResult check() {\n      return new HealthCheckResult(false, \"info2\", \"extra data 2\");\n    }\n  };\n\n\n  @BeforeEach\n  public void reset() {\n    HealthCheckerManager.getInstance().unregister(good.getName());\n    HealthCheckerManager.getInstance().unregister(bad.getName());\n  }\n\n  @Test\n  public void checkHealthGood() {\n    HealthCheckerManager.getInstance().register(good);\n    HealthEndpointImpl publisher = new HealthEndpointImpl();\n    Assertions.assertTrue(publisher.checkHealth());\n  }\n\n  @Test\n  public void checkHealthBad() {\n    HealthCheckerManager.getInstance().register(good);\n    HealthCheckerManager.getInstance().register(bad);\n    HealthEndpointImpl publisher = new HealthEndpointImpl();\n    Assertions.assertFalse(publisher.checkHealth());\n  }\n\n  @Test\n  public void checkHealthDetails() {\n    HealthCheckerManager.getInstance().register(good);\n    HealthCheckerManager.getInstance().register(bad);\n    HealthEndpointImpl publisher = new HealthEndpointImpl();\n    Map<String, HealthCheckResult> content = publisher.checkHealthDetails();\n    Assertions.assertTrue(content.get(\"test\").isHealthy());\n    Assertions.assertEquals(\"info\", content.get(\"test\").getInformation());\n    Assertions.assertEquals(\"extra data\", content.get(\"test\").getExtraData());\n  }\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/test/java/org/apache/servicecomb/solution/basic/integration/TestManagementEndpointImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\npublic class TestManagementEndpointImpl {\n\n}\n"
  },
  {
    "path": "solutions/solution-basic/src/test/java/org/apache/servicecomb/solution/basic/integration/TestMetricsEndpointImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.solution.basic.integration;\n\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.DEFAULT_METRICS_WINDOW_TIME;\nimport static org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig.METRICS_WINDOW_TIME;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport com.google.common.eventbus.EventBus;\n\nimport io.micrometer.core.instrument.MeterRegistry;\nimport io.micrometer.core.instrument.simple.SimpleMeterRegistry;\n\npublic class TestMetricsEndpointImpl {\n  MetricsEndpointImpl publisher = new MetricsEndpointImpl();\n\n  EventBus eventBus = new EventBus();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME))\n        .thenReturn(DEFAULT_METRICS_WINDOW_TIME);\n    Mockito.when(environment.getProperty(\n            CONFIG_LATENCY_DISTRIBUTION_MIN_SCOPE_LEN, int.class, 7))\n        .thenReturn(7);\n  }\n\n  @Test\n  public void measure_globalRegistryNull() {\n    MeterRegistry registry = new SimpleMeterRegistry();\n    publisher.init(registry, eventBus, new MetricsBootstrapConfig(environment));\n\n    Map<String, Double> result = publisher.measure();\n\n    Assertions.assertEquals(0, result.size());\n  }\n\n  @Test\n  public void measure_normal() {\n    MeterRegistry registry = new SimpleMeterRegistry();\n    registry.timer(\"name\", \"t1\", \"v1\", \"t2\", \"v2\");\n\n    publisher.init(registry, eventBus, new MetricsBootstrapConfig(environment));\n    Map<String, Double> result = publisher.measure();\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(0, result.get(\"name(statistic=COUNT,t1=v1,t2=v2)\"), 0);\n    Assertions.assertEquals(0, result.get(\"name(statistic=TOTAL_TIME,t1=v1,t2=v2)\"), 0);\n    Assertions.assertEquals(0, result.get(\"name(statistic=MAX,t1=v1,t2=v2)\"), 0);\n  }\n}\n"
  },
  {
    "path": "spring-boot/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n\n  <modelVersion>4.0.0</modelVersion>\n  <packaging>pom</packaging>\n  <artifactId>java-chassis-spring-boot</artifactId>\n  <name>Java Chassis::Spring Boot</name>\n\n  <modules>\n    <module>spring-boot-starters</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>java-chassis-spring-boot-starters</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>java-chassis-spring-boot-starter-servlet</artifactId>\n  <name>Java Chassis::Spring Boot Starter::Servlet</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-starter-web</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-servlet</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-springmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-pojo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>jakarta.servlet</groupId>\n      <artifactId>jakarta.servlet-api</artifactId>\n      <scope>compile</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/src/main/java/org/apache/servicecomb/springboot/starter/servlet/RestServletInitializer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.starter.servlet;\n\nimport java.io.IOException;\nimport java.net.ServerSocket;\n\nimport org.apache.servicecomb.transport.rest.servlet.ServletUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.web.server.AbstractConfigurableWebServerFactory;\nimport org.springframework.boot.web.server.WebServerFactoryCustomizer;\nimport org.springframework.boot.web.servlet.ServletContextInitializer;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletException;\n\npublic class RestServletInitializer\n    implements WebServerFactoryCustomizer<AbstractConfigurableWebServerFactory>, ServletContextInitializer {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestServletInitializer.class);\n\n  private AbstractConfigurableWebServerFactory factory = null;\n\n  private Environment environment;\n\n  @Autowired\n  public void setEnvironment(Environment environment) {\n    this.environment = environment;\n  }\n\n  @Override\n  public void customize(AbstractConfigurableWebServerFactory factory) {\n    this.factory = factory;\n  }\n\n  @Override\n  @SuppressWarnings(\"try\")\n  public void onStartup(ServletContext servletContext) throws ServletException {\n    if (this.factory == null) {\n      // when running in external tomcat, WebServerFactoryCustomizer will not be available, but now tomcat\n      // is already listening and we can call ServletUtils.init directly.\n      ServletUtils.init(servletContext, environment);\n      return;\n    }\n\n    if (factory.getPort() == 0) {\n      LOGGER.warn(\n          \"spring boot embedded web container listen port is 0, ServiceComb will not use container's port to handler REST request.\");\n      return;\n    }\n\n    // when running in embedded tomcat, web container did not listen now. Call ServletUtils.init needs server is ready,\n    // so mock to listen, and then close.\n    try (ServerSocket ignored = new ServerSocket(factory.getPort(), 0, factory.getAddress())) {\n      ServletUtils.init(servletContext, environment);\n    } catch (IOException e) {\n      throw new ServletException(e);\n    }\n  }\n}\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/src/main/java/org/apache/servicecomb/springboot/starter/servlet/SpringBootStarterServletConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.springboot.starter.servlet;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class SpringBootStarterServletConfiguration {\n  @Bean\n  public RestServletInitializer restServletInitializer() {\n    return new RestServletInitializer();\n  }\n}\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/src/main/java/org/apache/servicecomb/springboot/starter/servlet/package-info.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.springboot.starter.servlet;\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.springboot.starter.servlet.SpringBootStarterServletConfiguration\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-standalone/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>java-chassis-spring-boot-starters</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>java-chassis-spring-boot-starter-standalone</artifactId>\n  <name>Java Chassis::Spring Boot Starter::Standalone</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-springmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-jaxrs</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>provider-pojo</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-loadbalance</artifactId>\n    </dependency>\n    <!--ConditionEvaluationReportLoggingListener need in autoconfigure-->\n    <dependency>\n      <groupId>org.hibernate.validator</groupId>\n      <artifactId>hibernate-validator</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "spring-boot/spring-boot-starters/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>java-chassis-spring-boot</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>java-chassis-spring-boot-starters</artifactId>\n  <name>Java Chassis::Spring Boot Starter::Parent</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>java-chassis-spring-boot-starter-servlet</module>\n    <module>java-chassis-spring-boot-starter-standalone</module>\n  </modules>\n\n</project>\n"
  },
  {
    "path": "swagger/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>swagger</artifactId>\n  <name>Java Chassis::Swagger</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>swagger-generator</module>\n    <module>swagger-invocation</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-generator</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-generator-core</artifactId>\n  <name>Java Chassis::Swagger::Generator::Core</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.validation</groupId>\n      <artifactId>jakarta.validation-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.swagger.core.v3</groupId>\n      <artifactId>swagger-core-jakarta</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>jakarta.servlet</groupId>\n      <artifactId>jakarta.servlet-api</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.reactivestreams</groupId>\n      <artifactId>reactive-streams</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.mockito</groupId>\n      <artifactId>mockito-inline</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.junit.jupiter</groupId>\n      <artifactId>junit-jupiter-api</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-web</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Objects;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.commons.lang3.ClassUtils;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.base.DynamicEnum;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.springframework.util.CollectionUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.core.converter.AnnotatedType;\nimport io.swagger.v3.core.converter.ModelConverters;\nimport io.swagger.v3.core.converter.ResolvedSchema;\nimport io.swagger.v3.core.util.Yaml;\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.PathItem;\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.MediaType;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport io.swagger.v3.oas.models.servers.Server;\nimport jakarta.servlet.http.Part;\n\n@SuppressWarnings(\"rawtypes\")\npublic final class SwaggerUtils {\n  private SwaggerUtils() {\n  }\n\n  /**\n   * Only ones servers and contains only base path.\n   */\n  public static String getBasePath(OpenAPI swagger) {\n    if (swagger.getServers() == null || swagger.getServers().size() == 0) {\n      return null;\n    }\n    return swagger.getServers().get(0).getUrl();\n  }\n\n  /**\n   * Only ones servers and contains only base path.\n   */\n  public static void setBasePath(OpenAPI swagger, String basePath) {\n    if (swagger.getServers() == null) {\n      swagger.setServers(new ArrayList<>());\n    }\n    if (swagger.getServers().size() == 0) {\n      swagger.getServers().add(new Server());\n    }\n    swagger.getServers().get(0).setUrl(basePath);\n  }\n\n  public static String swaggerToString(OpenAPI swagger) {\n    try {\n      return Yaml.mapper().writeValueAsString(swagger);\n    } catch (Throwable e) {\n      throw new ServiceCombException(\"Convert swagger to string failed, \", e);\n    }\n  }\n\n  public static OpenAPI parseAndValidateSwagger(URL url) {\n    try {\n      String swaggerContent = IOUtils.toString(url, StandardCharsets.UTF_8);\n      OpenAPI result = internalParseSwagger(swaggerContent);\n      validateSwagger(result);\n      return result;\n    } catch (Throwable e) {\n      throw new ServiceCombException(\"Parse swagger from url failed, url=\" + url, e);\n    }\n  }\n\n  public static OpenAPI parseSwagger(String swaggerContent) {\n    try {\n      return internalParseSwagger(swaggerContent);\n    } catch (Throwable e) {\n      throw new ServiceCombException(\"Parse swagger from content failed, \", e);\n    }\n  }\n\n  private static void validateSwagger(OpenAPI openAPI) {\n    if (openAPI.getPaths() == null) {\n      return;\n    }\n    for (PathItem pathItem : openAPI.getPaths().values()) {\n      if (pathItem.getGet() != null) {\n        validateOperation(pathItem.getGet());\n      }\n      if (pathItem.getPost() != null) {\n        validateOperation(pathItem.getPost());\n      }\n      if (pathItem.getDelete() != null) {\n        validateOperation(pathItem.getDelete());\n      }\n      if (pathItem.getPut() != null) {\n        validateOperation(pathItem.getPut());\n      }\n      if (pathItem.getPatch() != null) {\n        validateOperation(pathItem.getPatch());\n      }\n    }\n  }\n\n  private static void validateOperation(Operation operation) {\n    if (operation.getRequestBody() != null) {\n      validateRequestBody(operation.getRequestBody());\n    }\n    if (operation.getParameters() != null) {\n      validateParameters(operation.getParameters());\n    }\n  }\n\n  private static void validateParameters(List<Parameter> parameters) {\n    for (Parameter parameter : parameters) {\n      if (parameter == null) {\n        throw new ServiceCombException(\"Parameter can not be null.\");\n      }\n      if (StringUtils.isEmpty(parameter.getName())) {\n        throw new ServiceCombException(\"Parameter name is required.\");\n      }\n    }\n  }\n\n  private static void validateRequestBody(RequestBody requestBody) {\n    for (String contentType : requestBody.getContent().keySet()) {\n      if (SwaggerConst.FILE_MEDIA_TYPE.equals(contentType) || SwaggerConst.FORM_MEDIA_TYPE.equals(contentType)) {\n        continue;\n      }\n      if (requestBody.getExtensions() == null) {\n        throw new ServiceCombException(\"Request body x-name extension is required.\");\n      }\n      if (StringUtils.isEmpty((String) requestBody.getExtensions().get(SwaggerConst.EXT_BODY_NAME))) {\n        throw new ServiceCombException(\"Request body x-name extension is required.\");\n      }\n      break;\n    }\n  }\n\n  private static OpenAPI internalParseSwagger(String swaggerContent) throws IOException {\n    return Yaml.mapper().readValue(swaggerContent, OpenAPI.class);\n  }\n\n  // add descriptions to response and add a default response if absent.\n  public static void correctResponses(Operation operation) {\n    if (operation.getResponses() == null) {\n      operation.setResponses(new ApiResponses());\n    }\n    if (operation.getResponses().size() == 0) {\n      operation.getResponses().addApiResponse(SwaggerConst.SUCCESS_KEY, new ApiResponse());\n    }\n\n    for (Entry<String, ApiResponse> responseEntry : operation.getResponses().entrySet()) {\n      ApiResponse response = responseEntry.getValue();\n      if (StringUtils.isEmpty(response.getDescription())) {\n        response.setDescription(\"response of \" + responseEntry.getKey());\n      }\n    }\n  }\n\n  public static void correctResponses(OpenAPI swagger) {\n    if (swagger.getPaths() == null) {\n      return;\n    }\n\n    for (PathItem path : swagger.getPaths().values()) {\n      for (Operation operation : path.readOperations()) {\n        correctResponses(operation);\n      }\n    }\n  }\n\n  public static Schema resolveTypeSchemas(OpenAPI swagger, Type type) {\n    ResolvedSchema resolvedSchema = ModelConverters.getInstance().resolveAsResolvedSchema(\n        new AnnotatedType(type).resolveAsRef(true));\n\n    if (resolvedSchema == null || resolvedSchema.schema == null) {\n      throw new IllegalArgumentException(\"cannot resolve type : \" + type);\n    }\n\n    if (swagger.getComponents() == null) {\n      swagger.setComponents(new Components());\n    }\n\n    Map<String, Schema> schemaMap = resolvedSchema.referencedSchemas;\n    if (!CollectionUtils.isEmpty(schemaMap)) {\n      Map<String, Schema> componentSchemas = swagger.getComponents().getSchemas();\n      if (componentSchemas == null) {\n        componentSchemas = new LinkedHashMap<>(schemaMap);\n      } else {\n        for (Map.Entry<String, Schema> entry : schemaMap.entrySet()) {\n          if (!componentSchemas.containsKey(entry.getKey())) {\n            componentSchemas.put(entry.getKey(), entry.getValue());\n          } else {\n            if (!schemaEquals(entry.getValue(), componentSchemas.get(entry.getKey()))) {\n              throw new IllegalArgumentException(\"duplicate param model: \" + entry.getKey());\n            }\n          }\n        }\n      }\n      swagger.getComponents().setSchemas(componentSchemas);\n    }\n    return resolvedSchema.schema;\n  }\n\n  // swagger api equals method will compare Map address(extensions)\n  // and is not applicable for usage.\n  public static int schemaHashCode(Schema<?> schema) {\n    int result = schema.getType() != null ? schema.getType().hashCode() : 0;\n    result = result ^ (schema.getFormat() != null ? schema.getFormat().hashCode() : 0);\n    result = result ^ (schema.getName() != null ? schema.getName().hashCode() : 0);\n    result = result ^ (schema.get$ref() != null ? schema.get$ref().hashCode() : 0);\n    result = result ^ (schema.getItems() != null ? schemaHashCode(schema.getItems()) : 0);\n    result = result ^ (schema.getAdditionalProperties() != null ?\n        schemaHashCode((Schema<?>) schema.getAdditionalProperties()) : 0);\n    result = result ^ (schema.getProperties() != null ? propertiesHashCode(schema.getProperties()) : 0);\n    return result;\n  }\n\n  private static int propertiesHashCode(Map<String, Schema> properties) {\n    int result = 0;\n    for (Entry<String, Schema> entry : properties.entrySet()) {\n      result = result ^ (entry.getKey().hashCode() ^ schemaHashCode(entry.getValue()));\n    }\n    return result;\n  }\n\n  // swagger api equals method will compare Map address(extensions)\n  // and is not applicable for usage.\n  public static boolean schemaEquals(Schema<?> schema1, Schema<?> schema2) {\n    if (schema1 == null && schema2 == null) {\n      return true;\n    }\n    if (schema1 == null || schema2 == null) {\n      return false;\n    }\n    return StringUtils.equals(schema1.getType(), schema2.getType())\n        && StringUtils.equals(schema1.getFormat(), schema2.getFormat())\n        && StringUtils.equals(schema1.getName(), schema2.getName())\n        && StringUtils.equals(schema1.get$ref(), schema2.get$ref())\n        && schemaEquals(schema1.getItems(), schema2.getItems())\n        && schemaEquals((Schema<?>) schema1.getAdditionalProperties(), (Schema<?>) schema2.getAdditionalProperties())\n        && propertiesEquals(schema1.getProperties(), schema2.getProperties())\n        && extensionEquals(schema1.getExtensions(), schema2.getExtensions());\n  }\n\n  private static boolean extensionEquals(Map<String, Object> extensions1, Map<String, Object> extensions2) {\n    if (extensions1 == null && extensions2 == null) {\n      return true;\n    }\n    if (extensions1 == null || extensions2 == null) {\n      return false;\n    }\n    if (extensions1.size() != extensions2.size()) {\n      return false;\n    }\n    boolean result = true;\n    for (Entry<String, Object> item : extensions1.entrySet()) {\n      if (!Objects.equals(item.getValue(), extensions2.get(item.getKey()))) {\n        result = false;\n        break;\n      }\n    }\n    return result;\n  }\n\n  public static boolean propertiesEquals(Map<String, Schema> properties1, Map<String, Schema> properties2) {\n    if (properties1 == null && properties2 == null) {\n      return true;\n    }\n    if (properties1 == null || properties2 == null) {\n      return false;\n    }\n    if (properties1.size() != properties2.size()) {\n      return false;\n    }\n    boolean result = true;\n    for (Entry<String, Schema> item : properties1.entrySet()) {\n      if (!schemaEquals(item.getValue(), properties2.get(item.getKey()))) {\n        result = false;\n        break;\n      }\n    }\n    return result;\n  }\n\n  public static Schema getSchema(OpenAPI swagger, String ref) {\n    return swagger.getComponents().getSchemas().get(ref.substring(Components.COMPONENTS_SCHEMAS_REF.length()));\n  }\n\n  public static String getSchemaName(String ref) {\n    return ref.substring(Components.COMPONENTS_SCHEMAS_REF.length());\n  }\n\n  public static Schema getSchema(OpenAPI swagger, Schema ref) {\n    if (ref == null) {\n      return null;\n    }\n    if (ref.get$ref() != null) {\n      return getSchema(swagger, ref.get$ref());\n    }\n    return ref;\n  }\n\n  public static boolean hasAnnotation(Class<?> cls, Class<? extends Annotation> annotation) {\n    if (cls.getAnnotation(annotation) != null) {\n      return true;\n    }\n\n    for (Method method : cls.getMethods()) {\n      if (method.getAnnotation(annotation) != null) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  public static boolean isRawJsonType(RequestBody param) {\n    if (param.getExtensions() == null) {\n      return false;\n    }\n    Object rawJson = param.getExtensions().get(SwaggerConst.EXT_RAW_JSON_TYPE);\n    if (rawJson instanceof Boolean) {\n      return (boolean) rawJson;\n    }\n    return false;\n  }\n\n  public static String getClassName(Map<String, Object> vendorExtensions) {\n    return getVendorExtension(vendorExtensions, SwaggerConst.EXT_JAVA_CLASS);\n  }\n\n  public static String getInterfaceName(Map<String, Object> vendorExtensions) {\n    return getVendorExtension(vendorExtensions, SwaggerConst.EXT_JAVA_INTF);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T getVendorExtension(Map<String, Object> vendorExtensions, String key) {\n    if (vendorExtensions == null) {\n      return null;\n    }\n\n    return (T) vendorExtensions.get(key);\n  }\n\n  public static boolean isBean(Type type) {\n    if (type == null) {\n      return false;\n    }\n\n    JavaType javaType = TypeFactory.defaultInstance().constructType(type);\n    if (javaType.isContainerType() || javaType.isEnumType() || javaType.isTypeOrSubTypeOf(DynamicEnum.class)) {\n      return false;\n    }\n\n    Class<?> cls = javaType.getRawClass();\n    if (ClassUtils.isPrimitiveOrWrapper(cls)) {\n      return false;\n    }\n\n    return (cls != String.class\n        && cls != Date.class\n        && cls != LocalDate.class\n        && cls != LocalDateTime.class\n        && cls != byte[].class\n        && cls != File.class\n        && cls != BigInteger.class\n        && cls != BigDecimal.class\n        && !cls.getName().equals(\"org.springframework.web.multipart.MultipartFile\")\n        && !Part.class.isAssignableFrom(cls));\n  }\n\n  public static void updateProduces(Operation operation, String[] produces) {\n    if (produces == null || produces.length == 0) {\n      return;\n    }\n    if (operation.getResponses() == null) {\n      operation.setResponses(new ApiResponses());\n    }\n    if (operation.getResponses().size() == 0) {\n      operation.getResponses().addApiResponse(SwaggerConst.SUCCESS_KEY, new ApiResponse());\n    }\n    for (String produce : produces) {\n      operation.getResponses().forEach((k, v) -> {\n        if (v.getContent() == null) {\n          v.setContent(new Content());\n        }\n        if (v.getContent().get(produce) == null) {\n          v.getContent().addMediaType(produce, new MediaType());\n        }\n      });\n    }\n  }\n\n  public static boolean methodExists(PathItem pathItem, String httpMethod) {\n    PathItem.HttpMethod method = PathItem.HttpMethod.valueOf(httpMethod);\n    return switch (method) {\n      case GET -> pathItem.getGet() != null;\n      case PUT -> pathItem.getPut() != null;\n      case POST -> pathItem.getPost() != null;\n      case PATCH -> pathItem.getPatch() != null;\n      case DELETE -> pathItem.getDelete() != null;\n      default -> false;\n    };\n  }\n\n  public static String concatAbsolutePath(OpenAPI swagger, String operationPath) {\n    String basePath = getBasePath(swagger);\n    return concatPath(basePath, operationPath);\n  }\n\n  /**\n   * Concat the two paths to an absolute path, without end of '/'.\n   * <p>\n   * e.g. \"/\" + \"/ope\" = /ope\n   * e.g. \"/prefix\" + \"/ope\" = /prefix/ope\n   */\n  public static String concatPath(String basePath, String operationPath) {\n    return (\"/\" + nonNullify(basePath) + \"/\" + nonNullify(operationPath))\n            .replaceAll(\"/{2,}\", \"/\");\n  }\n\n  private static String nonNullify(String path) {\n    return path == null ? \"\" : path;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/AbstractConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.converter;\n\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings(\"rawtypes\")\npublic abstract class AbstractConverter implements Converter {\n  protected abstract Map<String, Object> findVendorExtensions(Object def);\n\n  protected abstract JavaType doConvert(OpenAPI swagger, Schema def);\n\n  @Override\n  public JavaType convert(OpenAPI swagger, Schema def) {\n    Map<String, Object> vendorExtensions = findVendorExtensions(def);\n    String canonical = SwaggerUtils.getClassName(vendorExtensions);\n    if (StringUtils.isEmpty(canonical)) {\n      return doConvert(swagger, def);\n    }\n\n    try {\n      return TypeFactory.defaultInstance().constructFromCanonical(canonical);\n    } catch (Throwable e) {\n      return doConvert(swagger, def);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/Converter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.converter;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings(\"rawtypes\")\npublic interface Converter {\n  JavaType OBJECT_JAVA_TYPE = TypeFactory.defaultInstance().constructType(Object.class);\n\n  JavaType STRING_JAVA_TYPE = TypeFactory.defaultInstance().constructType(String.class);\n\n  // def can be property or model\n  // def can not be null\n  JavaType convert(OpenAPI swagger, Schema def);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.converter;\n\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.converter.property.ArrayPropertyConverter;\nimport org.apache.servicecomb.swagger.converter.property.MapPropertyConverter;\nimport org.apache.servicecomb.swagger.converter.property.ObjectPropertyConverter;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.MapSchema;\nimport io.swagger.v3.oas.models.media.ObjectSchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport jakarta.servlet.http.Part;\n\n@SuppressWarnings(\"rawtypes\")\npublic final class ConverterMgr {\n  private static final JavaType VOID_JAVA_TYPE = TypeFactory.defaultInstance().constructType(Void.class);\n\n  // key is \"type.format\" of standard swagger data type\n  // value is related java class\n  private static final Map<String, JavaType> TYPE_FORMAT_MAP = new HashMap<>();\n\n  private static final Map<Class<?>, Converter> converterMap = new HashMap<>();\n\n  static {\n    initTypeFormatMap();\n    initConverters();\n  }\n\n  private static String genTypeFormatKey(String type, String format) {\n    return type + \":\" + (format == null ? \"\" : format);\n  }\n\n  private ConverterMgr() {\n\n  }\n\n  private static void initTypeFormatMap() {\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"boolean\", \"\"),\n        TypeFactory.defaultInstance().constructType(Boolean.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"integer\", \"int32\"),\n        TypeFactory.defaultInstance().constructType(Integer.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"integer\", \"int64\"),\n        TypeFactory.defaultInstance().constructType(Long.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"integer\", \"\"),\n        TypeFactory.defaultInstance().constructType(BigInteger.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"number\", \"float\"),\n        TypeFactory.defaultInstance().constructType(Float.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"number\", \"double\"),\n        TypeFactory.defaultInstance().constructType(Double.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"number\", \"\"),\n        TypeFactory.defaultInstance().constructType(BigDecimal.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"string\", \"\"),\n        TypeFactory.defaultInstance().constructType(String.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"string\", \"date\"),\n        TypeFactory.defaultInstance().constructType(LocalDate.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"string\", \"date-time\"),\n        TypeFactory.defaultInstance().constructType(LocalDateTime.class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"string\", \"password\"),\n        TypeFactory.defaultInstance().constructType(String.class));\n\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"string\", \"byte\"),\n        TypeFactory.defaultInstance().constructType(Byte[].class));\n    TYPE_FORMAT_MAP.put(genTypeFormatKey(\"string\", \"binary\"),\n        TypeFactory.defaultInstance().constructType(Part.class));\n  }\n\n  private static void initConverters() {\n    converterMap.put(ArraySchema.class, new ArrayPropertyConverter());\n    converterMap.put(MapSchema.class, new MapPropertyConverter());\n    converterMap.put(ObjectSchema.class, new ObjectPropertyConverter());\n    converterMap.put(Schema.class, new ObjectPropertyConverter());\n  }\n\n  public static JavaType findJavaType(String type, String format) {\n    String key = genTypeFormatKey(type, format);\n    return TYPE_FORMAT_MAP.get(key);\n  }\n\n  // def is null means void\n  public static JavaType findJavaType(OpenAPI swagger, Schema def) {\n    if (def == null) {\n      return VOID_JAVA_TYPE;\n    }\n    JavaType javaType = findJavaType(def.getType(), def.getFormat());\n    if (javaType != null) {\n      return javaType;\n    }\n    Converter converter = converterMap.get(def.getClass());\n    if (converter == null) {\n      throw new Error(\"not support def type: \" + def.getClass());\n    }\n    return converter.convert(swagger, def);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/AbstractPropertyConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.converter.property;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.converter.AbstractConverter;\n\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic abstract class AbstractPropertyConverter extends AbstractConverter {\n  protected Map<String, Object> findVendorExtensions(Object def) {\n    return ((Schema) def).getExtensions();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ArrayPropertyConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.converter.property;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Set;\n\nimport org.apache.servicecomb.swagger.converter.ConverterMgr;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings(\"rawtypes\")\npublic class ArrayPropertyConverter extends AbstractPropertyConverter {\n  public static JavaType findJavaType(OpenAPI swagger, Schema itemProperty, Boolean uniqueItems) {\n    JavaType itemJavaType = ConverterMgr.findJavaType(swagger, itemProperty);\n\n    @SuppressWarnings(\"rawtypes\")\n    Class<? extends Collection> collectionClass = List.class;\n    if (Boolean.TRUE.equals(uniqueItems)) {\n      collectionClass = Set.class;\n    }\n    return TypeFactory.defaultInstance().constructCollectionType(collectionClass, itemJavaType);\n  }\n\n  @Override\n  public JavaType doConvert(OpenAPI swagger, Schema property) {\n    ArraySchema arrayProperty = (ArraySchema) property;\n\n    return findJavaType(swagger, arrayProperty.getItems(), arrayProperty.getUniqueItems());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/MapPropertyConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.converter.property;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.converter.ConverterMgr;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.MapSchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings(\"rawtypes\")\npublic class MapPropertyConverter extends AbstractPropertyConverter {\n  @Override\n  public JavaType doConvert(OpenAPI swagger, Schema property) {\n    MapSchema mapProperty = (MapSchema) property;\n    Object valueProperty = mapProperty.getAdditionalProperties();\n    if (valueProperty instanceof Boolean) {\n      return TypeFactory.defaultInstance().constructType(Boolean.class);\n    }\n    return findJavaType(swagger, (Schema) valueProperty);\n  }\n\n  public static JavaType findJavaType(OpenAPI swagger, Schema valueProperty) {\n    JavaType valueJavaType = ConverterMgr.findJavaType(swagger, valueProperty);\n    return TypeFactory.defaultInstance().constructMapType(Map.class, STRING_JAVA_TYPE, valueJavaType);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.converter.property;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.converter.AbstractConverter;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings(\"rawtypes\")\npublic class ObjectPropertyConverter extends AbstractConverter {\n\n  @Override\n  protected Map<String, Object> findVendorExtensions(Object def) {\n    return ((Schema<?>) def).getExtensions();\n  }\n\n  @Override\n  protected JavaType doConvert(OpenAPI swagger, Schema def) {\n    return OBJECT_JAVA_TYPE;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ConcreteTypeRegister.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.extend;\n\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\npublic interface ConcreteTypeRegister {\n  void register(Set<Type> types);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/DefaultModelResolveObjectMapperProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend;\n\nimport org.apache.servicecomb.swagger.extend.module.EnumModuleExt;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.SerializationFeature;\n\nimport io.swagger.v3.core.util.Json;\n\n\npublic class DefaultModelResolveObjectMapperProvider implements ModelResolveObjectMapperProvider {\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n\n  @Override\n  public ObjectMapper getMapper() {\n    ObjectMapper mapper = Json.mapper();\n    mapper.registerModule(new EnumModuleExt());\n    mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, false);\n    return mapper;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolveObjectMapperProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\n/**\n * Implement this interface to create custom {@link ObjectMapper} for Swagger schema generation.\n */\npublic interface ModelResolveObjectMapperProvider {\n  /**\n   * @return order The smaller value it is, the higher priority this provider has.\n   */\n  default int getOrder() {\n    return 0;\n  }\n\n  /**\n   * @return the ObjectMapper, which is used by Swagger to introspect the param types and generate property collections.\n   */\n  ObjectMapper getMapper();\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend;\n\nimport java.lang.reflect.Type;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.base.DynamicEnum;\nimport org.apache.servicecomb.foundation.common.base.EnumUtils;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.extend.property.creator.ByteArrayPropertyCreator;\nimport org.apache.servicecomb.swagger.extend.property.creator.BytePropertyCreator;\nimport org.apache.servicecomb.swagger.extend.property.creator.InputStreamPropertyCreator;\nimport org.apache.servicecomb.swagger.extend.property.creator.PartPropertyCreator;\nimport org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.core.converter.AnnotatedType;\nimport io.swagger.v3.core.converter.ModelConverter;\nimport io.swagger.v3.core.converter.ModelConverterContext;\nimport io.swagger.v3.core.jackson.ModelResolver;\nimport io.swagger.v3.core.util.PrimitiveType;\nimport io.swagger.v3.oas.models.media.NumberSchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.media.StringSchema;\n\n/**\n * Customize swagger model converters to support:\n *\n * 1. byte and byte[] related types\n * 2. stream related types\n * 3. jason mapper customization\n * 4. add x-java-class to model\n */\n@SuppressWarnings({\"unchecked\", \"rawtypes\"})\npublic class ModelResolverExt extends ModelResolver {\n  private final Map<Type, PropertyCreator> propertyCreatorMap = new HashMap<>();\n\n  private final Set<Type> concreteInterfaces = new HashSet<>();\n\n  public ModelResolverExt() {\n    super(findMapper());\n\n    addPropertyCreator(new BytePropertyCreator());\n    addPropertyCreator(new ByteArrayPropertyCreator());\n\n    addPropertyCreator(new InputStreamPropertyCreator());\n    addPropertyCreator(new PartPropertyCreator());\n\n    SPIServiceUtils.getAllService(PropertyCreator.class)\n        .forEach(this::addPropertyCreator);\n    SPIServiceUtils.getAllService(ConcreteTypeRegister.class)\n        .forEach(r -> r.register(concreteInterfaces));\n  }\n\n  private static ObjectMapper findMapper() {\n    ModelResolveObjectMapperProvider objectMapperProvider = SPIServiceUtils\n        .getPriorityHighestService(ModelResolveObjectMapperProvider.class);\n    if (null == objectMapperProvider) {\n      objectMapperProvider = new DefaultModelResolveObjectMapperProvider();\n    }\n    return objectMapperProvider.getMapper();\n  }\n\n  private void addPropertyCreator(PropertyCreator creator) {\n    for (Class<?> cls : creator.classes()) {\n      propertyCreatorMap.put(cls, creator);\n      propertyCreatorMap.put(TypeFactory.defaultInstance().constructType(cls), creator);\n    }\n  }\n\n\n  @Override\n  public Schema<?> resolve(AnnotatedType propType, ModelConverterContext context, Iterator<ModelConverter> next) {\n    PropertyCreator creator = propertyCreatorMap.get(propType.getType());\n    if (creator != null) {\n      return creator.createProperty();\n    }\n\n    if (EnumUtils.isDynamicEnum(propType.getType())) {\n      return resolveDynamicEnum(TypeFactory.defaultInstance().constructType(propType.getType()));\n    }\n\n    Schema result = super.resolve(propType, context, next);\n    if (!StringUtils.isEmpty(result.get$ref())) {\n      Schema referencedSchema = context.getDefinedModels() != null\n          ? context.getDefinedModels().get(SwaggerUtils.getSchemaName(result.get$ref())) : null;\n      if (referencedSchema != null) {\n        if (referencedSchema.getExtensions() == null) {\n          referencedSchema.setExtensions(new HashMap<>());\n        }\n        if (propType.getType() instanceof JavaType) {\n          referencedSchema.getExtensions().put(SwaggerConst.EXT_JAVA_CLASS,\n              ((JavaType) propType.getType()).toCanonical());\n        } else {\n          referencedSchema.getExtensions().put(SwaggerConst.EXT_JAVA_CLASS,\n              TypeFactory.defaultInstance().constructType(propType.getType()).toCanonical());\n        }\n      }\n    }\n    return result;\n  }\n\n  private Schema resolveDynamicEnum(JavaType propType) {\n    Class<?> enumClass = propType.getRawClass();\n    Class<?> enumValueClass = propType.findTypeParameters(DynamicEnum.class)[0].getRawClass();\n    Schema property = PrimitiveType.createProperty(enumValueClass);\n\n    if (property instanceof StringSchema) {\n      List<String> enums = SwaggerEnum.DYNAMIC.readEnumValues(enumClass);\n      property.setEnum(enums);\n    }\n\n    if (property instanceof NumberSchema) {\n      List<Integer> enums = SwaggerEnum.DYNAMIC.readEnumValues(enumClass);\n      property.setEnum(enums);\n    }\n\n    return property;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/SwaggerEnum.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.extend;\n\nimport static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Field;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.base.DynamicEnum;\nimport org.apache.servicecomb.foundation.common.base.EnumUtils;\n\nimport io.swagger.v3.core.util.Json;\nimport io.swagger.v3.oas.annotations.Parameter;\n\n\npublic enum SwaggerEnum {\n  JDK {\n    @SuppressWarnings({\"unchecked\", \"deprecation\"})\n    @Override\n    protected <T> T readEnumValue(Field enumField) {\n      Enum<?> enumValue = EnumUtils.readEnum(enumField);\n      return (T) Json.mapper().getSerializationConfig().getAnnotationIntrospector().findEnumValue(enumValue);\n    }\n  },\n  DYNAMIC {\n    @Override\n    protected <T> T readEnumValue(Field enumField) {\n      DynamicEnum<T> enumValue = EnumUtils.readEnum(enumField);\n      return enumValue.getValue();\n    }\n  };\n\n  public String findPropertyDescription(Class<?> enumClass, Annotation[] annotations) {\n    StringBuilder sb = new StringBuilder();\n\n    String propertyDescription = readDescription(annotations, null);\n    if (StringUtils.isNotEmpty(propertyDescription)) {\n      appendLine(sb, propertyDescription);\n    }\n\n    EnumUtils.findEnumFields(enumClass).forEach(enumField -> {\n      Object enumValue = readEnumValue(enumField);\n      String description = readDescription(enumField.getAnnotations(), \"\");\n      appendLine(sb, \"- %s: %s\", enumValue, description);\n    });\n\n    return sb.toString();\n  }\n\n  public <T> List<T> readEnumValues(Class<?> enumClass) {\n    return EnumUtils.findEnumFields(enumClass)\n        .map(this::<T>readEnumValue)\n        .collect(Collectors.toList());\n  }\n\n  protected abstract <T> T readEnumValue(Field enumField);\n\n  @SuppressWarnings(\"unchecked\")\n  private <T extends Annotation> T findAnnotation(Annotation[] annotations, Class<T> cls) {\n    if (annotations == null) {\n      return null;\n    }\n\n    return Arrays.stream(annotations)\n        .filter(annotation -> cls.isAssignableFrom(annotation.getClass()))\n        .map(annotation -> (T) annotation)\n        .findAny()\n        .orElse(null);\n  }\n\n  private String readDescription(Annotation[] annotations, String defaultDescription) {\n    Parameter apiParam = findAnnotation(annotations, Parameter.class);\n    if (apiParam != null && StringUtils.isNotEmpty(apiParam.description())) {\n      return apiParam.description();\n    }\n\n    return defaultDescription;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/annotations/RawJsonRequestBody.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.annotations;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target({ElementType.PARAMETER})\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\npublic @interface RawJsonRequestBody {\n  // aliasFor \"name\"\n  String value() default \"\";\n\n  // aliasFor \"value\"\n  String name() default \"\";\n\n  boolean required() default true;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.introspector;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.base.EnumUtils;\nimport org.apache.servicecomb.swagger.extend.SwaggerEnum;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport com.fasterxml.jackson.databind.introspect.Annotated;\n\nimport io.swagger.v3.core.jackson.SwaggerAnnotationIntrospector;\n\nimport java.util.Objects;\n\n\npublic class JsonPropertyIntrospector extends SwaggerAnnotationIntrospector {\n  private static final long serialVersionUID = 4157263023893695762L;\n\n  @SuppressWarnings(\"deprecation\")\n  @Override\n  public String findEnumValue(Enum<?> value) {\n    try {\n      JsonProperty annotation = value.getClass().getField(value.name()).getAnnotation(JsonProperty.class);\n      if (null == annotation || StringUtils.isEmpty(annotation.value())) {\n        return super.findEnumValue(value);\n      }\n      return annotation.value();\n    } catch (NoSuchFieldException e) {\n      return super.findEnumValue(value);\n    }\n  }\n\n  @Override\n  public String findPropertyDescription(Annotated annotated) {\n    Class<?> enumClass = annotated.getRawType();\n    if (enumClass.isEnum() && Objects.nonNull(annotated.getAnnotated())) {\n      return SwaggerEnum.JDK.findPropertyDescription(enumClass, annotated.getAnnotated().getAnnotations());\n    }\n    if (EnumUtils.isDynamicEnum(enumClass) && Objects.nonNull(annotated.getAnnotated())) {\n      return SwaggerEnum.DYNAMIC.findPropertyDescription(enumClass, annotated.getAnnotated().getAnnotations());\n    }\n\n    return super.findPropertyDescription(annotated);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/module/EnumModuleExt.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.module;\n\nimport org.apache.servicecomb.swagger.extend.introspector.JsonPropertyIntrospector;\n\nimport com.fasterxml.jackson.databind.module.SimpleModule;\n\npublic class EnumModuleExt extends SimpleModule {\n  private static final long serialVersionUID = 2934449381601447264L;\n\n  public EnumModuleExt() {\n    super(\"SCB-swagger-enum\");\n  }\n\n  @Override\n  public void setupModule(SetupContext context) {\n    context.insertAnnotationIntrospector(new JsonPropertyIntrospector());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/creator/ByteArrayPropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.property.creator;\n\nimport io.swagger.v3.oas.models.media.ByteArraySchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\n/**\n * Swagger core will generate byte array to type=array, this is not correct.\n * In Open API, byte array should use type=string,format=byte.\n */\n@SuppressWarnings({\"rawtypes\"})\npublic class ByteArrayPropertyCreator implements PropertyCreator {\n\n  private final Class<?>[] classes = {Byte[].class, byte[].class};\n\n  @Override\n  public Schema<?> createProperty() {\n    return new ByteArraySchema();\n  }\n\n  @Override\n  public Class<?>[] classes() {\n    return classes;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/creator/BytePropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.property.creator;\n\n\nimport io.swagger.v3.oas.models.media.IntegerSchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\n/**\n * Swagger core will generate byte to type=string,format=byte, this is not correct.\n * In Open API, type=string,format=byte is for byte array.\n */\n@SuppressWarnings({\"rawtypes\"})\npublic class BytePropertyCreator implements PropertyCreator {\n\n  private final Class<?>[] classes = {Byte.class, byte.class};\n\n  @Override\n  public Schema<?> createProperty() {\n    return new IntegerSchema();\n  }\n\n  @Override\n  public Class<?>[] classes() {\n    return classes;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/creator/InputStreamPropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.property.creator;\n\nimport java.io.InputStream;\n\nimport io.swagger.v3.oas.models.media.ByteArraySchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic class InputStreamPropertyCreator implements PropertyCreator {\n\n  private final Class<?>[] classes = {InputStream.class};\n\n  @Override\n  public Schema<?> createProperty() {\n    return new ByteArraySchema();\n  }\n\n  @Override\n  public Class<?>[] classes() {\n    return classes;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/creator/PartPropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.property.creator;\n\nimport io.swagger.v3.oas.models.media.FileSchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport jakarta.servlet.http.Part;\n\npublic class PartPropertyCreator implements PropertyCreator {\n  private final Class<?>[] classes = {Part.class};\n\n  @Override\n  public Schema<?> createProperty() {\n    return new FileSchema();\n  }\n\n  @Override\n  public Class<?>[] classes() {\n    return classes;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/property/creator/PropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.property.creator;\n\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings({\"rawtypes\"})\npublic interface PropertyCreator {\n  Schema<?> createProperty();\n\n  Class<?>[] classes();\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.reflect.Type;\n\npublic interface ClassAnnotationProcessor<ANNOTATION> {\n  Type getProcessType();\n\n  void process(SwaggerGenerator swaggerGenerator, ANNOTATION annotation);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/MethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.reflect.Type;\n\npublic interface MethodAnnotationProcessor<ANNOTATION> {\n  Type getProcessType();\n\n  void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, ANNOTATION annotation);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/OperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\n\nimport org.apache.servicecomb.swagger.generator.core.OperationGeneratorContext;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\n\npublic interface OperationGenerator {\n  OpenAPI getSwagger();\n\n  Operation getOperation();\n\n  void setHttpMethod(String httpMethod);\n\n  String getHttpMethod();\n\n  void addOperationToSwagger();\n\n  void setPath(String value);\n\n  OperationGeneratorContext getOperationGeneratorContext();\n\n  /**\n   * Used to check if one of operation has form parameter\n   */\n  boolean isForm();\n\n  /**\n   * Used to check if one of operation form parameter is binary\n   */\n  boolean isBinary();\n\n  /**\n   *\n   * Used to check if this operation is websocket\n   */\n  boolean isWebsocket();\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.reflect.Type;\n\npublic interface ParameterAnnotationProcessor<ANNOTATION> {\n  Type getProcessType();\n\n  /**\n   * Get parameter name from annotation. This method is used in both\n   * swagger generation and invocation. In invocation, need to find the\n   * swagger parameter name of the method parameter.\n   */\n  String getParameterName(ANNOTATION annotation);\n\n  void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, ANNOTATION annotation);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.annotation.Annotation;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.core.ParameterGeneratorContext;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.MediaType;\nimport io.swagger.v3.oas.models.media.ObjectSchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.CookieParameter;\nimport io.swagger.v3.oas.models.parameters.HeaderParameter;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.PathParameter;\nimport io.swagger.v3.oas.models.parameters.QueryParameter;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\npublic class ParameterGenerator {\n  private final List<Annotation> annotations;\n\n  private final OperationGenerator operationGenerator;\n\n  private final ParameterGeneratorContext parameterGeneratorContext;\n\n  /**\n   * Used for pojo wrap parameter, while parameter type is null.\n   */\n  public ParameterGenerator(OperationGenerator operationGenerator, String parameterName, Schema<?> schema) {\n    this.operationGenerator = operationGenerator;\n    this.parameterGeneratorContext = new ParameterGeneratorContext(operationGenerator.getOperationGeneratorContext());\n    this.parameterGeneratorContext.setParameterName(parameterName);\n    this.parameterGeneratorContext.setSchema(schema);\n    this.annotations = Collections.emptyList();\n  }\n\n  /**\n   * Used for @BeanParam like parameters, while extract JavaType of the bean parameter type.\n   */\n  public ParameterGenerator(OperationGenerator operationGenerator,\n      Map<String, List<Annotation>> methodAnnotationMap,\n      String parameterName,\n      Annotation[] parameterAnnotations, JavaType genericType) {\n    this.operationGenerator = operationGenerator;\n    this.annotations = SwaggerGeneratorUtils.collectParameterAnnotations(parameterAnnotations,\n        methodAnnotationMap,\n        parameterName);\n    this.parameterGeneratorContext = new ParameterGeneratorContext(operationGenerator.getOperationGeneratorContext());\n    this.parameterGeneratorContext.setParameterName(parameterName);\n    this.parameterGeneratorContext.setParameterType(genericType);\n  }\n\n  /**\n   * Used for normal method parameter initialization, while extract JavaType from method parameter.\n   */\n  public ParameterGenerator(OperationGenerator operationGenerator,\n      Map<String, List<Annotation>> methodAnnotationMap,\n      java.lang.reflect.Parameter methodParameter, JavaType genericType) {\n    this(operationGenerator,\n        methodAnnotationMap,\n        methodParameter.isNamePresent() ? methodParameter.getName() : null,\n        methodParameter.getAnnotations(),\n        genericType);\n  }\n\n  /**\n   * Used for annotation defined parameter, while initial parameter type is null\n   * and will extract JavaType annotation processors.\n   */\n  public ParameterGenerator(OperationGenerator operationGenerator, String parameterName, List<Annotation> annotations) {\n    this.operationGenerator = operationGenerator;\n    this.parameterGeneratorContext = new ParameterGeneratorContext(operationGenerator.getOperationGeneratorContext());\n    this.parameterGeneratorContext.setParameterName(parameterName);\n    this.annotations = annotations;\n  }\n\n  public ParameterGeneratorContext getParameterGeneratorContext() {\n    return this.parameterGeneratorContext;\n  }\n\n  public List<Annotation> getAnnotations() {\n    return annotations;\n  }\n\n  public JavaType getGenericType() {\n    return this.parameterGeneratorContext.getParameterType();\n  }\n\n  public HttpParameterType getHttpParameterType() {\n    return this.parameterGeneratorContext.getHttpParameterType();\n  }\n\n  public void setHttpParameterType(HttpParameterType httpParameterType) {\n    this.parameterGeneratorContext.setHttpParameterType(httpParameterType);\n  }\n\n  public boolean isForm() {\n    return parameterGeneratorContext.isForm();\n  }\n\n  public boolean isBinary() {\n    return parameterGeneratorContext.isBinary();\n  }\n\n  public void generate() {\n    this.parameterGeneratorContext.updateConsumes(\n        this.operationGenerator.isForm(), this.operationGenerator.isBinary(), this.operationGenerator.isWebsocket());\n\n    if (this.parameterGeneratorContext.getHttpParameterType() == HttpParameterType.BODY) {\n      if (parameterGeneratorContext.getSupportedConsumes().size() == 0) {\n        throw new IllegalArgumentException(\"Consumes not provided for BODY parameter, or is empty \"\n            + \"by annotations rule.\");\n      }\n      RequestBody requestBody = new RequestBody();\n      requestBody.setRequired(parameterGeneratorContext.getRequired());\n      Map<String, Object> extensions = new HashMap<>();\n      extensions.put(SwaggerConst.EXT_BODY_NAME, parameterGeneratorContext.getParameterName());\n      if (parameterGeneratorContext.getRawJson() != null) {\n        extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, parameterGeneratorContext.getRawJson());\n      }\n      requestBody.setExtensions(extensions);\n      requestBody.setContent(new Content());\n      for (String media : parameterGeneratorContext.getSupportedConsumes()) {\n        MediaType mediaType = new MediaType();\n        mediaType.setSchema(parameterGeneratorContext.getSchema());\n        requestBody.getContent().addMediaType(media, mediaType);\n      }\n      this.operationGenerator.getOperation().setRequestBody(requestBody);\n      return;\n    }\n    if (this.parameterGeneratorContext.getHttpParameterType() == HttpParameterType.FORM) {\n      if (parameterGeneratorContext.getSupportedConsumes().size() == 0) {\n        throw new IllegalArgumentException(\"Consumes not provided for FORM parameter, or is empty \"\n            + \"by annotations rule.\");\n      }\n      RequestBody requestBody = this.operationGenerator.getOperation().getRequestBody();\n      if (requestBody == null) {\n        requestBody = new RequestBody();\n        requestBody.setContent(new Content());\n        this.operationGenerator.getOperation().setRequestBody(requestBody);\n      }\n      for (String media : parameterGeneratorContext.getSupportedConsumes()) {\n        MediaType mediaType = requestBody.getContent().get(media);\n        if (mediaType == null) {\n          mediaType = new MediaType();\n          mediaType.setSchema(new ObjectSchema());\n          requestBody.getContent().addMediaType(media, mediaType);\n        }\n        mediaType.getSchema().addProperty(parameterGeneratorContext.getParameterName(),\n            parameterGeneratorContext.getSchema());\n      }\n      return;\n    }\n    Parameter parameter;\n    switch (this.parameterGeneratorContext.getHttpParameterType()) {\n      case PATH -> parameter = new PathParameter();\n      case QUERY -> parameter = new QueryParameter();\n      case HEADER -> parameter = new HeaderParameter();\n      case COOKIE -> parameter = new CookieParameter();\n      default -> throw new IllegalStateException(\"not support httpParameterType \"\n          + this.parameterGeneratorContext.getHttpParameterType());\n    }\n    parameter.setName(parameterGeneratorContext.getParameterName());\n    parameter.setSchema(parameterGeneratorContext.getSchema());\n    parameter.setRequired(parameterGeneratorContext.getRequired());\n    parameter.setExplode(parameterGeneratorContext.getExplode());\n    this.operationGenerator.getOperation().addParametersItem(parameter);\n\n    // validations and other annotations supported by swagger default\n    if (parameterGeneratorContext.getParameterType() != null) {\n      io.swagger.v3.core.util.ParameterProcessor.applyAnnotations(parameter,\n          parameterGeneratorContext.getParameterType(),\n          annotations, operationGenerator.getSwagger().getComponents(),\n          null, null, null);\n    }\n    // spring mvc DefaultValue annotation not processed by swagger api.\n    if (parameterGeneratorContext.getDefaultValue() != null) {\n      parameter.getSchema().setDefault(parameterGeneratorContext.getDefaultValue());\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic interface ParameterTypeProcessor {\n  JavaType getProcessType();\n\n  void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ResponseTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.reflect.Type;\n\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic interface ResponseTypeProcessor {\n  Type getProcessType();\n\n  /**\n   * @return if genericResponseType is CompletableFuture&lt;String&gt;, then return String\n   */\n  Type extractResponseType(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      Type genericResponseType);\n\n  default Type extractResponseType(Type genericResponseType) {\n    return extractResponseType(null, null, genericResponseType);\n  }\n\n  Schema<?> process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, Type genericResponseType);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerConst.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator;\n\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response;\n\npublic final class SwaggerConst {\n  private SwaggerConst() {\n\n  }\n\n  public static final String SUCCESS_KEY = String.valueOf(Response.Status.OK.getStatusCode());\n\n  public static final String DEFAULT_MEDIA_TYPE = MediaType.APPLICATION_JSON;\n\n  public static final String FORM_MEDIA_TYPE = MediaType.APPLICATION_FORM_URLENCODED;\n\n  public static final String FILE_MEDIA_TYPE = MediaType.MULTIPART_FORM_DATA;\n\n  public static final String PROTOBUF_TYPE = \"application/protobuf\";\n\n  public static final String WEBSOCKET_TYPE = \"application/websocket\";\n\n  public static final String TAG_WEBSOCKET = \"websocket\";\n\n  public static final String EXT_JAVA_INTF = \"x-java-interface\";\n\n  public static final String EXT_JAVA_CLASS = \"x-java-class\";\n\n  public static final String EXT_RAW_JSON_TYPE = \"x-raw-json\";\n\n  public static final String EXT_JSON_VIEW = \"x-json-view\";\n\n  public static final String EXT_BODY_NAME = \"x-name\";\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerContextRegister.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.reflect.Type;\n\npublic interface SwaggerContextRegister {\n  Type getContextType();\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.reflect.Method;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic interface SwaggerGenerator {\n  Logger LOGGER = LoggerFactory.getLogger(SwaggerGenerator.class);\n\n  static OpenAPI generate(Class<?> cls) {\n    return create(cls).generate();\n  }\n\n  static SwaggerGenerator create(Class<?> cls) {\n    List<SwaggerGeneratorFactory> factories = SPIServiceUtils.getOrLoadSortedService(SwaggerGeneratorFactory.class);\n    for (SwaggerGeneratorFactory factory : factories) {\n      if (factory.canProcess(cls)) {\n        LOGGER.info(\"select [{}] for [{}] to generate schema.\", factory.getClass().getName(), cls.getName());\n        return factory.create(cls);\n      }\n    }\n\n    throw new IllegalStateException(\"impossible, must be bug. can not generate swagger for \" + cls.getName());\n  }\n\n  SwaggerGeneratorContext getSwaggerGeneratorContext();\n\n  /**\n   * base path contains application server context-path, and schema base path.\n   */\n  void setBasePath(String basePath);\n\n  void scanClassAnnotation();\n\n  OpenAPI generate();\n\n  Class<?> getClazz();\n\n  OpenAPI getOpenAPI();\n\n  void setHttpMethod(String httpMethod);\n\n  void replaceMethodWhiteList(String... methodNames);\n\n  <T extends OperationGenerator> T createOperationGenerator(Method method);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerGeneratorFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\npublic interface SwaggerGeneratorFactory extends SPIOrder {\n  boolean canProcess(Class<?> cls);\n\n  SwaggerGenerator create(Class<?> cls);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerGeneratorUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Executable;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.generator.core.processor.response.DefaultResponseTypeProcessor;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.Module;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.core.util.Json;\n\n@SuppressWarnings(\"rawtypes\")\npublic final class SwaggerGeneratorUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerGeneratorUtils.class);\n\n  // all static fields load from SPI and stateless\n  private static final Set<JavaType> contextTypes = SPIServiceUtils.getOrLoadSortedService(SwaggerContextRegister.class)\n      .stream()\n      .map(swaggerContextRegister -> TypeFactory.defaultInstance()\n          .constructType(swaggerContextRegister.getContextType()))\n      .collect(Collectors.toSet());\n\n  private static final Map<Type, ClassAnnotationProcessor<?>> classAnnotationProcessors = new HashMap<>();\n\n  private static final Map<Type, MethodAnnotationProcessor<?>> methodAnnotationProcessors = new HashMap<>();\n\n  private static final Map<Type, ResponseTypeProcessor> responseTypeProcessors = new HashMap<>();\n\n  private static final DefaultResponseTypeProcessor defaultResponseTypeProcessor = new DefaultResponseTypeProcessor();\n\n  private static final List<ParameterAnnotationProcessor> parameterAnnotationProcessors = SPIServiceUtils\n      .getOrLoadSortedService(ParameterAnnotationProcessor.class);\n\n  private static final List<ParameterTypeProcessor> parameterTypeProcessors = SPIServiceUtils\n      .getOrLoadSortedService(ParameterTypeProcessor.class);\n\n  static {\n    // low order value has high priority\n    for (ClassAnnotationProcessor<?> processor : SPIServiceUtils\n        .getOrLoadSortedService(ClassAnnotationProcessor.class)) {\n      if (classAnnotationProcessors.putIfAbsent(processor.getProcessType(), processor) != null) {\n        LOGGER.info(\"ignore duplicated ClassAnnotationProcessor, type={}, processor={}.\",\n            processor.getProcessType().getTypeName(), processor.getClass().getName());\n      }\n    }\n\n    for (MethodAnnotationProcessor<?> processor : SPIServiceUtils\n        .getOrLoadSortedService(MethodAnnotationProcessor.class)) {\n      if (methodAnnotationProcessors.putIfAbsent(processor.getProcessType(), processor) != null) {\n        LOGGER.info(\"ignore duplicated MethodAnnotationProcessor, type={}, processor={}.\",\n            processor.getProcessType().getTypeName(), processor.getClass().getName());\n      }\n    }\n\n    for (ResponseTypeProcessor processor : SPIServiceUtils.getOrLoadSortedService(ResponseTypeProcessor.class)) {\n      if (responseTypeProcessors.putIfAbsent(processor.getProcessType(), processor) != null) {\n        LOGGER.info(\"ignore duplicated ResponseTypeProcessor, type={}, processor={}.\",\n            processor.getProcessType().getTypeName(), processor.getClass().getName());\n      }\n    }\n\n    List<Module> modules = SPIServiceUtils.getOrLoadSortedService(Module.class);\n    Json.mapper().registerModules(modules.toArray(new Module[0]));\n  }\n\n  private SwaggerGeneratorUtils() {\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <ANNOTATION> ClassAnnotationProcessor<ANNOTATION> findClassAnnotationProcessor(Type type) {\n    return (ClassAnnotationProcessor<ANNOTATION>) classAnnotationProcessors.get(type);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <ANNOTATION> MethodAnnotationProcessor<ANNOTATION> findMethodAnnotationProcessor(Type type) {\n    return (MethodAnnotationProcessor<ANNOTATION>) methodAnnotationProcessors.get(type);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static ParameterAnnotationProcessor<Annotation> findParameterAnnotationProcessor(Type type) {\n    for (ParameterAnnotationProcessor<Annotation> processor : parameterAnnotationProcessors) {\n      if (processor.getProcessType() == type) {\n        return processor;\n      }\n    }\n    return null;\n  }\n\n  public static ParameterTypeProcessor findParameterTypeProcessor(Type type) {\n    for (ParameterTypeProcessor processor : parameterTypeProcessors) {\n      if (processor.getProcessType() == type) {\n        return processor;\n      }\n    }\n    return null;\n  }\n\n  public static ResponseTypeProcessor findResponseTypeProcessor(Type type) {\n    ResponseTypeProcessor processor = responseTypeProcessors.get(type);\n    if (processor != null) {\n      return processor;\n    }\n\n    if (type instanceof ParameterizedType) {\n      return responseTypeProcessors.getOrDefault(((ParameterizedType) type).getRawType(), defaultResponseTypeProcessor);\n    }\n\n    return defaultResponseTypeProcessor;\n  }\n\n  public static boolean isContextParameter(JavaType type) {\n    return contextTypes.contains(type);\n  }\n\n  public static Annotation[] collectAnnotations(BeanPropertyDefinition propertyDefinition) {\n    List<Annotation> annotations = new ArrayList<>();\n    if (propertyDefinition.getField() != null) {\n      Collections.addAll(annotations, propertyDefinition.getField().getAnnotated().getAnnotations());\n    }\n    if (propertyDefinition.getGetter() != null) {\n      Collections.addAll(annotations, propertyDefinition.getGetter().getAnnotated().getAnnotations());\n    }\n    if (propertyDefinition.getSetter() != null) {\n      Collections.addAll(annotations, propertyDefinition.getSetter().getAnnotated().getAnnotations());\n    }\n    return annotations.toArray(new Annotation[0]);\n  }\n\n  public static String collectParameterName(java.lang.reflect.Parameter methodParameter) {\n    return collectParameterName(methodParameter.getDeclaringExecutable(), methodParameter.getAnnotations(),\n        methodParameter.isNamePresent() ? methodParameter.getName() : null);\n  }\n\n  public static String collectParameterName(Method method, BeanPropertyDefinition propertyDefinition) {\n    Annotation[] annotations = collectAnnotations(propertyDefinition);\n    return collectParameterName(method, annotations, propertyDefinition.getName());\n  }\n\n  public static String collectParameterName(Executable executable, Annotation[] annotations, String defaultName) {\n    // 1.annotations\n    //   it's ambiguous to use different name in different annotation\n    //   so we only read the first available name\n    for (Annotation annotation : annotations) {\n      ParameterAnnotationProcessor<Annotation> processor = findParameterAnnotationProcessor(\n          annotation.annotationType());\n      if (processor == null) {\n        continue;\n      }\n\n      String name = processor.getParameterName(annotation);\n      if (StringUtils.isNotEmpty(name)) {\n        return name;\n      }\n    }\n\n    // 2.use signature name\n    // ensure present parameter name\n    if (StringUtils.isNotEmpty(defaultName)) {\n      return defaultName;\n    }\n\n    String msg = String.format(\"\"\"\n            parameter name is not present, method=%s:%s\n            solution:\n              change pom.xml, add compiler argument: -parameters, for example:\n                <plugin>\n                  <groupId>org.apache.maven.plugins</groupId>\n                  <artifactId>maven-compiler-plugin</artifactId>\n                  <configuration>\n                    <compilerArgument>-parameters</compilerArgument>\n                  </configuration>\n                </plugin>\"\"\",\n        executable.getDeclaringClass().getName(), executable.getName());\n    throw new IllegalStateException(msg);\n  }\n\n  public static List<Annotation> collectParameterAnnotations(Annotation[] parameterAnnotations,\n      Map<String, List<Annotation>> methodAnnotationMap, String parameterName) {\n    List<Annotation> methodAnnotations = methodAnnotationMap.remove(parameterName);\n    if (methodAnnotations == null) {\n      methodAnnotations = Collections.emptyList();\n    }\n\n    List<Annotation> annotations = new ArrayList<>();\n    Collections.addAll(annotations, parameterAnnotations);\n    annotations.addAll(methodAnnotations);\n\n    return annotations;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator;\n\n/**\n * A generic class to help classify implementations. Processors of swagger annotations\n * will implement this class.\n */\npublic abstract class SwaggerParameterAnnotationProcessor<ANNOTATION> implements\n    ParameterAnnotationProcessor<ANNOTATION> {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectAnnotations;\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findMethodAnnotationProcessor;\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findResponseTypeProcessor;\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.isContextParameter;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Map.Entry;\nimport java.util.Set;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.inject.PlaceholderResolver;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterTypeProcessor;\nimport org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;\n\nimport com.fasterxml.jackson.databind.BeanDescription;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.google.common.reflect.TypeToken;\n\nimport io.swagger.v3.core.util.Json;\nimport io.swagger.v3.core.util.ReflectionUtils;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.PathItem;\nimport io.swagger.v3.oas.models.Paths;\nimport io.swagger.v3.oas.models.headers.Header;\nimport io.swagger.v3.oas.models.media.Content;\nimport io.swagger.v3.oas.models.media.MediaType;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport jakarta.servlet.http.HttpServletResponse;\n\n@SuppressWarnings(\"rawtypes\")\npublic abstract class AbstractOperationGenerator implements OperationGenerator {\n  protected AbstractSwaggerGenerator swaggerGenerator;\n\n  protected OpenAPI swagger;\n\n  protected Class<?> clazz;\n\n  protected Method method;\n\n  protected String httpMethod;\n\n  protected List<ParameterGenerator> parameterGenerators = new ArrayList<>();\n\n  protected String path;\n\n  protected Operation swaggerOperation;\n\n  protected OperationGeneratorContext operationGeneratorContext;\n\n  public AbstractOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, Method method) {\n    this.swaggerGenerator = swaggerGenerator;\n    this.swagger = swaggerGenerator.getOpenAPI();\n    this.clazz = swaggerGenerator.getClazz();\n    this.method = method;\n    this.httpMethod = swaggerGenerator.getHttpMethod();\n\n    operationGeneratorContext = new OperationGeneratorContext(swaggerGenerator.getSwaggerGeneratorContext());\n    swaggerOperation = new Operation();\n  }\n\n  @Override\n  public OperationGeneratorContext getOperationGeneratorContext() {\n    return operationGeneratorContext;\n  }\n\n  @Override\n  public void setHttpMethod(String httpMethod) {\n    if (StringUtils.isEmpty(httpMethod)) {\n      return;\n    }\n\n    this.httpMethod = httpMethod.toUpperCase(Locale.US);\n  }\n\n  @Override\n  public OpenAPI getSwagger() {\n    return this.swagger;\n  }\n\n  @Override\n  public String getHttpMethod() {\n    return httpMethod;\n  }\n\n  @Override\n  public Operation getOperation() {\n    return swaggerOperation;\n  }\n\n  public String getOperationId() {\n    return swaggerOperation.getOperationId();\n  }\n\n  @Override\n  public void setPath(String path) {\n    path = new PlaceholderResolver().replaceFirst(path);\n    if (!path.startsWith(\"/\")) {\n      path = \"/\" + path;\n    }\n    this.path = path;\n  }\n\n  public void generate() {\n    scanMethodAnnotation();\n    scanMethodParameters();\n    scanResponse();\n    correctOperation();\n  }\n\n  protected void scanMethodAnnotation() {\n    for (Annotation annotation : Arrays.stream(method.getAnnotations())\n        .sorted(Comparator.comparing(a -> a.annotationType().getSimpleName()))\n        .collect(Collectors.toList())) {\n      MethodAnnotationProcessor<Annotation> processor = findMethodAnnotationProcessor(annotation.annotationType());\n      if (processor == null) {\n        continue;\n      }\n      processor.process(swaggerGenerator, this, annotation);\n    }\n\n    if (StringUtils.isEmpty(swaggerOperation.getOperationId())) {\n      swaggerOperation.setOperationId(MethodUtils.findSwaggerMethodName(method));\n    }\n  }\n\n  protected void scanMethodParameters() {\n    // init generators\n    initParameterGenerators();\n\n    // scan annotations and types\n    Set<String> names = new HashSet<>();\n    int bodyCount = 0;\n    for (ParameterGenerator parameterGenerator : parameterGenerators) {\n      scanMethodParameter(parameterGenerator);\n\n      if (!names.add(parameterGenerator.getParameterGeneratorContext().getParameterName())) {\n        throw new IllegalArgumentException(\n            String.format(\"not support duplicated parameter, name=%s.\",\n                parameterGenerator.getParameterGeneratorContext().getParameterName()));\n      }\n      if (parameterGenerator.getHttpParameterType() == HttpParameterType.BODY) {\n        if (bodyCount > 0) {\n          throw new IllegalArgumentException(String.format(\"Defined %d body parameter.\", bodyCount));\n        }\n        bodyCount++;\n      }\n    }\n\n    // generate\n    for (ParameterGenerator parameterGenerator : parameterGenerators) {\n      parameterGenerator.generate();\n    }\n  }\n\n  protected void initParameterGenerators() {\n    // 1.group method annotations by parameter name\n    // key is parameter name\n    Map<String, List<Annotation>> methodAnnotationMap = initMethodAnnotationByParameterName();\n\n    // 2.create ParameterGenerators by method parameters, merge annotations with method annotations\n    initMethodParameterGenerators(methodAnnotationMap);\n\n    // 3.create ParameterGenerators remains method annotations\n    initRemainMethodAnnotationsParameterGenerators(methodAnnotationMap);\n  }\n\n  protected void initMethodParameterGenerators(Map<String, List<Annotation>> methodAnnotationMap) {\n    for (java.lang.reflect.Parameter methodParameter : method.getParameters()) {\n      Type genericType = TypeToken.of(clazz)\n          .resolveType(methodParameter.getParameterizedType())\n          .getType();\n      ParameterGenerator parameterGenerator = new ParameterGenerator(\n          this, methodAnnotationMap, methodParameter,\n          TypeFactory.defaultInstance().constructType(genericType));\n      validateParameter(parameterGenerator.getGenericType());\n      if (isContextParameter(parameterGenerator.getGenericType())) {\n        continue;\n      }\n\n      // jaxrs: @BeanParam\n      // springmvc: is query, and is bean type\n      if (isAggregatedParameter(parameterGenerator, methodParameter)) {\n        extractAggregatedParameterGenerators(methodAnnotationMap, methodParameter);\n        continue;\n      }\n\n      parameterGenerators.add(parameterGenerator);\n    }\n  }\n\n  protected boolean isAggregatedParameter(ParameterGenerator parameterGenerator,\n      java.lang.reflect.Parameter methodParameter) {\n    return false;\n  }\n\n  protected void extractAggregatedParameterGenerators(Map<String, List<Annotation>> methodAnnotationMap,\n      java.lang.reflect.Parameter methodParameter) {\n    JavaType javaType = TypeFactory.defaultInstance().constructType(methodParameter.getParameterizedType());\n    BeanDescription beanDescription = Json.mapper().getSerializationConfig().introspect(javaType);\n    for (BeanPropertyDefinition propertyDefinition : beanDescription.findProperties()) {\n      if (!propertyDefinition.couldSerialize()) {\n        continue;\n      }\n\n      Annotation[] annotations = collectAnnotations(propertyDefinition);\n      ParameterGenerator propertyParameterGenerator = new ParameterGenerator(this,\n          methodAnnotationMap,\n          propertyDefinition.getName(),\n          annotations,\n          propertyDefinition.getPrimaryType());\n      parameterGenerators.add(propertyParameterGenerator);\n    }\n  }\n\n  protected void initRemainMethodAnnotationsParameterGenerators(Map<String, List<Annotation>> methodAnnotationMap) {\n    for (Entry<String, List<Annotation>> entry : methodAnnotationMap.entrySet()) {\n      ParameterGenerator parameterGenerator = new ParameterGenerator(this, entry.getKey(), entry.getValue());\n      parameterGenerators.add(parameterGenerator);\n    }\n  }\n\n  private Map<String, List<Annotation>> initMethodAnnotationByParameterName() {\n    Map<String, List<Annotation>> methodAnnotations = new LinkedHashMap<>();\n    for (Annotation annotation : method.getAnnotations()) {\n      if (annotation instanceof io.swagger.v3.oas.annotations.Parameters) {\n        for (io.swagger.v3.oas.annotations.Parameter apiImplicitParam\n            : ((io.swagger.v3.oas.annotations.Parameters) annotation).value()) {\n          addMethodAnnotationByParameterName(methodAnnotations, apiImplicitParam.name(), apiImplicitParam);\n        }\n        continue;\n      }\n\n      if (annotation instanceof io.swagger.v3.oas.annotations.Parameter) {\n        addMethodAnnotationByParameterName(methodAnnotations,\n            ((io.swagger.v3.oas.annotations.Parameter) annotation).name(), annotation);\n      }\n    }\n    return methodAnnotations;\n  }\n\n  private void addMethodAnnotationByParameterName(Map<String, List<Annotation>> methodAnnotations, String name,\n      Annotation annotation) {\n    if (StringUtils.isEmpty(name)) {\n      throw new IllegalStateException(String.format(\"%s.name should not be empty. method=%s:%s\",\n          annotation.annotationType().getSimpleName(),\n          method.getDeclaringClass().getName(),\n          method.getName()));\n    }\n\n    methodAnnotations.computeIfAbsent(name, n -> new ArrayList<>())\n        .add(annotation);\n  }\n\n  protected void validateParameter(JavaType type) {\n    if (type.isTypeOrSubTypeOf(HttpServletResponse.class)) {\n      // not support, log the reason\n      throw new IllegalStateException(\n          \"all input/output of ServiceComb operation are models, not allow to use HttpServletResponse.\");\n    }\n  }\n\n  protected void scanMethodParameter(ParameterGenerator parameterGenerator) {\n    for (Annotation annotation : parameterGenerator.getAnnotations()) {\n      ParameterAnnotationProcessor<Annotation> processor = SwaggerGeneratorUtils\n          .findParameterAnnotationProcessor(annotation.annotationType());\n      if (processor != null) {\n        processor.process(this.swaggerGenerator, this, parameterGenerator, annotation);\n      }\n    }\n\n    Schema<?> schema = parameterGenerator.getParameterGeneratorContext().getSchema();\n    if (schema == null) {\n      JavaType parameterType = parameterGenerator.getGenericType();\n      ParameterTypeProcessor processor = SwaggerGeneratorUtils.findParameterTypeProcessor(parameterType);\n      if (processor != null) {\n        processor.process(this.swaggerGenerator, this, parameterGenerator);\n      } else {\n        parameterGenerator.getParameterGeneratorContext().setSchema(SwaggerUtils.resolveTypeSchemas(this.swagger,\n            parameterType));\n      }\n    }\n  }\n\n  @Override\n  public boolean isForm() {\n    for (ParameterGenerator parameterGenerator : parameterGenerators) {\n      if (parameterGenerator.isForm()) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  @Override\n  public boolean isBinary() {\n    for (ParameterGenerator parameterGenerator : parameterGenerators) {\n      if (parameterGenerator.isBinary()) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  @Override\n  public boolean isWebsocket() {\n    return this.swaggerOperation.getTags() != null &&\n        this.swaggerOperation.getTags().contains(SwaggerConst.TAG_WEBSOCKET);\n  }\n\n  @Override\n  public void addOperationToSwagger() {\n    if (StringUtils.isEmpty(httpMethod)) {\n      return;\n    }\n\n    if (swagger.getPaths() == null) {\n      swagger.setPaths(new Paths());\n    }\n\n    PathItem pathObj = swagger.getPaths().get(path);\n    if (pathObj == null) {\n      pathObj = new PathItem();\n      swagger.path(path, pathObj);\n    } else if (SwaggerUtils.methodExists(pathObj, httpMethod)) {\n      throw new IllegalStateException(String.format(\"Duplicate operation path detected. method=%s:%s.\",\n          method.getDeclaringClass().getName(),\n          method.getName()));\n    }\n\n    pathObj.operation(PathItem.HttpMethod.valueOf(httpMethod), swaggerOperation);\n  }\n\n  public void correctOperation() {\n    SwaggerUtils.correctResponses(swaggerOperation);\n  }\n\n  public void scanResponse() {\n    operationGeneratorContext.updateProduces();\n    swaggerOperation.setResponses(new ApiResponses());\n    for (Entry<String, Schema<?>> response : operationGeneratorContext.getResponses().entrySet()) {\n      ApiResponse apiResponse = new ApiResponse();\n      if (StringUtils.isNotEmpty(operationGeneratorContext.getResponseDescriptions().get(response.getKey()))) {\n        apiResponse.setDescription(operationGeneratorContext.getResponseDescriptions().get(response.getKey()));\n      }\n      if (operationGeneratorContext.getResponseHeaders().get(response.getKey()) != null) {\n        operationGeneratorContext.getResponseHeaders().get(response.getKey()).forEach((k, v) -> {\n          Header header = new Header();\n          header.setSchema(v);\n          apiResponse.addHeaderObject(k, header);\n        });\n      }\n      Schema<?> schema = response.getValue() != null ? response.getValue() :\n          createResponseModel();\n\n      if (schema == null) {\n        swaggerOperation.getResponses().addApiResponse(response.getKey(), apiResponse);\n        continue;\n      }\n\n      apiResponse.setContent(new Content());\n      // file download using WILDCARD content-type\n      if (\"string\".equals(schema.getType()) && \"binary\".equals(schema.getFormat())) {\n        MediaType mediaType = new MediaType();\n        mediaType.setSchema(schema);\n        apiResponse.getContent().addMediaType(jakarta.ws.rs.core.MediaType.WILDCARD, mediaType);\n      } else {\n        for (String produce : operationGeneratorContext.getSupportedProduces()) {\n          MediaType mediaType = new MediaType();\n          mediaType.setSchema(schema);\n          apiResponse.getContent().addMediaType(produce, mediaType);\n        }\n      }\n      swaggerOperation.getResponses().addApiResponse(response.getKey(), apiResponse);\n    }\n  }\n\n  protected Schema<?> createResponseModel() {\n    Type responseType =\n        TypeToken.of(clazz)\n            .resolveType(method.getGenericReturnType())\n            .getType();\n    if (ReflectionUtils.isVoid(responseType)) {\n      return null;\n    }\n\n    ResponseTypeProcessor processor = findResponseTypeProcessor(responseType);\n    return processor.process(swaggerGenerator, this, responseType);\n  }\n\n  public Method getMethod() {\n    return method;\n  }\n\n  public List<ParameterGenerator> getParameterGenerators() {\n    return parameterGenerators;\n  }\n\n  public Operation getSwaggerOperation() {\n    return swaggerOperation;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractSwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findClassAnnotationProcessor;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.config.inject.PlaceholderResolver;\nimport org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Paths;\nimport io.swagger.v3.oas.models.info.Info;\nimport io.swagger.v3.oas.models.servers.Server;\n\n\n/**\n * <pre>\n * support:\n * 1.pojo + swagger annotation\n *   wrap all input parameter to be fields of body\n * 2.pojo + swagger annotation + jaxrs annotation\n * 3.pojo + swagger annotation + springmvc annotation\n * </pre>\n */\npublic abstract class AbstractSwaggerGenerator implements SwaggerGenerator {\n  protected SwaggerGeneratorContext swaggerGeneratorContext = new SwaggerGeneratorContext();\n\n  protected Class<?> cls;\n\n  protected OpenAPI openAPI;\n\n  // allowed to control only process some methods\n  // empty means all methods are available\n  protected Set<String> methodWhiteList = new HashSet<>();\n\n  // key is operationId\n  // to check if operationId is duplicated\n  protected Map<String, AbstractOperationGenerator> operationGenerators = new LinkedHashMap<>();\n\n  protected String httpMethod;\n\n  public AbstractSwaggerGenerator(Class<?> cls) {\n    this.openAPI = new OpenAPI();\n    this.openAPI.components(new Components())\n        .paths(new Paths())\n        .servers(new ArrayList<>())\n        .info(new Info());\n    this.cls = cls;\n  }\n\n  public OpenAPI getOpenAPI() {\n    return openAPI;\n  }\n\n  @Override\n  public Class<?> getClazz() {\n    return cls;\n  }\n\n  public String getHttpMethod() {\n    return httpMethod;\n  }\n\n  @Override\n  public void setHttpMethod(String httpMethod) {\n    this.httpMethod = httpMethod.toUpperCase(Locale.US);\n  }\n\n  @Override\n  public SwaggerGeneratorContext getSwaggerGeneratorContext() {\n    return swaggerGeneratorContext;\n  }\n\n  public OpenAPI generate() {\n    LOGGER.info(\"generate schema from [{}]\", cls);\n    scanClassAnnotation();\n\n    scanMethods();\n    addOperationsToSwagger();\n\n    correctSwagger();\n\n    return openAPI;\n  }\n\n  public void scanClassAnnotation() {\n    for (Annotation annotation : cls.getAnnotations()) {\n      ClassAnnotationProcessor<Annotation> processor = findClassAnnotationProcessor(annotation.annotationType());\n      if (processor == null) {\n        continue;\n      }\n      processor.process(this, annotation);\n    }\n  }\n\n  /**\n   * fill empty and required field to be default value\n   * if can not build default value, then throw exceptions\n   */\n  protected void correctSwagger() {\n    correctBasePath();\n    correctInfo();\n  }\n\n  private void correctBasePath() {\n    if (openAPI.getServers() == null) {\n      openAPI.setServers(new ArrayList<>());\n    }\n    if (openAPI.getServers().size() <= 0) {\n      Server server = new Server();\n      server.setUrl(\"/\" + cls.getSimpleName());\n      openAPI.getServers().add(server);\n    }\n  }\n\n  private void correctInfo() {\n    Info info = openAPI.getInfo();\n    if (info == null) {\n      info = new Info();\n      openAPI.setInfo(info);\n    }\n\n    if (StringUtils.isEmpty(info.getTitle())) {\n      info.setTitle(\"swagger definition for \" + cls.getName());\n    }\n    if (StringUtils.isEmpty(info.getVersion())) {\n      info.setVersion(\"1.0.0\");\n    }\n  }\n\n  @Override\n  public void replaceMethodWhiteList(String... methodNames) {\n    methodWhiteList.clear();\n\n    if (methodNames == null || methodNames.length == 0) {\n      return;\n    }\n\n    methodWhiteList.addAll(Arrays.asList(methodNames));\n  }\n\n  /**\n   * Whether this method should be processed as a swagger operation\n   * @return true if this isn't a swagger operation; otherwise, false.\n   */\n  protected boolean isSkipMethod(Method method) {\n    if (method.getDeclaringClass().getName().equals(Object.class.getName())) {\n      return true;\n    }\n    // skip static method\n    int modifiers = method.getModifiers();\n    if (Modifier.isStatic(modifiers)) {\n      return true;\n    }\n    // skip bridge method\n    if (method.isBridge()) {\n      return true;\n    }\n\n    Operation apiOperation = method.getAnnotation(Operation.class);\n    if (apiOperation != null && apiOperation.hidden()) {\n      return true;\n    }\n\n    if (!methodWhiteList.isEmpty()) {\n      return !methodWhiteList.contains(MethodUtils.findSwaggerMethodName(method));\n    }\n\n    return false;\n  }\n\n  protected void scanMethods() {\n    List<Method> methods = MethodUtils.findSwaggerMethods(cls);\n\n    for (Method method : methods) {\n      if (isSkipMethod(method)) {\n        continue;\n      }\n\n      AbstractOperationGenerator operationGenerator = createOperationGenerator(method);\n      operationGenerator.setHttpMethod(httpMethod);\n      try {\n        operationGenerator.generate();\n      } catch (Throwable e) {\n        String msg = String.format(\"Generate swagger operation failed, method=%s:%s, cause=%s\",\n            this.cls.getSimpleName(), method.getName(), e.getMessage());\n        throw new IllegalStateException(msg, e);\n      }\n\n      if (StringUtils.isEmpty(operationGenerator.httpMethod)) {\n        throw new IllegalStateException(\n            String.format(\"HttpMethod must not both be empty in class and method, method=%s:%s.\",\n                cls.getName(), method.getName()));\n      }\n\n      if (operationGenerators.putIfAbsent(operationGenerator.getOperationId(), operationGenerator) != null) {\n        throw new IllegalStateException(\n            String.format(\"OperationId must be unique. method=%s:%s.\", cls.getName(), method.getName()));\n      }\n    }\n  }\n\n  protected void addOperationsToSwagger() {\n    for (OperationGenerator operationGenerator : operationGenerators.values()) {\n      operationGenerator.addOperationToSwagger();\n    }\n  }\n\n  @Override\n  public void setBasePath(String basePath) {\n    basePath = new PlaceholderResolver().replaceFirst(basePath);\n    if (openAPI.getServers() == null) {\n      openAPI.setServers(new ArrayList<>());\n    }\n    if (openAPI.getServers().size() == 0) {\n      openAPI.getServers().add(new Server());\n    }\n    openAPI.getServers().get(0).setUrl(basePath);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGeneratorContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic class OperationGeneratorContext extends SwaggerGeneratorContext {\n  private final Map<String, Schema<?>> responses = new HashMap<>();\n\n  private JavaType responseType;\n\n  private final Map<String, String> responseDescriptions = new HashMap<>();\n\n  // statusCode:headerName:headerSchema\n  private final Map<String, Map<String, Schema<?>>> responseHeaders = new HashMap<>();\n\n  public OperationGeneratorContext(SwaggerGeneratorContext parent) {\n    super(parent);\n    updateResponse(SwaggerConst.SUCCESS_KEY, null);\n  }\n\n  public Map<String, Schema<?>> getResponses() {\n    return responses;\n  }\n\n  public void updateResponse(String code, Schema<?> schema) {\n    this.responses.put(code, schema);\n  }\n\n  public JavaType getResponseType() {\n    return responseType;\n  }\n\n  public void setResponseType(JavaType responseType) {\n    this.responseType = responseType;\n  }\n\n  public Map<String, String> getResponseDescriptions() {\n    return responseDescriptions;\n  }\n\n  public void updateResponseDescription(String code, String description) {\n    this.responseDescriptions.put(code, description);\n  }\n\n  public Map<String, Map<String, Schema<?>>> getResponseHeaders() {\n    return responseHeaders;\n  }\n\n  public void updateResponseHeader(String code, String header, Schema<?> schema) {\n    this.responseHeaders.computeIfAbsent(code, key -> new HashMap<>());\n    this.responseHeaders.get(code).put(header, schema);\n  }\n\n  public void updateProduces() {\n    List<String> removed = new ArrayList<>();\n    for (String media : supportedProduces) {\n      if (SUPPORTED_BODY_CONTENT_TYPE.contains(media)) {\n        continue;\n      }\n      removed.add(media);\n    }\n    supportedProduces.removeAll(removed);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/ParameterGeneratorContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class ParameterGeneratorContext extends OperationGeneratorContext {\n  /**\n   * Parameter type. Maybe override by annotations. And for pojo wrapped parameter,\n   * this is null.\n   */\n  private JavaType parameterType;\n\n  private String parameterName;\n\n  private HttpParameterType httpParameterType;\n\n  private Boolean explode;\n\n  private Boolean required;\n\n  private Object defaultValue;\n\n  private Boolean rawJson;\n\n  private Schema<?> schema;\n\n  public ParameterGeneratorContext(OperationGeneratorContext parent) {\n    super(parent);\n  }\n\n  public JavaType getParameterType() {\n    return parameterType;\n  }\n\n  public void setParameterType(JavaType parameterType) {\n    this.parameterType = parameterType;\n  }\n\n  public String getParameterName() {\n    return parameterName;\n  }\n\n  public void setParameterName(String parameterName) {\n    this.parameterName = parameterName;\n  }\n\n  public Boolean getExplode() {\n    return explode;\n  }\n\n  public void setExplode(Boolean explode) {\n    this.explode = explode;\n  }\n\n  public Boolean getRequired() {\n    return required;\n  }\n\n  public void setRequired(Boolean required) {\n    this.required = required;\n  }\n\n  public Boolean getRawJson() {\n    return rawJson;\n  }\n\n  public void setRawJson(Boolean rawJson) {\n    this.rawJson = rawJson;\n  }\n\n  public Schema<?> getSchema() {\n    return schema;\n  }\n\n  public void setSchema(Schema<?> schema) {\n    this.schema = schema;\n  }\n\n  public HttpParameterType getHttpParameterType() {\n    return httpParameterType;\n  }\n\n  public void setHttpParameterType(HttpParameterType httpParameterType) {\n    this.httpParameterType = httpParameterType;\n  }\n\n  public Object getDefaultValue() {\n    return defaultValue;\n  }\n\n  public void setDefaultValue(Object defaultValue) {\n    this.defaultValue = defaultValue;\n  }\n\n  public void updateConsumes(boolean isForm, boolean isBinary, boolean isWebSocket) {\n    List<String> removed = new ArrayList<>();\n    if (isWebSocket) {\n      supportedConsumes.clear();\n      supportedConsumes.add(SwaggerConst.WEBSOCKET_TYPE);\n      return;\n    }\n\n    if (httpParameterType == HttpParameterType.BODY) {\n      if (isForm) {\n        throw new IllegalArgumentException(\"Both form and body parameter not allowed.\");\n      }\n      for (String media : supportedConsumes) {\n        if (SUPPORTED_BODY_CONTENT_TYPE.contains(media)) {\n          continue;\n        }\n        removed.add(media);\n      }\n      supportedConsumes.removeAll(removed);\n      return;\n    }\n\n    if (httpParameterType == HttpParameterType.FORM) {\n      for (String media : supportedConsumes) {\n        if (!SUPPORTED_FORM_CONTENT_TYPE.contains(media)) {\n          removed.add(media);\n          continue;\n        }\n        if (isBinary && supportedConsumes.contains(MediaType.APPLICATION_FORM_URLENCODED)) {\n          removed.add(MediaType.APPLICATION_FORM_URLENCODED);\n        }\n        if (!isBinary && supportedConsumes.contains(MediaType.MULTIPART_FORM_DATA)) {\n          removed.add(MediaType.MULTIPART_FORM_DATA);\n        }\n      }\n      supportedConsumes.removeAll(removed);\n      return;\n    }\n\n    supportedConsumes.clear();\n  }\n\n  public boolean isForm() {\n    return httpParameterType == HttpParameterType.FORM;\n  }\n\n  public boolean isBinary() {\n    if (\"string\".equals(this.schema.getType()) && \"binary\".equals(this.schema.getFormat())) {\n      return true;\n    }\n\n    return \"array\".equals(this.schema.getType()) &&\n        \"string\".equals(this.schema.getItems().getType()) &&\n        \"binary\".equals(this.schema.getItems().getFormat());\n  }\n\n  public boolean isObject() {\n    return \"object\".equals(this.schema.getType());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/SwaggerGeneratorContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\n\nimport jakarta.ws.rs.core.MediaType;\n\n/**\n * Context information to help generate specific open api parts.\n */\npublic class SwaggerGeneratorContext {\n  protected static final List<String> SUPPORTED_CONTENT_TYPE\n      = Arrays.asList(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN,\n      MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED, SwaggerConst.WEBSOCKET_TYPE,\n      MediaType.SERVER_SENT_EVENTS);\n\n  protected static final List<String> SUPPORTED_BODY_CONTENT_TYPE\n      = Arrays.asList(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE,\n      MediaType.TEXT_PLAIN);\n\n  protected static final List<String> SUPPORTED_FORM_CONTENT_TYPE\n      = Arrays.asList(MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED);\n\n  protected List<String> supportedConsumes;\n\n  protected List<String> supportedProduces;\n\n  public SwaggerGeneratorContext() {\n    supportedConsumes = new ArrayList<>();\n    supportedConsumes.addAll(SUPPORTED_CONTENT_TYPE);\n    supportedProduces = new ArrayList<>();\n    supportedProduces.addAll(SUPPORTED_CONTENT_TYPE);\n  }\n\n  public SwaggerGeneratorContext(SwaggerGeneratorContext parent) {\n    supportedConsumes = new ArrayList<>();\n    supportedConsumes.addAll(parent.supportedConsumes);\n    supportedProduces = new ArrayList<>();\n    supportedProduces.addAll(parent.supportedProduces);\n  }\n\n  public void updateProduces(List<String> produces) {\n    checkMediaTypeValid(produces);\n    supportedProduces.clear();\n    supportedProduces.addAll(produces);\n  }\n\n  public void updateConsumes(List<String> consumes) {\n    checkMediaTypeValid(consumes);\n    supportedConsumes.clear();\n    supportedConsumes.addAll(consumes);\n  }\n\n  public List<String> getSupportedConsumes() {\n    return supportedConsumes;\n  }\n\n  public List<String> getSupportedProduces() {\n    return supportedProduces;\n  }\n\n  private void checkMediaTypeValid(List<String> produces) {\n    for (String produce : produces) {\n      if (!SUPPORTED_CONTENT_TYPE.contains(produce)) {\n        throw new IllegalArgumentException(\"Not support media type \" + produce);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/model/HttpParameterType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.model;\n\nimport java.util.Locale;\n\nimport org.apache.commons.lang3.StringUtils;\n\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\n\npublic enum HttpParameterType {\n  /** io.swagger.v3.oas.annotations.enums.ParameterIn.PATH */\n  PATH,\n  /** io.swagger.v3.oas.annotations.enums.ParameterIn.QUERY */\n  QUERY,\n  /** io.swagger.v3.oas.annotations.enums.ParameterIn.HEADER */\n  HEADER,\n  /** io.swagger.v3.oas.annotations.enums.ParameterIn.COOKIE */\n  COOKIE,\n\n  /** request bodies: application/x-www-form-urlencoded, multipart/form-data */\n  FORM,\n\n  /** request bodies: application/json, etc. */\n  BODY;\n\n  public static HttpParameterType from(ParameterIn in) {\n    return switch (in) {\n      case COOKIE -> HttpParameterType.COOKIE;\n      case QUERY -> HttpParameterType.QUERY;\n      case HEADER -> HttpParameterType.HEADER;\n      case PATH -> HttpParameterType.PATH;\n      default -> null;\n    };\n  }\n\n  public static HttpParameterType parse(String value) {\n    if (StringUtils.isEmpty(value)) {\n      return null;\n    }\n\n    return HttpParameterType.valueOf(value.toUpperCase(Locale.US));\n  }\n\n  public static boolean isBodyParameter(HttpParameterType type) {\n    return BODY == type || FORM == type;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/model/SwaggerOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.model;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.PathItem.HttpMethod;\n\npublic class SwaggerOperation {\n  private final OpenAPI swagger;\n\n  private final String path;\n\n  private final HttpMethod httpMethod;\n\n  private final Operation operation;\n\n  public SwaggerOperation(OpenAPI swagger, String path, HttpMethod httpMethod, Operation operation) {\n    this.swagger = swagger;\n    this.path = path;\n    this.httpMethod = httpMethod;\n    this.operation = operation;\n  }\n\n  public int parameterCount() {\n    int result = 0;\n    if (operation.getRequestBody() != null) {\n      result++;\n    }\n    if (operation.getParameters() != null) {\n      result += operation.getParameters().size();\n    }\n    return result;\n  }\n\n  public OpenAPI getSwagger() {\n    return swagger;\n  }\n\n  public String getPath() {\n    return path;\n  }\n\n  public HttpMethod getHttpMethod() {\n    return httpMethod;\n  }\n\n  public Operation getOperation() {\n    return operation;\n  }\n\n  public String getOperationId() {\n    return operation.getOperationId();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/model/SwaggerOperations.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.PathItem;\nimport io.swagger.v3.oas.models.PathItem.HttpMethod;\nimport io.swagger.v3.oas.models.Paths;\n\npublic class SwaggerOperations {\n  public static SwaggerOperations generate(Class<?> cls) {\n    OpenAPI swagger = SwaggerGenerator.create(cls).generate();\n    return new SwaggerOperations(swagger);\n  }\n\n  private final OpenAPI swagger;\n\n  // key is operationId\n  private final Map<String, SwaggerOperation> operations = new HashMap<>();\n\n  public SwaggerOperations(OpenAPI swagger) {\n    this.swagger = swagger;\n    Paths paths = swagger.getPaths();\n    if (paths == null || paths.isEmpty()) {\n      return;\n    }\n\n    for (Entry<String, PathItem> pathEntry : paths.entrySet()) {\n      for (Entry<HttpMethod, Operation> operationEntry : pathEntry.getValue().readOperationsMap().entrySet()) {\n        if (StringUtils.isEmpty(operationEntry.getValue().getOperationId())) {\n          throw new IllegalStateException(String\n              .format(\"OperationId can not be empty, path=%s, httpMethod=%s.\",\n                  pathEntry.getKey(), operationEntry.getKey()));\n        }\n\n        SwaggerOperation swaggerOperation = new SwaggerOperation(swagger, pathEntry.getKey(), operationEntry.getKey(),\n            operationEntry.getValue());\n        if (operations.putIfAbsent(operationEntry.getValue().getOperationId(), swaggerOperation) != null) {\n          throw new IllegalStateException(\n              \"please make sure operationId is unique, duplicated operationId is \" + operationEntry.getValue()\n                  .getOperationId());\n        }\n      }\n    }\n  }\n\n  public OpenAPI getSwagger() {\n    return swagger;\n  }\n\n  public SwaggerOperation findOperation(String operationId) {\n    return operations.get(operationId);\n  }\n\n  public Map<String, SwaggerOperation> getOperations() {\n    return operations;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/AnnotationUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\n\nimport io.swagger.v3.oas.annotations.ExternalDocumentation;\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.extensions.Extension;\nimport io.swagger.v3.oas.annotations.extensions.ExtensionProperty;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.info.Contact;\nimport io.swagger.v3.oas.annotations.info.Info;\nimport io.swagger.v3.oas.annotations.info.License;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.ExampleObject;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.parameters.RequestBody;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport io.swagger.v3.oas.annotations.servers.Server;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.MediaType;\n\n/**\n * Utility class to convert from OpenAPI annotations to models.\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic final class AnnotationUtils {\n  private AnnotationUtils() {\n\n  }\n\n  public static List<io.swagger.v3.oas.models.servers.Server> serversModel(Server[] servers) {\n    if (servers == null) {\n      return null;\n    }\n    return Arrays.stream(servers).map(AnnotationUtils::convertServer).collect(Collectors.toList());\n  }\n\n  public static io.swagger.v3.oas.models.servers.Server convertServer(Server server) {\n    io.swagger.v3.oas.models.servers.Server item = new io.swagger.v3.oas.models.servers.Server();\n    item.setUrl(server.url());\n    item.setDescription(server.description());\n    return item;\n  }\n\n  public static io.swagger.v3.oas.models.info.Info infoModel(Info infoAnnotation) {\n    if (infoAnnotation == null) {\n      return null;\n    }\n\n    io.swagger.v3.oas.models.info.Info info = new io.swagger.v3.oas.models.info.Info();\n\n    info.setTitle(infoAnnotation.title());\n    info.setVersion(infoAnnotation.version());\n    if (StringUtils.isNotEmpty(infoAnnotation.description())) {\n      info.setDescription(infoAnnotation.description());\n    }\n    if (StringUtils.isNotEmpty(infoAnnotation.termsOfService())) {\n      info.setTermsOfService(infoAnnotation.termsOfService());\n    }\n    info.setContact(contactModel(infoAnnotation.contact()));\n    info.setLicense(licenseModel(infoAnnotation.license()));\n    info.setExtensions(extensionsModel(infoAnnotation.extensions()));\n\n    return info;\n  }\n\n  public static io.swagger.v3.oas.models.info.License licenseModel(License licenseAnnotation) {\n    io.swagger.v3.oas.models.info.License license = new io.swagger.v3.oas.models.info.License();\n\n    if (StringUtils.isNotEmpty(licenseAnnotation.name())) {\n      license.setName(licenseAnnotation.name());\n    }\n    if (StringUtils.isNotEmpty(licenseAnnotation.url())) {\n      license.setUrl(licenseAnnotation.url());\n    }\n\n    if (StringUtils.isEmpty(license.getName()) && StringUtils.isEmpty(license.getUrl())) {\n      return null;\n    }\n\n    return license;\n  }\n\n  public static io.swagger.v3.oas.models.info.Contact contactModel(Contact contactAnnotation) {\n    io.swagger.v3.oas.models.info.Contact contact = new io.swagger.v3.oas.models.info.Contact();\n\n    if (StringUtils.isNotEmpty(contactAnnotation.name())) {\n      contact.setName(contactAnnotation.name());\n    }\n    if (StringUtils.isNotEmpty(contactAnnotation.url())) {\n      contact.setUrl(contactAnnotation.url());\n    }\n    if (StringUtils.isNotEmpty(contactAnnotation.email())) {\n      contact.setEmail(contactAnnotation.email());\n    }\n\n    if (StringUtils.isEmpty(contact.getName()) &&\n        StringUtils.isEmpty(contact.getUrl()) &&\n        StringUtils.isEmpty(contact.getEmail())) {\n      return null;\n    }\n\n    return contact;\n  }\n\n  public static List<io.swagger.v3.oas.models.tags.Tag> tagsModel(Tag[] tagArray) {\n    if (tagArray == null) {\n      return null;\n    }\n\n    List<io.swagger.v3.oas.models.tags.Tag> tags = Arrays.stream(tagArray)\n        .filter(t -> !t.name().isEmpty())\n        .map(AnnotationUtils::tagModel)\n        .collect(Collectors.toList());\n    return tags.isEmpty() ? null : tags;\n  }\n\n  public static List<String> tagsModel(String[] tagArray) {\n    if (tagArray == null) {\n      return null;\n    }\n\n    List<String> tags = Arrays.stream(tagArray)\n        .filter(t -> !t.isEmpty())\n        .collect(Collectors.toList());\n    return tags.isEmpty() ? null : tags;\n  }\n\n  public static io.swagger.v3.oas.models.tags.Tag tagModel(Tag tagAnnotation) {\n    io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag();\n    tag.setName(tagAnnotation.name());\n    tag.setDescription(tagAnnotation.description());\n    tag.setExternalDocs(externalDocumentationModel(tagAnnotation.externalDocs()));\n    tag.setExtensions(extensionsModel(tagAnnotation.extensions()));\n    return tag;\n  }\n\n  public static io.swagger.v3.oas.models.ExternalDocumentation externalDocumentationModel(\n      ExternalDocumentation externalDocs) {\n    io.swagger.v3.oas.models.ExternalDocumentation doc = new io.swagger.v3.oas.models.ExternalDocumentation();\n    doc.setUrl(externalDocs.url());\n    doc.setDescription(externalDocs.description());\n    return doc;\n  }\n\n  public static Map<String, Object> extensionsModel(Extension[] extensions) {\n    Map<String, Object> result = new HashMap<>();\n    Stream.of(extensions).forEach(e -> result.put(e.name(), extensionPropertiesModel(e.properties())));\n    return result;\n  }\n\n  public static Map<String, String> extensionPropertiesModel(ExtensionProperty[] properties) {\n    Map<String, String> result = new HashMap<>();\n    Stream.of(properties).forEach(e -> result.put(e.name(), e.value()));\n    return result;\n  }\n\n  public static String responseCodeModel(ApiResponse apiResponse) {\n    if (StringUtils.isEmpty(apiResponse.responseCode())) {\n      return \"200\";\n    }\n    return apiResponse.responseCode();\n  }\n\n  public static io.swagger.v3.oas.models.responses.ApiResponses apiResponsesModel(OpenAPI openAPI,\n      ApiResponses apiResponses) {\n    io.swagger.v3.oas.models.responses.ApiResponses result =\n        new io.swagger.v3.oas.models.responses.ApiResponses();\n    result.setExtensions(extensionsModel(apiResponses.extensions()));\n    for (ApiResponse apiResponse : apiResponses.value()) {\n      result.addApiResponse(responseCodeModel(apiResponse), apiResponseModel(openAPI, apiResponse));\n    }\n    return result;\n  }\n\n  public static io.swagger.v3.oas.models.responses.ApiResponses apiResponsesModel(OpenAPI openAPI,\n      ApiResponse[] apiResponses) {\n    io.swagger.v3.oas.models.responses.ApiResponses result =\n        new io.swagger.v3.oas.models.responses.ApiResponses();\n    for (ApiResponse apiResponse : apiResponses) {\n      if (result.get(responseCodeModel(apiResponse)) != null) {\n        throw new IllegalStateException(\"not support too many ApiResponse with same status code\");\n      } else {\n        result.addApiResponse(responseCodeModel(apiResponse), apiResponseModel(openAPI, apiResponse));\n      }\n    }\n    return result;\n  }\n\n  public static io.swagger.v3.oas.models.responses.ApiResponse apiResponseModel(OpenAPI openAPI,\n      ApiResponse apiResponse) {\n    io.swagger.v3.oas.models.responses.ApiResponse result =\n        new io.swagger.v3.oas.models.responses.ApiResponse();\n    result.setDescription(apiResponse.description());\n    result.setContent(contentModel(openAPI, apiResponse.content()));\n    result.setHeaders(headersModel(openAPI, apiResponse.headers()));\n    return result;\n  }\n\n  public static Map<String, io.swagger.v3.oas.models.headers.Header> headersModel(OpenAPI openAPI, Header[] headers) {\n    Map<String, io.swagger.v3.oas.models.headers.Header> result = new HashMap<>();\n    for (Header header : headers) {\n      io.swagger.v3.oas.models.headers.Header model =\n          new io.swagger.v3.oas.models.headers.Header();\n      model.setDescription(header.description());\n      model.setSchema(schemaModel(openAPI, header.schema()));\n      result.put(header.name(), model);\n    }\n    return result;\n  }\n\n  public static io.swagger.v3.oas.models.media.Content contentModel(OpenAPI openAPI, Content[] contents) {\n    io.swagger.v3.oas.models.media.Content result = new io.swagger.v3.oas.models.media.Content();\n    for (io.swagger.v3.oas.annotations.media.Content content : contents) {\n      String mediaTypeName = mediaTypeModel(content);\n      MediaType mediaType = result.get(mediaTypeName);\n      boolean isForm = SwaggerConst.FORM_MEDIA_TYPE.equals(mediaTypeName) ||\n          SwaggerConst.FILE_MEDIA_TYPE.equals(mediaTypeName);\n      if (mediaType == null) {\n        mediaType = new MediaType();\n        if (isForm) {\n          io.swagger.v3.oas.models.media.Schema schema = new io.swagger.v3.oas.models.media.Schema();\n          schema.setProperties(new HashMap<>());\n          schema.addProperty(content.schema().name(), schemaModel(openAPI, content.schema(), content.examples()));\n          mediaType.setSchema(schema);\n        } else {\n          mediaType.setSchema(schemaModel(openAPI, content.schema(), content.examples()));\n        }\n        result.addMediaType(mediaTypeName, mediaType);\n      } else {\n        if (isForm) {\n          mediaType.getSchema().addProperty(content.schema().name(),\n              schemaModel(openAPI, content.schema(), content.examples()));\n        } else {\n          throw new IllegalStateException(\"Not allowed to define duplicated content type for \" + mediaTypeName);\n        }\n      }\n    }\n    return result;\n  }\n\n  public static io.swagger.v3.oas.models.parameters.RequestBody requestBodyModel(OpenAPI openAPI,\n      RequestBody requestBody) {\n    if (requestBody == null || isOperationDefaultRequestBody(requestBody)) {\n      return null;\n    }\n    io.swagger.v3.oas.models.parameters.RequestBody result = new io.swagger.v3.oas.models.parameters.RequestBody();\n    result.setContent(AnnotationUtils.contentModel(openAPI, requestBody.content()));\n    return result;\n  }\n\n  private static boolean isOperationDefaultRequestBody(RequestBody requestBody) {\n    return \"\".equals(requestBody.description()) && requestBody.content().length == 0\n        && !requestBody.required() && requestBody.extensions().length == 0;\n  }\n\n  private static String mediaTypeModel(io.swagger.v3.oas.annotations.media.Content content) {\n    if (StringUtils.isEmpty(content.mediaType())) {\n      return SwaggerConst.DEFAULT_MEDIA_TYPE;\n    }\n    return content.mediaType();\n  }\n\n  public static io.swagger.v3.oas.models.media.Schema schemaModel(OpenAPI openAPI, Schema schema) {\n    if (schema.implementation() != Void.class) {\n      io.swagger.v3.oas.models.media.Schema result =\n          SwaggerUtils.resolveTypeSchemas(openAPI, schema.implementation());\n      result.setDescription(schema.description());\n      result.setExample(schema.example());\n      result.setNullable(schema.nullable());\n      return result;\n    }\n\n    io.swagger.v3.oas.models.media.Schema result =\n        new io.swagger.v3.oas.models.media.Schema();\n    result.setType(schema.type());\n    result.setFormat(schema.format());\n    result.setDescription(schema.description());\n    result.setExample(schema.example());\n    result.setNullable(schema.nullable());\n    return result;\n  }\n\n  public static io.swagger.v3.oas.models.media.Schema schemaModel(OpenAPI openAPI, Schema schema,\n      ExampleObject[] exampleObjects) {\n    io.swagger.v3.oas.models.media.Schema result = schemaModel(openAPI, schema);\n    List<Object> examples = new ArrayList<>();\n    for (ExampleObject exampleObject : exampleObjects) {\n      examples.add(exampleObject.name() + \":\" + exampleObject.value());\n    }\n    result.setExamples(examples);\n    return result;\n  }\n\n  public static io.swagger.v3.oas.models.Operation operationModel(OpenAPI openAPI, Operation apiOperationAnnotation) {\n    io.swagger.v3.oas.models.Operation result = new io.swagger.v3.oas.models.Operation();\n    result.setSummary(apiOperationAnnotation.summary());\n    result.setDescription(apiOperationAnnotation.description());\n    result.setExtensions(extensionsModel(apiOperationAnnotation.extensions()));\n    result.setResponses(apiResponsesModel(openAPI, apiOperationAnnotation.responses()));\n    result.setOperationId(apiOperationAnnotation.operationId());\n    result.setTags(tagsModel(apiOperationAnnotation.tags()));\n    result.setRequestBody(requestBodyModel(openAPI, apiOperationAnnotation.requestBody()));\n    return result;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponseMethodProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.util.CollectionUtils;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\n\npublic class ApiResponseMethodProcessor implements MethodAnnotationProcessor<ApiResponse> {\n  @Override\n  public Type getProcessType() {\n    return ApiResponse.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ApiResponse apiResponse) {\n    List<String> produces = new ArrayList<>();\n    String responseCode = apiResponse.responseCode();\n    if (StringUtils.isEmpty(responseCode) || \"default\".equals(responseCode)) {\n      responseCode = SwaggerConst.SUCCESS_KEY;\n    }\n    Class<?> type = null;\n    for (Content content : apiResponse.content()) {\n      if (StringUtils.isNotEmpty(content.mediaType())) {\n        produces.add(content.mediaType());\n      }\n      if (content.schema() != null && content.schema().implementation() != Void.class) {\n        type = content.schema().implementation();\n      }\n    }\n    operationGenerator.getOperationGeneratorContext().updateResponse(responseCode,\n        type == null ? null : SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), type));\n    if (StringUtils.isNotEmpty(apiResponse.description())) {\n      operationGenerator.getOperationGeneratorContext().updateResponseDescription(responseCode,\n          apiResponse.description());\n    }\n    for (Header header : apiResponse.headers()) {\n      if (header.schema() == null || header.schema().implementation() == Void.class) {\n        throw new IllegalArgumentException(\"@ApiResponse header schema implementation must be defined.\");\n      }\n      if (StringUtils.isEmpty(header.name())) {\n        throw new IllegalArgumentException(\"@ApiResponse header name must be defined.\");\n      }\n      operationGenerator.getOperationGeneratorContext().updateResponseHeader(responseCode,\n          header.name(), AnnotationUtils.schemaModel(swaggerGenerator.getOpenAPI(), header.schema()));\n    }\n    if (!CollectionUtils.isEmpty(produces)) {\n      operationGenerator.getOperationGeneratorContext().updateProduces(produces);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesMethodProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.util.CollectionUtils;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\n\n\npublic class ApiResponsesMethodProcessor implements MethodAnnotationProcessor<ApiResponses> {\n  @Override\n  public Type getProcessType() {\n    return ApiResponses.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ApiResponses apiResponses) {\n    List<String> produces = new ArrayList<>();\n    for (ApiResponse apiResponse : apiResponses.value()) {\n      if (StringUtils.isEmpty(apiResponse.responseCode()) || \"default\".equals(apiResponse.responseCode())) {\n        throw new IllegalArgumentException(\"@ApiResponse status code must be defined.\");\n      }\n      Class<?> type = null;\n      for (Content content : apiResponse.content()) {\n        if (StringUtils.isNotEmpty(content.mediaType())) {\n          produces.add(content.mediaType());\n        }\n        if (content.schema() != null && content.schema().implementation() != Void.class) {\n          type = content.schema().implementation();\n        }\n      }\n      operationGenerator.getOperationGeneratorContext().updateResponse(apiResponse.responseCode(),\n          type == null ? null : SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), type));\n      if (StringUtils.isNotEmpty(apiResponse.description())) {\n        operationGenerator.getOperationGeneratorContext().updateResponseDescription(apiResponse.responseCode(),\n            apiResponse.description());\n      }\n      for (Header header : apiResponse.headers()) {\n        if (header.schema() == null || header.schema().implementation() == Void.class) {\n          throw new IllegalArgumentException(\"@ApiResponse header schema implementation must be defined.\");\n        }\n        if (StringUtils.isEmpty(header.name())) {\n          throw new IllegalArgumentException(\"@ApiResponse header name must be defined.\");\n        }\n        operationGenerator.getOperationGeneratorContext().updateResponseHeader(apiResponse.responseCode(),\n            header.name(), AnnotationUtils.schemaModel(swaggerGenerator.getOpenAPI(), header.schema()));\n      }\n    }\n    if (!CollectionUtils.isEmpty(produces)) {\n      operationGenerator.getOperationGeneratorContext().updateProduces(produces);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OpenAPIDefinitionProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class OpenAPIDefinitionProcessor implements ClassAnnotationProcessor<OpenAPIDefinition> {\n  @Override\n  public Type getProcessType() {\n    return OpenAPIDefinition.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OpenAPIDefinition definitionAnnotation) {\n    OpenAPI swagger = swaggerGenerator.getOpenAPI();\n    swagger.setServers(AnnotationUtils.serversModel(definitionAnnotation.servers()));\n    swagger.setTags(AnnotationUtils.tagsModel(definitionAnnotation.tags()));\n    swagger.setInfo(AnnotationUtils.infoModel(definitionAnnotation.info()));\n    swagger.setExternalDocs(AnnotationUtils.externalDocumentationModel(definitionAnnotation.externalDocs()));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.util.CollectionUtils;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\n\npublic class OperationMethodAnnotationProcessor implements MethodAnnotationProcessor<Operation> {\n  public Type getProcessType() {\n    return Operation.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator,\n      OperationGenerator operationGenerator, Operation apiOperationAnnotation) {\n    io.swagger.v3.oas.models.Operation operation = operationGenerator.getOperation();\n\n    if (!StringUtils.isEmpty(apiOperationAnnotation.method())) {\n      operationGenerator.setHttpMethod(apiOperationAnnotation.method());\n    }\n\n    if (apiOperationAnnotation.responses() != null) {\n      // This is a bit different from swagger annotation intention.\n      // Here we assume @Content defines all supported media type and only one implementation class for one status code.\n      List<String> produces = new ArrayList<>();\n      for (ApiResponse apiResponse : apiOperationAnnotation.responses()) {\n        if (StringUtils.isEmpty(apiResponse.responseCode()) || \"default\".equals(apiResponse.responseCode())) {\n          throw new IllegalArgumentException(\"@ApiResponse status code must be defined.\");\n        }\n        Class<?> type = null;\n        for (Content content : apiResponse.content()) {\n          if (StringUtils.isNotEmpty(content.mediaType())) {\n            produces.add(content.mediaType());\n          }\n          if (content.schema() != null && content.schema().implementation() != Void.class) {\n            type = content.schema().implementation();\n          }\n        }\n        operationGenerator.getOperationGeneratorContext().updateResponse(apiResponse.responseCode(),\n            type == null ? null : SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), type));\n        if (StringUtils.isNotEmpty(apiResponse.description())) {\n          operationGenerator.getOperationGeneratorContext().updateResponseDescription(apiResponse.responseCode(),\n              apiResponse.description());\n        }\n        for (Header header : apiResponse.headers()) {\n          if (header.schema() == null || header.schema().implementation() == Void.class) {\n            throw new IllegalArgumentException(\"@ApiResponse header schema implementation must be defined.\");\n          }\n          if (StringUtils.isEmpty(header.name())) {\n            throw new IllegalArgumentException(\"@ApiResponse header name must be defined.\");\n          }\n          operationGenerator.getOperationGeneratorContext().updateResponseHeader(apiResponse.responseCode(),\n              header.name(), AnnotationUtils.schemaModel(swaggerGenerator.getOpenAPI(), header.schema()));\n        }\n      }\n      if (!CollectionUtils.isEmpty(produces)) {\n        operationGenerator.getOperationGeneratorContext().updateProduces(produces);\n      }\n    }\n\n    io.swagger.v3.oas.models.Operation specificOperation =\n        AnnotationUtils.operationModel(swaggerGenerator.getOpenAPI(), apiOperationAnnotation);\n    if (!StringUtils.isEmpty(specificOperation.getSummary())) {\n      operation.setSummary(specificOperation.getSummary());\n    }\n\n    if (!StringUtils.isEmpty(specificOperation.getDescription())) {\n      operation.setDescription(specificOperation.getDescription());\n    }\n\n    if (!StringUtils.isEmpty(specificOperation.getOperationId())) {\n      operation.setOperationId(specificOperation.getOperationId());\n    }\n\n    if (!CollectionUtils.isEmpty(specificOperation.getExtensions())) {\n      operation.setExtensions(specificOperation.getExtensions());\n    }\n\n    if (!CollectionUtils.isEmpty(specificOperation.getTags())) {\n      operation.setTags(specificOperation.getTags());\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/RequestBodyMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.oas.annotations.parameters.RequestBody;\n\npublic class RequestBodyMethodAnnotationProcessor implements MethodAnnotationProcessor<RequestBody> {\n  @Override\n  public Type getProcessType() {\n    return RequestBody.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      RequestBody annotation) {\n    io.swagger.v3.oas.models.parameters.RequestBody requestBody =\n        AnnotationUtils.requestBodyModel(swaggerGenerator.getOpenAPI(), annotation);\n    operationGenerator.getOperation().setRequestBody(requestBody);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/package-info.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * swagger竟然没提供从annotation生成swagger对象的功能，只好自己做了\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/HttpServletRequestContextRegister.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.HttpServletRequest;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerContextRegister;\n\npublic class HttpServletRequestContextRegister implements SwaggerContextRegister {\n  @Override\n  public Type getContextType() {\n    return HttpServletRequest.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/ParameterParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerParameterAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.enums.Explode;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\n\npublic class ParameterParameterAnnotationProcessor\n    extends SwaggerParameterAnnotationProcessor<io.swagger.v3.oas.annotations.Parameter> {\n  @Override\n  public Class<?> getProcessType() {\n    return io.swagger.v3.oas.annotations.Parameter.class;\n  }\n\n  @Override\n  public String getParameterName(Parameter annotation) {\n    if (StringUtils.isNotEmpty(annotation.name())) {\n      return annotation.name();\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, io.swagger.v3.oas.annotations.Parameter annotation) {\n    if (annotation.schema() != null\n        && annotation.schema().implementation() != null\n        && annotation.schema().implementation() != Void.class) {\n      parameterGenerator.getParameterGeneratorContext()\n          .setParameterType(TypeFactory.defaultInstance().constructType(annotation.schema().implementation()));\n    }\n\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n\n    if (annotation.in() != null && annotation.in() != ParameterIn.DEFAULT) {\n      parameterGenerator.setHttpParameterType(HttpParameterType.from(annotation.in()));\n    }\n\n    if (Explode.TRUE.equals(annotation.explode())) {\n      parameterGenerator.getParameterGeneratorContext().setExplode(true);\n    }\n    if (Explode.FALSE.equals(annotation.explode())) {\n      parameterGenerator.getParameterGeneratorContext().setExplode(false);\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/PartArrayParameterTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.ArraySchema;\nimport io.swagger.v3.oas.models.media.FileSchema;\nimport jakarta.servlet.http.Part;\n\npublic class PartArrayParameterTypeProcessor extends PartParameterTypeProcessor {\n  @Override\n  public JavaType getProcessType() {\n    return TypeFactory.defaultInstance().constructType(Part[].class);\n  }\n\n  @Override\n  protected void formParameterSchema(ParameterGenerator parameterGenerator) {\n    parameterGenerator.getParameterGeneratorContext().setSchema(new ArraySchema().items(new FileSchema()));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/PartListParameterTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport jakarta.servlet.http.Part;\n\npublic class PartListParameterTypeProcessor extends PartArrayParameterTypeProcessor {\n  @Override\n  public JavaType getProcessType() {\n    return TypeFactory.defaultInstance().constructType(ParameterizedTypeUtil.make(List.class, Part.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/PartParameterTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterTypeProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.media.FileSchema;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class PartParameterTypeProcessor implements ParameterTypeProcessor {\n  @Override\n  public JavaType getProcessType() {\n    return TypeFactory.defaultInstance().constructType(Part.class);\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator) {\n    if (!parameterGenerator.getParameterGeneratorContext().getSupportedConsumes()\n        .contains(MediaType.MULTIPART_FORM_DATA)) {\n      throw new IllegalArgumentException(\"Part type must declare consumes \" + MediaType.MULTIPART_FORM_DATA);\n    }\n    if (parameterGenerator.getHttpParameterType() != HttpParameterType.FORM) {\n      throw new IllegalArgumentException(\n          getProcessType().getRawClass().getSimpleName() + \" type must declare as form parameter.\");\n    }\n    if (StringUtils.isEmpty(parameterGenerator.getParameterGeneratorContext().getParameterName())) {\n      throw new IllegalArgumentException(\n          \"Name is required for parameter \" + getProcessType().getRawClass().getSimpleName());\n    }\n    parameterGenerator.getParameterGeneratorContext().updateConsumes(List.of(MediaType.MULTIPART_FORM_DATA));\n\n    formParameterSchema(parameterGenerator);\n  }\n\n  protected void formParameterSchema(ParameterGenerator parameterGenerator) {\n    parameterGenerator.getParameterGeneratorContext().setSchema(new FileSchema());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/RawJsonRequestBodyProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport java.util.Arrays;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerParameterAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport jakarta.ws.rs.core.MediaType;\n\npublic class RawJsonRequestBodyProcessor extends\n    SwaggerParameterAnnotationProcessor<RawJsonRequestBody> {\n  @Override\n  public Class<?> getProcessType() {\n    return RawJsonRequestBody.class;\n  }\n\n  @Override\n  public String getParameterName(RawJsonRequestBody annotation) {\n    if (StringUtils.isNotEmpty(annotation.value())) {\n      return annotation.value();\n    } else if (StringUtils.isNotEmpty(annotation.name())) {\n      return annotation.name();\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, RawJsonRequestBody annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.BODY);\n\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n    parameterGenerator.getParameterGeneratorContext().setRawJson(true);\n    parameterGenerator.getParameterGeneratorContext().updateConsumes(Arrays.asList(MediaType.APPLICATION_JSON,\n        MediaType.TEXT_PLAIN));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/RequestBodyParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerParameterAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport io.swagger.v3.oas.annotations.parameters.RequestBody;\n\npublic class RequestBodyParameterAnnotationProcessor extends\n    SwaggerParameterAnnotationProcessor<io.swagger.v3.oas.annotations.parameters.RequestBody> {\n  @Override\n  public Class<?> getProcessType() {\n    return io.swagger.v3.oas.annotations.parameters.RequestBody.class;\n  }\n\n  @Override\n  public String getParameterName(RequestBody requestBody) {\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, io.swagger.v3.oas.annotations.parameters.RequestBody annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.BODY);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/ServerWebSocketContextRegister.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.parameter;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerContextRegister;\n\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class ServerWebSocketContextRegister implements SwaggerContextRegister {\n  @Override\n  public Type getContextType() {\n    return ServerWebSocket.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/CompletableFutureProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.response;\n\nimport java.util.concurrent.CompletableFuture;\n\npublic class CompletableFutureProcessor extends DefaultResponseTypeProcessor {\n  public CompletableFutureProcessor() {\n    extractActualType = true;\n  }\n\n  @Override\n  public Class<?> getProcessType() {\n    return CompletableFuture.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/DefaultResponseTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.response;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findResponseTypeProcessor;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport io.swagger.v3.core.util.ReflectionUtils;\nimport io.swagger.v3.oas.models.media.Schema;\nimport jakarta.servlet.http.Part;\n\npublic class DefaultResponseTypeProcessor implements ResponseTypeProcessor {\n  protected boolean extractActualType;\n\n  @Override\n  public Type getProcessType() {\n    // not care for this.\n    return null;\n  }\n\n  @Override\n  public Type extractResponseType(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      Type genericResponseType) {\n    if (extractActualType) {\n      genericResponseType = ((ParameterizedType) genericResponseType).getActualTypeArguments()[0];\n    }\n\n    return doExtractResponseType(genericResponseType);\n  }\n\n  private Type doExtractResponseType(Type genericResponseType) {\n    if (!(genericResponseType instanceof ParameterizedType)) {\n      return genericResponseType;\n    }\n\n    // eg:\n    //   genericResponseType is CompletableFuture<ResponseEntity<String>>\n    //   responseType is ResponseEntity<String>\n    //   responseRawType is ResponseEntity\n    Type responseRawType = genericResponseType;\n    if (genericResponseType instanceof ParameterizedType) {\n      responseRawType = ((ParameterizedType) genericResponseType).getRawType();\n    }\n\n    ResponseTypeProcessor processor = findResponseTypeProcessor(responseRawType);\n    if (responseRawType.equals(processor.getProcessType())) {\n      return processor.extractResponseType(genericResponseType);\n    }\n\n    return genericResponseType;\n  }\n\n  @Override\n  public Schema<?> process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      Type genericResponseType) {\n    Type responseType = extractResponseType(swaggerGenerator, operationGenerator, genericResponseType);\n    if (responseType == null || ReflectionUtils.isVoid(responseType)) {\n      return null;\n    }\n\n    if (responseType instanceof Class && Part.class.isAssignableFrom((Class<?>) responseType)) {\n      responseType = Part.class;\n    }\n\n    return SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), responseType);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/OptionalProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.response;\n\nimport java.lang.reflect.Type;\nimport java.util.Optional;\n\npublic class OptionalProcessor extends DefaultResponseTypeProcessor {\n  public OptionalProcessor() {\n    extractActualType = true;\n  }\n\n  @Override\n  public Type getProcessType() {\n    return Optional.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/PublisherProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.processor.response;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.reactivestreams.Publisher;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class PublisherProcessor extends DefaultResponseTypeProcessor {\n  public PublisherProcessor() {\n    extractActualType = true;\n  }\n\n  @Override\n  public Type getProcessType() {\n    return Publisher.class;\n  }\n\n  @Override\n  public Schema<?> process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      Type genericResponseType) {\n    operationGenerator.getOperationGeneratorContext()\n        .updateProduces(List.of(MediaType.SERVER_SENT_EVENTS));\n    return super.process(swaggerGenerator, operationGenerator, genericResponseType);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/unittest/UnitTestSwaggerUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.unittest;\n\nimport java.io.IOException;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.ObjectWriter;\nimport com.fasterxml.jackson.dataformat.yaml.YAMLFactory;\n\nimport io.swagger.v3.core.util.Yaml;\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic final class UnitTestSwaggerUtils {\n  private static final ObjectWriter writer = Yaml.pretty();\n\n  private UnitTestSwaggerUtils() {\n  }\n\n  public static String loadExpect(String resPath) {\n    URL url = Thread.currentThread().getContextClassLoader().getResource(resPath);\n    if (url == null) {\n      return \"can not found res \" + resPath;\n    }\n\n    try {\n      return IOUtils.toString(url, StandardCharsets.UTF_8);\n    } catch (IOException e) {\n      return e.getMessage();\n    }\n  }\n\n  public static String pretty(OpenAPI swagger) {\n    try {\n      return writer.writeValueAsString(swagger);\n    } catch (JsonProcessingException e) {\n      throw new Error(e);\n    }\n  }\n\n  public static OpenAPI parse(String content) {\n    try {\n      return Yaml.mapper().readValue(content, OpenAPI.class);\n    } catch (Exception e) {\n      return new OpenAPI();\n      //            throw new Error(e);\n    }\n  }\n\n  public static SwaggerGenerator testSwagger(String resPath, Class<?> cls, String... methods) {\n    SwaggerGenerator generator = SwaggerGenerator.create(cls);\n    generator.replaceMethodWhiteList(methods);\n\n    OpenAPI swagger = generator.generate();\n    String schema = pretty(swagger).trim();\n\n    String expectSchema = loadExpect(resPath).replace(\"\\r\\n\", \"\\n\").trim();\n    int offset = expectSchema.indexOf(\"---\\nopenapi: 3.0.1\");\n    if (offset > 0) {\n      expectSchema = expectSchema.substring(offset + 4);\n    }\n\n    try {\n      ObjectMapper yaml = new ObjectMapper(new YAMLFactory());\n      JsonNode expected = yaml.readTree(expectSchema);\n      JsonNode actual   = yaml.readTree(schema);\n\n      if (!actual.equals(expected)) {\n        ObjectMapper json = new ObjectMapper();\n        String expectedPretty = json.writerWithDefaultPrettyPrinter().writeValueAsString(expected);\n        String actualPretty   = json.writerWithDefaultPrettyPrinter().writeValueAsString(actual);\n        Assertions.fail(\"OpenAPI mismatch.\\n=== EXPECTED ===\\n\" + expectedPretty + \"\\n=== ACTUAL ===\\n\" + actualPretty);\n      }\n    } catch (Exception e) {\n      Assertions.fail(\"Failed to parse/compare OpenAPI YAML: \" + e.getMessage(), e);\n    }\n\n    return generator;\n  }\n\n  public static Throwable getException(Class<?> cls, String... methods) {\n    try {\n      SwaggerGenerator generator = SwaggerGenerator.create(cls);\n      generator.replaceMethodWhiteList(methods);\n\n      generator.generate();\n    } catch (Throwable e) {\n      return e;\n    }\n\n    // 不允许成功\n    Assertions.assertEquals(\"not allowed run to here\", \"run to here\");\n    return null;\n  }\n\n  public static void testException(String expectMsgLevel1, String expectMsgLevel2, String expectMsgLevel3, Class<?> cls,\n      String... methods) {\n    Throwable exception = getException(cls, methods);\n    Assertions.assertEquals(expectMsgLevel1, exception.getMessage());\n    Assertions.assertEquals(expectMsgLevel2, exception.getCause().getMessage());\n    Assertions.assertEquals(expectMsgLevel3, exception.getCause().getCause().getMessage());\n  }\n\n  public static void testException(String expectMsgLevel1, String expectMsgLevel2, Class<?> cls, String... methods) {\n    Throwable exception = getException(cls, methods);\n    Assertions.assertEquals(expectMsgLevel1, exception.getMessage());\n    Assertions.assertEquals(expectMsgLevel2, exception.getCause().getMessage());\n  }\n\n  public static void testException(String expectMsg, Class<?> cls, String... methods) {\n    Throwable exception = getException(cls, methods);\n    Assertions.assertEquals(expectMsg, exception.getMessage());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/unittest/package-info.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * 专用于ut场景\n */\npackage org.apache.servicecomb.swagger.generator.core.unittest;\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/MethodUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\n\npublic class MethodUtils {\n  /**\n   * Get the methods of <code>cls</code> which are valid for generating Swagger schema.\n   * @param cls The REST interface class, or so called \"controller\" class, to be analysed.\n   * @return the valid methods to be used to generate Swagger schema, sorted by their Swagger operation name.\n   */\n  public static List<Method> findSwaggerMethods(Class<?> cls) {\n    Method[] methods = cls.getMethods();\n    List<Method> result = new ArrayList<>(methods.length);\n\n    for (Method m : methods) {\n      if (!isSkipMethod(cls, m)) {\n        result.add(m);\n      }\n    }\n\n    // order of cls.getMethods() is undefined and not stable\n    // so we must sort them first to make generation is stable\n    result.sort(Comparator.comparing(MethodUtils::findSwaggerMethodName));\n    return result;\n  }\n\n  public static Map<String, Method> findSwaggerMethodsMapOfOperationId(Class<?> cls) {\n    List<Method> methods = findSwaggerMethods(cls);\n    Map<String, Method> result = new HashMap<>();\n    methods.forEach((item) -> result.put(findSwaggerMethodName(item), item));\n    return result;\n  }\n\n  /**\n   * Pick out those methods not proper to be added into the Swagger schema.\n   *\n   * @param cls the owner class of the <code>method</code>\n   * @param method the method to be validate\n   * @return true if this method should be abandoned;\n   * false if this method should be added in to Swagger schema\n   */\n  public static boolean isSkipMethod(Class<?> cls, Method method) {\n    if (method.isDefault()) {\n      return true;\n    }\n    if (method.getDeclaringClass() == Object.class) {\n      return true;\n    }\n    if (method.getDeclaringClass().isInterface()\n        && !cls.isInterface()) {\n      // inherited template methods\n      return true;\n    }\n    // skip static method\n    int modifiers = method.getModifiers();\n    if (Modifier.isStatic(modifiers)) {\n      return true;\n    }\n    // skip bridge method\n    if (method.isBridge()) {\n      return true;\n    }\n\n    Operation apiOperation = method.getAnnotation(Operation.class);\n    return apiOperation != null && apiOperation.hidden();\n  }\n\n  /**\n   * Get the operationId in schema of this method,\n   * no matter whether it should be hidden.\n   * @return If the operation name is specified via {@link Operation}, use that one.\n   * Otherwise the method name is returned.\n   */\n  public static String findSwaggerMethodName(Method method) {\n    Operation apiOperationAnnotation = method.getAnnotation(Operation.class);\n    if (apiOperationAnnotation == null || StringUtils.isEmpty(apiOperationAnnotation.operationId())) {\n      return method.getName();\n    }\n\n    return apiOperationAnnotation.operationId();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoOperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.pojo;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.isContextParameter;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.core.AbstractOperationGenerator;\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;\n\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.google.common.reflect.TypeToken;\n\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.media.ObjectSchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport jakarta.ws.rs.HttpMethod;\n\npublic class PojoOperationGenerator extends AbstractOperationGenerator {\n  public PojoOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, Method method) {\n    super(swaggerGenerator, method);\n  }\n\n  @Override\n  protected void initParameterGenerators() {\n    List<ParameterGenerator> bodyParameters = new ArrayList<>();\n    for (java.lang.reflect.Parameter methodParameter : method.getParameters()) {\n      Type type = TypeToken.of(clazz)\n          .resolveType(methodParameter.getParameterizedType())\n          .getType();\n      ParameterGenerator parameterGenerator = new ParameterGenerator(\n          this, Collections.emptyMap(), methodParameter,\n          TypeFactory.defaultInstance().constructType(type));\n      validateParameter(parameterGenerator.getGenericType());\n      if (isContextParameter(parameterGenerator.getGenericType())) {\n        continue;\n      }\n\n      bodyParameters.add(parameterGenerator);\n    }\n\n    tryWrapParametersToBody(bodyParameters);\n  }\n\n  private void tryWrapParametersToBody(List<ParameterGenerator> bodyParameters) {\n    if (bodyParameters.size() == 0) {\n      return;\n    }\n\n    if (bodyParameters.size() == 1 && SwaggerUtils.isBean(bodyParameters.get(0).getGenericType())) {\n      ParameterGenerator parameterGenerator = bodyParameters.get(0);\n      parameterGenerator.setHttpParameterType(HttpParameterType.BODY);\n      parameterGenerators.add(parameterGenerator);\n      return;\n    }\n\n    wrapParametersToBody(bodyParameters);\n  }\n\n  private void wrapParametersToBody(List<ParameterGenerator> bodyFields) {\n    // process annotations like parameter name\n    for (ParameterGenerator parameterGenerator : bodyFields) {\n      scanMethodParameter(parameterGenerator);\n    }\n\n    String simpleRef = MethodUtils.findSwaggerMethodName(method) + \"Body\";\n\n    Schema<?> bodyModel = new ObjectSchema();\n    for (ParameterGenerator parameterGenerator : bodyFields) {\n      bodyModel.addProperty(parameterGenerator.getParameterGeneratorContext().getParameterName(),\n          parameterGenerator.getParameterGeneratorContext().getSchema());\n    }\n\n    swagger.getComponents().addSchemas(simpleRef, bodyModel);\n    Schema<?> bodyModelNew = new Schema<>();\n    bodyModelNew.set$ref(Components.COMPONENTS_SCHEMAS_REF + simpleRef);\n    ParameterGenerator newParameterGenerator = new ParameterGenerator(this, simpleRef, bodyModelNew);\n    newParameterGenerator.setHttpParameterType(HttpParameterType.BODY);\n    parameterGenerators.add(newParameterGenerator);\n  }\n\n  @Override\n  public void correctOperation() {\n    correctPath();\n    correctHttpMethod();\n    super.correctOperation();\n  }\n\n  protected void correctPath() {\n    if (StringUtils.isEmpty(path)) {\n      path = \"/\" + getOperationId();\n    }\n  }\n\n  protected void correctHttpMethod() {\n    if (StringUtils.isEmpty(httpMethod)) {\n      setHttpMethod(HttpMethod.POST);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoSwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.pojo;\n\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\n\nimport jakarta.ws.rs.core.MediaType;\n\npublic class PojoSwaggerGenerator extends AbstractSwaggerGenerator {\n  protected static final List<String> SUPPORTED_CONTENT_TYPE\n      = Arrays.asList(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN);\n\n  public PojoSwaggerGenerator(Class<?> cls) {\n    super(cls);\n    swaggerGeneratorContext.updateConsumes(SUPPORTED_CONTENT_TYPE);\n    swaggerGeneratorContext.updateProduces(SUPPORTED_CONTENT_TYPE);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public <T extends OperationGenerator> T createOperationGenerator(Method method) {\n    return (T) new PojoOperationGenerator(this, method);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoSwaggerGeneratorFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.pojo;\n\nimport java.lang.annotation.Annotation;\n\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGeneratorFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class PojoSwaggerGeneratorFactory implements SwaggerGeneratorFactory {\n  private static final Logger LOGGER = LoggerFactory.getLogger(PojoSwaggerGeneratorFactory.class);\n\n  @Override\n  public int getOrder() {\n    return Integer.MAX_VALUE;\n  }\n\n  @Override\n  public boolean canProcess(Class<?> cls) {\n    for (Annotation annotation : cls.getAnnotations()) {\n      // we check the annotations by class name to avoid importing extra dependencies in this module\n      if (annotation instanceof Path\n          || \"org.springframework.web.bind.annotation.RequestMapping\"\n          .equals(annotation.annotationType().getCanonicalName())) {\n        LOGGER.info(\n            \"There is @RequestMapping or @Path annotation on the REST interface class, but POJO swagger generator is chosen. \"\n                + \"If this is unexpected, maybe you should check your dependency jar files.\");\n      }\n    }\n    return true;\n  }\n\n  @Override\n  public SwaggerGenerator create(Class<?> cls) {\n    return new PojoSwaggerGenerator(cls);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/rest/RestOperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.rest;\n\nimport java.lang.reflect.Method;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.core.AbstractOperationGenerator;\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\n\npublic abstract class RestOperationGenerator extends AbstractOperationGenerator {\n  public RestOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, Method method) {\n    super(swaggerGenerator, method);\n  }\n\n  @Override\n  public void correctOperation() {\n    checkPath();\n    correctPath();\n    super.correctOperation();\n  }\n\n  protected void checkPath() {\n    if (StringUtils.isEmpty(path)\n        && StringUtils.isEmpty(SwaggerUtils.getBasePath(swagger))) {\n      throw new IllegalStateException(\"Path must not both be empty in class and method\");\n    }\n  }\n\n  protected void correctPath() {\n    if (StringUtils.isEmpty(path)) {\n      path = \"/\";\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/rest/RestSwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.rest;\n\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\n\npublic abstract class RestSwaggerGenerator extends AbstractSwaggerGenerator {\n  public RestSwaggerGenerator(Class<?> cls) {\n    super(cls);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/io.swagger.v3.core.converter.ModelConverter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.extend.ModelResolverExt\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.core.processor.annotation.OpenAPIDefinitionProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.core.processor.annotation.OperationMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.core.processor.annotation.ApiResponsesMethodProcessor\norg.apache.servicecomb.swagger.generator.core.processor.annotation.ApiResponseMethodProcessor\norg.apache.servicecomb.swagger.generator.core.processor.annotation.RequestBodyMethodAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.core.processor.parameter.RequestBodyParameterAnnotationProcessor\norg.apache.servicecomb.swagger.generator.core.processor.parameter.ParameterParameterAnnotationProcessor\norg.apache.servicecomb.swagger.generator.core.processor.parameter.RawJsonRequestBodyProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ParameterTypeProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.core.processor.parameter.PartParameterTypeProcessor\norg.apache.servicecomb.swagger.generator.core.processor.parameter.PartArrayParameterTypeProcessor\norg.apache.servicecomb.swagger.generator.core.processor.parameter.PartListParameterTypeProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ResponseTypeProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.core.processor.response.CompletableFutureProcessor\norg.apache.servicecomb.swagger.generator.core.processor.response.OptionalProcessor\norg.apache.servicecomb.swagger.generator.core.processor.response.PublisherProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerContextRegister",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.core.processor.parameter.HttpServletRequestContextRegister\norg.apache.servicecomb.swagger.generator.core.processor.parameter.ServerWebSocketContextRegister\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerGenerator",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGenerator\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerGeneratorFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGeneratorFactory\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/TestSwaggerUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger;\n\nimport java.io.IOException;\nimport java.net.URL;\nimport java.nio.charset.StandardCharsets;\n\nimport org.apache.commons.io.IOUtils;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.MockedStatic;\nimport org.mockito.Mockito;\n\nimport io.swagger.v3.core.util.Yaml;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.PathItem;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\n\npublic class TestSwaggerUtils {\n\n  @Test\n  public void swaggerToStringNormal() {\n    OpenAPI swagger = new OpenAPI();\n    String content = SwaggerUtils.swaggerToString(swagger);\n\n    OpenAPI newSwagger = SwaggerUtils.parseSwagger(content);\n    Assertions.assertEquals(swagger, newSwagger);\n  }\n\n\n  @Test\n  public void parseSwaggerUrlNormal() throws IOException {\n    String content = \"openapi: 3.0.1\";\n    URL url = Mockito.mock(URL.class);\n    try (MockedStatic<IOUtils> ioUtilsMockedStatic = Mockito.mockStatic(IOUtils.class)) {\n      ioUtilsMockedStatic.when(() -> IOUtils.toString(url, StandardCharsets.UTF_8)).thenReturn(content);\n      OpenAPI swagger = Yaml.mapper().readValue(content, OpenAPI.class);\n      OpenAPI result = SwaggerUtils.parseAndValidateSwagger(url);\n      Assertions.assertEquals(swagger, result);\n      Assertions.assertEquals(\"3.0.1\", result.getOpenapi());\n    }\n  }\n\n  @Test\n  public void parseSwaggerUrlException() throws IOException {\n    URL url = Mockito.mock(URL.class);\n    try (MockedStatic<IOUtils> ioUtilsMockedStatic = Mockito.mockStatic(IOUtils.class)) {\n      ioUtilsMockedStatic.when(() -> IOUtils.toString(url, StandardCharsets.UTF_8))\n          .thenThrow(new RuntimeExceptionWithoutStackTrace(\"failed\"));\n      ServiceCombException exception = Assertions.assertThrows(ServiceCombException.class,\n          () -> SwaggerUtils.parseAndValidateSwagger(url));\n      Assertions.assertTrue(exception.getMessage().contains(\"Parse swagger from url failed, \"));\n    }\n  }\n\n  @Test\n  public void parseSwaggerContentException() {\n    ServiceCombException exception = Assertions.assertThrows(ServiceCombException.class,\n        () -> SwaggerUtils.parseSwagger(\"\"));\n    Assertions.assertEquals(\"Parse swagger from content failed, \", exception.getMessage());\n  }\n\n  @Test\n  public void correctResponsesOperationFixEmptyDescription() {\n    ApiResponse response = new ApiResponse();\n\n    Operation operation = new Operation();\n    operation.setResponses(new ApiResponses());\n    operation.getResponses().addApiResponse(\"200\", response);\n\n    SwaggerUtils.correctResponses(operation);\n    Assertions.assertEquals(\"response of 200\", response.getDescription());\n  }\n\n  @Test\n  public void correctResponsesOperationNotChangeExistDescription() {\n    ApiResponse response = new ApiResponse();\n    response.setDescription(\"description\");\n\n    Operation operation = new Operation();\n    operation.setResponses(new ApiResponses());\n    operation.getResponses().addApiResponse(\"200\", response);\n\n    SwaggerUtils.correctResponses(operation);\n    Assertions.assertEquals(\"description\", response.getDescription());\n  }\n\n  @Test\n  public void correctResponsesHavePaths() {\n    ApiResponse response = new ApiResponse();\n\n    Operation operation = new Operation();\n    operation.setResponses(new ApiResponses());\n    operation.getResponses().addApiResponse(\"200\", response);\n\n    PathItem path = new PathItem();\n    path.get(operation);\n\n    OpenAPI swagger = new OpenAPI();\n    swagger.path(\"/base\", path);\n\n    SwaggerUtils.correctResponses(swagger);\n\n    Assertions.assertEquals(\"response of 200\", response.getDescription());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospectorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.introspector;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class JsonPropertyIntrospectorTest {\n\n  @Test\n  public void findEnumValue() {\n    JsonPropertyIntrospector introspector = new JsonPropertyIntrospector();\n\n    Assertions.assertEquals(\"AB\", introspector.findEnumValue(TestEnum.AB));\n    Assertions.assertEquals(\"C-D\", introspector.findEnumValue(TestEnum.C_D));\n    Assertions.assertEquals(\"E.F\", introspector.findEnumValue(TestEnum.E_F));\n    Assertions.assertEquals(\"HI\", introspector.findEnumValue(TestEnum.HI));\n  }\n\n  public enum TestEnum {\n    AB,\n    @JsonProperty(value = \"C-D\")\n    C_D,\n    @JsonProperty(value = \"E.F\")\n    E_F,\n    @JsonProperty\n    HI\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/module/EnumModuleExtTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.module;\n\nimport static org.hamcrest.Matchers.contains;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.databind.ObjectMapper;\n\nimport io.swagger.v3.core.util.Json;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.Schema;\n\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic class EnumModuleExtTest {\n  public enum TestEnum {\n    AB,\n    @JsonProperty(value = \"C-D\")\n    C_D,\n    @JsonProperty(value = \"E.F\")\n    E_F,\n    @JsonProperty\n    HI\n  }\n\n  @Test\n  public void testEnumModule() throws JsonProcessingException {\n    ObjectMapper mapper = Json.mapper();\n    String serializeValue = mapper.writeValueAsString(TestEnum.AB);\n    Assertions.assertEquals(\"\\\"AB\\\"\", serializeValue);\n    serializeValue = mapper.writeValueAsString(TestEnum.C_D);\n    Assertions.assertEquals(\"\\\"C-D\\\"\", serializeValue);\n    serializeValue = mapper.writeValueAsString(TestEnum.E_F);\n    Assertions.assertEquals(\"\\\"E.F\\\"\", serializeValue);\n    serializeValue = mapper.writeValueAsString(TestEnum.HI);\n    Assertions.assertEquals(\"\\\"\\\"\", serializeValue);\n  }\n\n  @Test\n  public void testEnumModuleModel() {\n    OpenAPI openAPI = new OpenAPI();\n    Schema schema = SwaggerUtils.resolveTypeSchemas(openAPI, TestEnum.class);\n    Assertions.assertEquals(schema.getType(), \"string\");\n    MatcherAssert.assertThat((List<String>) schema.getEnum(), contains(\"AB\", \"C-D\", \"E.F\", \"\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/property/creator/TestPartPropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.extend.property.creator;\n\nimport jakarta.servlet.http.Part;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.media.FileSchema;\n\n\npublic class TestPartPropertyCreator {\n  PartPropertyCreator creator = new PartPropertyCreator();\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void classes() {\n    MatcherAssert.assertThat(creator.classes(), Matchers.arrayContaining(Part.class));\n  }\n\n  @Test\n  public void createProperty() {\n    MatcherAssert.assertThat(creator.createProperty(), Matchers.instanceOf(FileSchema.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport static org.hamcrest.core.Is.is;\nimport static org.hamcrest.core.IsNull.nullValue;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.extensions.Extension;\nimport io.swagger.v3.oas.annotations.extensions.ExtensionProperty;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.PathItem;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport jakarta.ws.rs.core.MediaType;\n\n@SuppressWarnings({\"rawtypes\", \"unused\"})\npublic class TestApiOperation {\n  static SwaggerOperations swaggerOperations = SwaggerOperations.generate(ApiOperationAnnotation.class);\n\n  @AfterAll\n  public static void teardown() {\n    swaggerOperations = null;\n  }\n\n  interface ApiOperationAnnotation {\n    @Operation(\n        summary = \"summary\",\n        description = \"notes\",\n        tags = {\"tag1\", \"tag2\"},\n        method = \"GET\",\n        operationId = \"test\",\n        responses = @ApiResponse(responseCode = \"202\",\n            content = @Content(mediaType = MediaType.APPLICATION_JSON,\n                schema = @Schema(implementation = String.class)),\n            headers = @Header(name = \"h1\", schema = @Schema(implementation = Integer.class))),\n        extensions = {@Extension(\n            name = \"x-tagA\",\n            properties = {@ExtensionProperty(name = \"x-tagAExt\", value = \"value of tagAExt\")})})\n    void testBase();\n\n    @Operation(summary = \"aaa\")\n    @ApiResponse(responseCode = \"202\", content = @Content(schema = @Schema(implementation = String.class)))\n    int testPrimitive();\n\n    @Operation(summary = \"aaa\", hidden = true)\n    int testHidden();\n  }\n\n\n  @Test\n  public void testApiOperation() {\n    OpenAPI swagger = swaggerOperations.getSwagger();\n    testBase(swagger.getPaths().get(\"/test\"));\n    testPrimitive(swagger.getPaths().get(\"/testPrimitive\"));\n    MatcherAssert.assertThat(swagger.getPaths().get(\"/testHidden\"), is(nullValue()));\n  }\n\n  private void testPrimitive(PathItem path) {\n    io.swagger.v3.oas.models.Operation operation = path.getPost();\n\n    Assertions.assertEquals(2, operation.getResponses().size());\n\n    io.swagger.v3.oas.models.media.Schema result200 =\n        operation.getResponses().get(\"200\").getContent().get(MediaType.APPLICATION_JSON).getSchema();\n    Assertions.assertEquals(\"integer\", result200.getType());\n    Assertions.assertEquals(\"int32\", result200.getFormat());\n\n    io.swagger.v3.oas.models.media.Schema result202 =\n        operation.getResponses().get(\"202\").getContent().get(MediaType.APPLICATION_JSON).getSchema();\n    Assertions.assertEquals(\"string\", result202.getType());\n  }\n\n  private void testBase(PathItem path) {\n    Assertions.assertEquals(1, path.readOperations().size());\n\n    io.swagger.v3.oas.models.Operation operation = path.getGet();\n\n    Assertions.assertEquals(\"summary\", operation.getSummary());\n    Assertions.assertEquals(\"notes\", operation.getDescription());\n    Assertions.assertEquals(Arrays.asList(\"tag1\", \"tag2\"), operation.getTags());\n\n    ApiResponses responseMap = operation.getResponses();\n    Assertions.assertEquals(2, responseMap.size());\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = responseMap.get(\"202\");\n    Assertions.assertNotNull(response);\n    Assertions.assertEquals(\"string\", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getType());\n\n    Assertions.assertEquals(1, response.getHeaders().size());\n    Assertions.assertEquals(\"integer\", response.getHeaders().get(\"h1\").getSchema().getType());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.TestInstance;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport jakarta.ws.rs.core.MediaType;\n\n@TestInstance(TestInstance.Lifecycle.PER_CLASS)\npublic class TestApiResponse {\n\n  SwaggerOperations swaggerOperations;\n\n  @BeforeAll\n  public void setUp() {\n    swaggerOperations = SwaggerOperations.generate(ApiResponseAnnotation.class);\n  }\n\n  @AfterAll\n  public void tearDown() {\n    swaggerOperations = null;\n  }\n\n  interface ApiResponseAnnotation {\n    @ApiResponse(\n        headers = {@Header(name = \"k1\", schema = @Schema(implementation = Integer.class)),\n            @Header(name = \"k2\", schema = @Schema(implementation = String.class))},\n        responseCode = \"200\",\n        description = \"\")\n    void testApiResponseHeader();\n\n    @ApiResponse(responseCode = \"200\",\n        headers = {@Header(name = \"k1\", schema = @Schema(implementation = Integer.class))})\n    void testResponseHeader();\n\n    @ApiResponse(\n        content = @Content(schema = @Schema(implementation = Integer.class)),\n        responseCode = \"200\",\n        description = \"msg\")\n    void testSingle();\n\n    @ApiResponses(value = {\n        @ApiResponse(responseCode = \"200\", content = @Content(schema = @Schema(implementation = Integer.class)), description = \"msg1\"),\n        @ApiResponse(responseCode = \"301\", content = @Content(schema = @Schema(implementation = String.class)), description = \"msg2\")})\n    void testMulti();\n  }\n\n  @Test\n  public void checkResponseHeader() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testResponseHeader\");\n    Assertions.assertEquals(\"/testResponseHeader\", swaggerOperation.getPath());\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get(\"200\");\n    io.swagger.v3.oas.models.headers.Header property = response.getHeaders().get(\"k1\");\n    Assertions.assertEquals(\"integer\", property.getSchema().getType());\n    Assertions.assertEquals(\"int32\", property.getSchema().getFormat());\n  }\n\n  @Test\n  public void checkResponseDesc() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testMulti\");\n    Assertions.assertEquals(\"/testMulti\", swaggerOperation.getPath());\n\n    io.swagger.v3.oas.models.responses.ApiResponse response1 = swaggerOperation.getOperation().getResponses()\n        .get(\"200\");\n    io.swagger.v3.oas.models.responses.ApiResponse response2 = swaggerOperation.getOperation().getResponses()\n        .get(\"301\");\n    Assertions.assertEquals(\"msg1\", response1.getDescription());\n    Assertions.assertEquals(\"msg2\", response2.getDescription());\n  }\n\n  @Test\n  public void checkApiResponseHeader() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testApiResponseHeader\");\n    Assertions.assertEquals(\"/testApiResponseHeader\", swaggerOperation.getPath());\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get(\"200\");\n    io.swagger.v3.oas.models.headers.Header property = response.getHeaders().get(\"k1\");\n    Assertions.assertEquals(\"integer\", property.getSchema().getType());\n    Assertions.assertEquals(\"int32\", property.getSchema().getFormat());\n\n    property = response.getHeaders().get(\"k2\");\n    Assertions.assertEquals(\"string\", property.getSchema().getType());\n    Assertions.assertEquals(null, property.getSchema().getFormat());\n  }\n\n  @Test\n  public void checkSingle() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testSingle\");\n    Assertions.assertEquals(\"/testSingle\", swaggerOperation.getPath());\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get(\"200\");\n    Assertions.assertEquals(\"integer\", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getType());\n    Assertions.assertEquals(\"int32\", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getFormat());\n  }\n\n  @Test\n  public void checkMulti() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testMulti\");\n    Assertions.assertEquals(\"/testMulti\", swaggerOperation.getPath());\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get(\"200\");\n    Assertions.assertEquals(\"integer\", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getType());\n    Assertions.assertEquals(\"int32\", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getFormat());\n\n    response = swaggerOperation.getOperation().getResponses().get(\"301\");\n    Assertions.assertEquals(\"string\", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getType());\n    Assertions.assertEquals(null, response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getFormat());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestArrayType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.apache.servicecomb.swagger.generator.core.schema.ArrayType;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.Components;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.ByteArraySchema;\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class TestArrayType {\n  @Test\n  public void test() {\n    SwaggerOperations swaggerOperations = SwaggerOperations.generate(ArrayType.class);\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testBytes\");\n    RequestBody bodyParameter = swaggerOperation.getOperation().getRequestBody();\n    Schema<?> model = bodyParameter.getContent().get(MediaType.APPLICATION_JSON).getSchema();\n\n    Assertions.assertEquals(Components.COMPONENTS_SCHEMAS_REF + \"testBytesBody\", model.get$ref());\n    OpenAPI openAPI = swaggerOperation.getSwagger();\n    Schema<?> schema = openAPI.getComponents().getSchemas().get(\"testBytesBody\");\n    Assertions.assertEquals(1, schema.getProperties().size());\n\n    ByteArraySchema arrayProperty = (ByteArraySchema) schema.getProperties().get(\"value\");\n    Assertions.assertEquals(\"string\", arrayProperty.getType());\n    Assertions.assertEquals(\"byte\", arrayProperty.getFormat());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestClassUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport jakarta.ws.rs.Path;\n\n@OpenAPIDefinition\npublic class TestClassUtils {\n  @Test\n  public void testHasAnnotation() {\n    Assertions.assertTrue(SwaggerUtils.hasAnnotation(TestClassUtils.class, OpenAPIDefinition.class));\n    Assertions.assertTrue(SwaggerUtils.hasAnnotation(TestClassUtils.class, Test.class));\n\n    Assertions.assertFalse(SwaggerUtils.hasAnnotation(TestClassUtils.class, Path.class));\n  }\n\n  @Test\n  public void isRawJsonType() {\n    RequestBody param = new RequestBody();\n\n    Assertions.assertFalse(SwaggerUtils.isRawJsonType(param));\n\n    param.addExtension(SwaggerConst.EXT_RAW_JSON_TYPE, Boolean.FALSE);\n    Assertions.assertFalse(SwaggerUtils.isRawJsonType(param));\n\n    param.addExtension(SwaggerConst.EXT_RAW_JSON_TYPE, Boolean.TRUE);\n    Assertions.assertTrue(SwaggerUtils.isRawJsonType(param));\n  }\n\n  @Test\n  public void getClassName_noName() {\n    Assertions.assertNull(SwaggerUtils.getClassName(null));\n\n    Map<String, Object> vendorExtensions = new HashMap<>();\n    Assertions.assertNull(SwaggerUtils.getClassName(vendorExtensions));\n  }\n\n  @Test\n  public void getClassName_normal() {\n    Map<String, Object> vendorExtensions = new HashMap<>();\n    vendorExtensions.put(SwaggerConst.EXT_JAVA_CLASS, String.class.getName());\n\n    Assertions.assertSame(String.class.getName(), SwaggerUtils.getClassName(vendorExtensions));\n  }\n\n  @Test\n  public void getInterfaceName_noName() {\n    Map<String, Object> vendorExtensions = new HashMap<>();\n\n    Assertions.assertNull(SwaggerUtils.getInterfaceName(vendorExtensions));\n  }\n\n  @Test\n  public void getInterfaceName_normal() {\n    Map<String, Object> vendorExtensions = new HashMap<>();\n    vendorExtensions.put(SwaggerConst.EXT_JAVA_INTF, String.class.getName());\n\n    Assertions.assertSame(String.class.getName(), SwaggerUtils.getInterfaceName(vendorExtensions));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport static org.hamcrest.Matchers.contains;\nimport static org.hamcrest.Matchers.equalTo;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.TestInstance;\n\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.extensions.Extension;\nimport io.swagger.v3.oas.annotations.extensions.ExtensionProperty;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.tags.Tag;\n\n@TestInstance(TestInstance.Lifecycle.PER_CLASS)\npublic class TestOperationGenerator {\n  SwaggerOperations swaggerOperations;\n\n  @BeforeAll\n  public void setUp() {\n    swaggerOperations = SwaggerOperations.generate(TestClass.class);\n  }\n\n  @AfterAll\n  public void tearDown() {\n    swaggerOperations = null;\n  }\n\n  @OpenAPIDefinition(tags = {@Tag(name = \"default0\"), @Tag(name = \"default1\")})\n  private static class TestClass {\n    @ApiResponse(responseCode = \"200\", description = \"200 is ok............\",\n        content = @Content(mediaType = \"application/json\", schema = @Schema(name = \"String\")),\n        headers = @Header(name = \"x-user-domain\", schema = @Schema(implementation = String.class)))\n    @Operation(summary = \"value1\", tags = {\"tag1\", \"tag2\"},\n        responses = {\n            @ApiResponse(responseCode = \"200\", headers =\n                {@Header(name = \"x-user-name\", schema = @Schema(implementation = String.class)),\n                    @Header(name = \"x-user-id\", schema = @Schema(implementation = String.class))})},\n        extensions = {\n            @Extension(name = \"x-class-name\", properties = @ExtensionProperty(value = \"value\", name = \"key\"))})\n    public void responseThenApiOperation() {\n    }\n\n    @Operation(summary = \"value1\", tags = {\"tag1\", \"tag2\"},\n        responses = {@ApiResponse(responseCode = \"200\", headers = {\n            @Header(name = \"x-user-name\", schema = @Schema(implementation = String.class)),\n            @Header(name = \"x-user-id\", schema = @Schema(implementation = String.class))})},\n        extensions = {\n            @Extension(name = \"x-class-name\", properties = {\n                @ExtensionProperty(value = \"value\", name = \"key\")})})\n    @ApiResponse(responseCode = \"200\", description = \"200 is ok............\",\n        content = @Content(mediaType = \"application/json\", schema = @Schema(implementation = String.class)),\n        headers = @Header(name = \"x-user-domain\", schema = @Schema(implementation = String.class)))\n    public void apiOperationThenResponse() {\n    }\n\n    @Operation(summary = \"value2\")\n    public void apiOperationNoTag() {\n    }\n\n    public void noApiOperation() {\n    }\n  }\n\n  @Test\n  public void apiOperationNoTag() {\n    SwaggerOperation operation = swaggerOperations.findOperation(\"apiOperationNoTag\");\n    List<String> tags = operation.getOperation().getTags();\n    MatcherAssert.assertThat(tags, equalTo(null));\n    Assertions.assertEquals(\"value2\", operation.getOperation().getSummary());\n  }\n\n  @Test\n  public void noApiOperation() {\n    SwaggerOperation operation = swaggerOperations.findOperation(\"noApiOperation\");\n    List<String> tags = operation.getOperation().getTags();\n    MatcherAssert.assertThat(tags, equalTo(null));\n    Assertions.assertNull(operation.getOperation().getSummary());\n  }\n\n  @Test\n  public void responseThenApiOperation() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"responseThenApiOperation\");\n    List<String> tags = swaggerOperation.getOperation().getTags();\n    MatcherAssert.assertThat(tags, contains(\"tag1\", \"tag2\"));\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get(\"200\");\n    Assertions.assertEquals(\"200 is ok............\", response.getDescription());\n    Assertions.assertNotNull(response.getHeaders().get(\"x-user-domain\"));\n    Assertions.assertNotNull(response.getHeaders().get(\"x-user-name\"));\n    Assertions.assertNotNull(swaggerOperation.getOperation().getExtensions().get(\"x-class-name\"));\n    Assertions.assertNull(swaggerOperation.getOperation().getExtensions().get(\"x-not-exists\"));\n  }\n\n  @Test\n  public void apiOperationThenResponse() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"apiOperationThenResponse\");\n    List<String> tags = swaggerOperation.getOperation().getTags();\n    MatcherAssert.assertThat(tags, contains(\"tag1\", \"tag2\"));\n\n    io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get(\"200\");\n    Assertions.assertEquals(\"200 is ok............\", response.getDescription());\n    Assertions.assertNotNull(response.getHeaders().get(\"x-user-domain\"));\n    Assertions.assertNotNull(response.getHeaders().get(\"x-user-name\"));\n    Assertions.assertNotNull(swaggerOperation.getOperation().getExtensions().get(\"x-class-name\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestPojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic class TestPojo {\n  @SuppressWarnings(\"unused\")\n  public static class ParameterAnnotation {\n    @Operation(summary = \"differentName\", operationId = \"differentName\")\n    public int operationIdAndParameter(@Parameter(name = \"x\") int a, @Parameter(name = \"y\") int b) {\n      return a * 2 + b;\n    }\n  }\n\n  @Test\n  public void testResponseEntity() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/ParameterAnnotation.yaml\", ParameterAnnotation.class);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestPojoExample.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport org.apache.servicecomb.swagger.generator.core.pojo.PojoExample1;\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.junit.jupiter.api.Test;\n\npublic class TestPojoExample {\n  @Test\n  public void testPojoExample1() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/pojoExample1.yaml\", PojoExample1.class);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerDefinition.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.annotations.ExternalDocumentation;\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.extensions.Extension;\nimport io.swagger.v3.oas.annotations.extensions.ExtensionProperty;\nimport io.swagger.v3.oas.annotations.info.Contact;\nimport io.swagger.v3.oas.annotations.info.Info;\nimport io.swagger.v3.oas.annotations.info.License;\nimport io.swagger.v3.oas.annotations.servers.Server;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestSwaggerDefinition {\n  @OpenAPIDefinition(\n      servers = @Server(url = \"host/base\"),\n      tags = {@Tag(\n          name = \"tagA\",\n          description = \"desc of tagA\",\n          externalDocs = @ExternalDocumentation(description = \"tagA ext docs\", url = \"url of tagA ext docs\"),\n          extensions = {@Extension(\n              name = \"x-tagA\",\n              properties = {@ExtensionProperty(name = \"x-tagAExt\", value = \"value of tagAExt\")})})},\n      info = @Info(\n          title = \"title of SwaggerAnnotation\",\n          version = \"0.1\",\n          termsOfService = \"termsOfService\",\n          description = \"description of info for SwaggerAnnotation\",\n          contact = @Contact(name = \"contact\", email = \"contact@email.com\", url = \"http://contact\"),\n          license = @License(name = \"license \", url = \"http://license\"),\n          extensions = {@Extension(\n              name = \"x-info\",\n              properties = {@ExtensionProperty(name = \"x-infoExt\", value = \"value of infoExt\")})}),\n      externalDocs = @ExternalDocumentation(\n          description = \"SwaggerAnnotation ext docs\",\n          url = \"url of SwaggerAnnotation ext docs\"))\n  interface SwaggerAnnotation {\n  }\n\n  interface SwaggerNoAnnotation {\n  }\n\n  @Test\n  public void testSwaggerDefinition() {\n    OpenAPI swagger = SwaggerGenerator.generate(SwaggerAnnotation.class);\n\n    Assertions.assertEquals(\"value of infoExt\",\n        ((Map<String, String>) swagger.getInfo().getExtensions().get(\"x-info\")).get(\"x-infoExt\"));\n    Assertions.assertEquals(\"3.0.1\", swagger.getOpenapi());\n    Assertions.assertEquals(\"host/base\", swagger.getServers().get(0).getUrl());\n\n    Assertions.assertEquals(1, swagger.getTags().size());\n    io.swagger.v3.oas.models.tags.Tag tagA = swagger.getTags().get(0);\n    Assertions.assertEquals(\"tagA\", tagA.getName());\n    Assertions.assertEquals(\"desc of tagA\", tagA.getDescription());\n    Assertions.assertEquals(\"tagA ext docs\", tagA.getExternalDocs().getDescription());\n    Assertions.assertEquals(\"url of tagA ext docs\", tagA.getExternalDocs().getUrl());\n    Assertions.assertEquals(1, tagA.getExtensions().size());\n\n    Map<String, String> tagValue = (Map<String, String>) tagA.getExtensions().get(\"x-tagA\");\n    Assertions.assertEquals(\"value of tagAExt\", tagValue.get(\"x-tagAExt\"));\n\n    io.swagger.v3.oas.models.info.Info info = swagger.getInfo();\n    Assertions.assertEquals(\"title of SwaggerAnnotation\", info.getTitle());\n    Assertions.assertEquals(\"0.1\", info.getVersion());\n    Assertions.assertEquals(\"termsOfService\", info.getTermsOfService());\n    Assertions.assertEquals(\"description of info for SwaggerAnnotation\", info.getDescription());\n\n    Assertions.assertEquals(\"contact\", info.getContact().getName());\n    Assertions.assertEquals(\"contact@email.com\", info.getContact().getEmail());\n    Assertions.assertEquals(\"http://contact\", info.getContact().getUrl());\n\n    Assertions.assertEquals(\"license \", info.getLicense().getName());\n    Assertions.assertEquals(\"http://license\", info.getLicense().getUrl());\n\n    Assertions.assertEquals(\"SwaggerAnnotation ext docs\", swagger.getExternalDocs().getDescription());\n    Assertions.assertEquals(\"url of SwaggerAnnotation ext docs\", swagger.getExternalDocs().getUrl());\n  }\n\n  @Test\n  public void testFillDefault() {\n    OpenAPI swagger = SwaggerGenerator.generate(SwaggerNoAnnotation.class);\n    Assertions.assertEquals(\"3.0.1\", swagger.getOpenapi());\n    Assertions.assertEquals(\"/SwaggerNoAnnotation\", swagger.getServers().get(0).getUrl());\n    Assertions.assertEquals(\"swagger definition for \" + SwaggerNoAnnotation.class.getName(),\n        swagger.getInfo().getTitle());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGenerator;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\npublic class TestSwaggerGenerator {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testBasePathPlaceHolder() {\n    Mockito.when(environment.getProperty(\"var\")).thenReturn(\"varValue\");\n\n    PojoSwaggerGenerator swaggerGenerator = new PojoSwaggerGenerator(null);\n    swaggerGenerator.setBasePath(\"/a/${var}/b\");\n\n    Assertions.assertEquals(\"/a/varValue/b\", SwaggerUtils.getBasePath(swaggerGenerator.getOpenAPI()));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core;\n\nimport static junit.framework.TestCase.fail;\nimport static org.hamcrest.Matchers.containsString;\nimport static org.mockito.Mockito.when;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.lang.reflect.Type;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Logger;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils;\nimport org.apache.servicecomb.swagger.generator.core.pojo.TestTypeClass;\nimport org.apache.servicecomb.swagger.generator.core.pojo.TestTypeRecord;\nimport org.apache.servicecomb.swagger.generator.core.pojo.TestType1;\nimport org.apache.servicecomb.swagger.generator.core.pojo.TestType2;\nimport org.apache.servicecomb.swagger.generator.core.schema.RepeatOperation;\nimport org.apache.servicecomb.swagger.generator.core.schema.Schema;\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.media.IntegerSchema;\nimport io.swagger.v3.oas.models.media.StringSchema;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\n@SuppressWarnings(\"rawtypes\")\npublic class TestSwaggerUtils {\n  Logger LOGGER = Logger.getLogger(TestSwaggerUtils.class.getName());\n\n  @Test\n  public void testSchemaMethod() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/Schema.yaml\",\n        Schema.class);\n  }\n\n  @Test\n  public void testRepeatOperation() {\n    UnitTestSwaggerUtils.testException(\n        \"OperationId must be unique. method=org.apache.servicecomb.swagger.generator.core.schema.RepeatOperation:add.\",\n        RepeatOperation.class);\n  }\n\n  @Test\n  public void noParameterName() {\n    Method method = ReflectUtils.findMethod(Schema.class, \"testint\");\n    Parameter parameter = Mockito.spy(method.getParameters()[0]);\n    Mockito.when(parameter.isNamePresent()).thenReturn(false);\n\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class,\n        () -> SwaggerGeneratorUtils.collectParameterName(parameter));\n    String expectedMsg =\n        \"parameter name is not present, method=org.apache.servicecomb.swagger.generator.core.schema.Schema:testint\\n\"\n            + \"solution:\\n\"\n            + \"  change pom.xml, add compiler argument: -parameters, for example:\\n\"\n            + \"    <plugin>\\n\"\n            + \"      <groupId>org.apache.maven.plugins</groupId>\\n\"\n            + \"      <artifactId>maven-compiler-plugin</artifactId>\\n\"\n            + \"      <configuration>\\n\"\n            + \"        <compilerArgument>-parameters</compilerArgument>\\n\"\n            + \"      </configuration>\\n\"\n            + \"    </plugin>\";\n    Assertions.assertEquals(expectedMsg, exception.getMessage());\n  }\n\n  @Test\n  public void testGetRawJsonType() {\n    RequestBody param = Mockito.mock(RequestBody.class);\n    Map<String, Object> extensions = new HashMap<>();\n    when(param.getExtensions()).thenReturn(extensions);\n\n    extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, true);\n    Assertions.assertTrue(SwaggerUtils.isRawJsonType(param));\n\n    extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, \"test\");\n    Assertions.assertFalse(SwaggerUtils.isRawJsonType(param));\n  }\n\n  private static class AllTypeTest1 {\n    TestType1 t1;\n\n    List<TestType1> t2;\n\n    Map<String, TestType1> t3;\n\n    TestType1[] t4;\n  }\n\n  private static class AllTypeTest2 {\n    TestType2 t1;\n\n    List<TestType2> t2;\n\n    Map<String, TestType2> t3;\n\n    TestType2[] t4;\n\n  }\n\n  private static class AllTypeTest3{\n    TestTypeRecord t5;\n  }\n  private static class AllTypeTest4{\n    TestTypeClass t5;\n  }\n\n  @Test\n  public void testAddDefinitions() {\n    testAllType(AllTypeTest1.class, AllTypeTest2.class);\n  }\n\n  private void testAllType(Class clazz1, Class clazz2) {\n    Field[] fields1 = clazz1.getDeclaredFields();\n    Field[] fields2 = clazz2.getDeclaredFields();\n    for (Field value : fields1) {\n      for (Field field : fields2) {\n        if (value.isSynthetic() || field.isSynthetic()) {\n          continue;\n        }\n        try {\n          testExcep(value.getGenericType(), field.getGenericType());\n          fail(\"IllegalArgumentException expected\");\n        } catch (IllegalArgumentException e) {\n          LOGGER.warning(value.getGenericType() + \" \" + field.getGenericType() + \" \" + e.getMessage());\n          MatcherAssert.assertThat(e.getMessage(), containsString(\"duplicate param model:\"));\n        }\n      }\n    }\n  }\n\n  @Test\n  public void testAddDefinitionsWithRecord() {\n    testAllType(AllTypeTest3.class, AllTypeTest4.class);\n  }\n\n  private void testExcep(Type f1, Type f2) {\n    OpenAPI swagger = new OpenAPI();\n    SwaggerUtils.resolveTypeSchemas(swagger, f1);\n    SwaggerUtils.resolveTypeSchemas(swagger, f2);\n  }\n\n  @Test\n  public void test_resolve_type_schemas_correct() {\n    OpenAPI openAPI = new OpenAPI();\n\n    io.swagger.v3.oas.models.media.Schema schema = SwaggerUtils.resolveTypeSchemas(openAPI, String.class);\n    Assertions.assertTrue(schema instanceof StringSchema);\n\n    openAPI = new OpenAPI();\n    schema = SwaggerUtils.resolveTypeSchemas(openAPI, Integer.class);\n    Assertions.assertTrue(schema instanceof IntegerSchema);\n\n    openAPI = new OpenAPI();\n    schema = SwaggerUtils.resolveTypeSchemas(openAPI, TestType1.class);\n    schema = SwaggerUtils.getSchema(openAPI, schema); // resolve reference\n    // should be ObjectSchema but swagger is not.\n    // <pre> Assertions.assertTrue(schema instanceof ObjectSchema) </pre>\n    Assertions.assertEquals(\"object\", schema.getType());\n\n    openAPI = new OpenAPI();\n    schema = SwaggerUtils.getSchema(openAPI, SwaggerUtils.resolveTypeSchemas(openAPI, TestTypeClass.class)); // resolve reference\n    Assertions.assertEquals(\"object\", schema.getType());\n\n    openAPI = new OpenAPI();\n    schema = SwaggerUtils.getSchema(openAPI, SwaggerUtils.resolveTypeSchemas(openAPI, TestTypeRecord.class)); // resolve reference\n    Assertions.assertEquals(\"object\", schema.getType());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/model/TestSwaggerOperations.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.model;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.pojo.PojoExample1;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\npublic class TestSwaggerOperations {\n\n  @Test\n  public void emptyOperationId() {\n    OpenAPI swagger = SwaggerUtils.parseAndValidateSwagger(this.getClass().getResource(\"/schemas/boolean.yaml\"));\n    swagger.getPaths().values().stream()\n        .findFirst().get()\n        .getPost().setOperationId(\"\");\n\n    IllegalStateException exception = Assertions.assertThrows(IllegalStateException.class,\n        () -> new SwaggerOperations(swagger));\n    Assertions.assertEquals(\"OperationId can not be empty, path=/testboolean, httpMethod=POST.\",\n        exception.getMessage());\n  }\n\n  @Test\n  public void testPojoExample1() {\n    SwaggerOperations swaggerOperations = SwaggerOperations.generate(PojoExample1.class);\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testMultiParameter\");\n    Assertions.assertEquals(null, swaggerOperation.getOperation().getParameters());\n    RequestBody requestBody = swaggerOperation.getOperation().getRequestBody();\n    Assertions.assertEquals(2,\n        SwaggerUtils.getSchema(swaggerOperation.getSwagger(),\n            requestBody.getContent().get(SwaggerConst.DEFAULT_MEDIA_TYPE).getSchema()).getProperties().size());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/PojoExample1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.pojo;\n\npublic class PojoExample1 {\n  public TestType1 testOneParameter(TestType1 testType1) {\n    return null;\n  }\n\n  public TestType1 testMultiParameter(TestType1 testType1, String testString) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestType1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.pojo;\n\nimport io.swagger.v3.oas.annotations.media.Schema;\n\n@Schema(name = \"XXX\")\npublic class TestType1 {\n  public Integer val1;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestType2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.pojo;\n\nimport io.swagger.v3.oas.annotations.media.Schema;\n\n@Schema(name = \"XXX\")\npublic class TestType2 {\n  public String val2;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeClass.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.pojo;\n\nimport io.swagger.v3.oas.annotations.media.Schema;\n\n@Schema(name = \"YYY\")\npublic class TestTypeClass {\n  @Schema(description = \"language\")\n  private TestTypeEnumLang testTypeEnumLang;\n\n  public TestTypeEnumLang getTestTypeEnumLang() {\n    return testTypeEnumLang;\n  }\n\n  public void setTestTypeEnumLang(TestTypeEnumLang testTypeEnumLang) {\n    this.testTypeEnumLang = testTypeEnumLang;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeEnumLang.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.pojo;\n\npublic enum TestTypeEnumLang {\n  JAVA, CHINESE, UNKNOWN;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeRecord.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.pojo;\n\nimport io.swagger.v3.oas.annotations.media.Schema;\n\n@Schema(name = \"YYY\")\npublic record TestTypeRecord(\n    @Schema(description = \"language\") TestTypeEnumLang testTypeEnumLang) {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OpenAPIDefinitionProcessorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.annotations.ExternalDocumentation;\nimport io.swagger.v3.oas.annotations.OpenAPIDefinition;\nimport io.swagger.v3.oas.annotations.info.Contact;\nimport io.swagger.v3.oas.annotations.info.Info;\nimport io.swagger.v3.oas.annotations.info.License;\nimport io.swagger.v3.oas.annotations.servers.Server;\nimport io.swagger.v3.oas.annotations.tags.Tag;\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class OpenAPIDefinitionProcessorTest {\n  @OpenAPIDefinition(tags = {\n      @Tag(name = \"testTag\", description = \"desc\", externalDocs = @ExternalDocumentation(description = \"testValue\", url = \"testUrl\"))\n  },\n      servers = {@Server(url = \"127.0.0.1\")},\n      info = @Info(title = \"title\", version = \"version\", description = \"desc\", contact = @Contact(name = \"contactName\"),\n          license = @License(name = \"licenseName\")))\n  private static class SwaggerTestTarget {\n  }\n\n  @Test\n  public void testProcess() {\n    OpenAPI swagger = SwaggerGenerator.generate(SwaggerTestTarget.class);\n\n    Assertions.assertEquals(1, swagger.getTags().size());\n    io.swagger.v3.oas.models.tags.Tag tag = swagger.getTags().get(0);\n    Assertions.assertEquals(\"testTag\", tag.getName());\n    Assertions.assertEquals(\"desc\", tag.getDescription());\n    Assertions.assertEquals(\"testValue\", tag.getExternalDocs().getDescription());\n    Assertions.assertEquals(\"testUrl\", tag.getExternalDocs().getUrl());\n    Assertions.assertEquals(\"127.0.0.1\", swagger.getServers().get(0).getUrl());\n\n    io.swagger.v3.oas.models.info.Info info = swagger.getInfo();\n    Assertions.assertEquals(\"title\", info.getTitle());\n    Assertions.assertEquals(\"version\", info.getVersion());\n    Assertions.assertEquals(\"desc\", info.getDescription());\n    Assertions.assertEquals(\"contactName\", info.getContact().getName());\n    Assertions.assertEquals(\"licenseName\", info.getLicense().getName());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.processor.annotation;\n\nimport static org.hamcrest.Matchers.containsInAnyOrder;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeAll;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.TestInstance;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.parameters.RequestBody;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.models.Components;\nimport jakarta.validation.constraints.NotBlank;\nimport jakarta.validation.constraints.NotEmpty;\nimport jakarta.validation.constraints.NotNull;\nimport jakarta.ws.rs.core.MediaType;\n\n@TestInstance(TestInstance.Lifecycle.PER_CLASS)\npublic class OperationMethodAnnotationProcessorTest {\n  SwaggerOperations swaggerOperations;\n\n  @BeforeAll\n  public void setUp() {\n    swaggerOperations = SwaggerOperations.generate(TestClass.class);\n  }\n\n  @AfterAll\n  public void tearDown() {\n    swaggerOperations = null;\n  }\n\n  private static class TestClass {\n    @Operation(summary = \"value1\", tags = {\"tag1\", \"tag2\"})\n    public void function() {\n    }\n\n    @Operation(summary = \"value2\")\n    public void functionWithNoTag() {\n    }\n\n    // mediaType will be ignored\n    @Operation(summary = \"testSingleMediaType\",\n        responses = {@ApiResponse(responseCode = \"200\", content = @Content(\n            mediaType = MediaType.TEXT_PLAIN, schema = @Schema(implementation = String.class)))})\n    public String testSingleMediaType(String input) {\n      return input;\n    }\n\n    @Operation(summary = \"testMultiMediaType\",\n        responses = {\n            @ApiResponse(responseCode = \"200\", content = {\n                @Content(mediaType = MediaType.APPLICATION_JSON),\n                @Content(mediaType = MediaType.TEXT_PLAIN)\n            })})\n    public String testMultiMediaType(String input) {\n      return input;\n    }\n\n    @Operation(summary = \"testBlankMediaType\",\n        responses = {@ApiResponse(responseCode = \"200\", content = @Content(mediaType = \"\"))},\n        requestBody = @RequestBody(content = @Content(mediaType = \"\",\n            schema = @Schema(implementation = String.class))))\n    public String testBlankMediaType(String input) {\n      return input;\n    }\n\n    @Operation(summary = \"testBodyParam\")\n    public String testBodyParam(@RequestBody(content = @Content(\n        schema = @Schema(\n            implementation = TestBodyBean.class))) TestBodyBean user) {\n      return user.toString();\n    }\n  }\n\n\n  private static class TestBodyBean {\n\n    @NotBlank\n    private String age;\n\n    @NotNull\n    private String name;\n\n    @NotEmpty\n    private String sexes;\n\n    public String getAge() {\n      return age;\n    }\n\n    public void setAge(String age) {\n      this.age = age;\n    }\n\n    public String getName() {\n      return name;\n    }\n\n    public void setName(String name) {\n      this.name = name;\n    }\n\n    public String getSexes() {\n      return sexes;\n    }\n\n    public void setSexes(String sexes) {\n      this.sexes = sexes;\n    }\n  }\n\n  @Test\n  public void testConvertTags() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"function\");\n    MatcherAssert.assertThat(swaggerOperation.getOperation().getTags(), containsInAnyOrder(\"tag1\", \"tag2\"));\n  }\n\n  @Test\n  public void testConvertTagsOnMethodWithNoTag() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"functionWithNoTag\");\n    Assertions.assertNull(swaggerOperation.getOperation().getTags());\n  }\n\n  @Test\n  public void testMultiMediaType() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testMultiMediaType\");\n    MatcherAssert.assertThat(swaggerOperation.getOperation().getRequestBody().getContent().keySet(),\n        Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN));\n    MatcherAssert.assertThat(swaggerOperation.getOperation().getResponses().get(\"200\").getContent().keySet(),\n        Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN));\n  }\n\n  @Test\n  public void testSingleMediaType() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testSingleMediaType\");\n    MatcherAssert.assertThat(swaggerOperation.getOperation()\n            .getRequestBody().getContent().get(MediaType.APPLICATION_JSON).getSchema().get$ref(),\n        Matchers.equalTo(Components.COMPONENTS_SCHEMAS_REF + \"testSingleMediaTypeBody\"));\n    MatcherAssert.assertThat(swaggerOperation.getOperation()\n            .getResponses().get(\"200\").getContent().get(MediaType.TEXT_PLAIN).getSchema().getType(),\n        Matchers.equalTo(\"string\"));\n  }\n\n  @Test\n  public void testBlankMediaType() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testBlankMediaType\");\n    MatcherAssert.assertThat(swaggerOperation.getOperation().getRequestBody().getContent().keySet(),\n        Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN));\n    MatcherAssert.assertThat(swaggerOperation.getOperation().getResponses()\n            .get(SwaggerConst.SUCCESS_KEY).getContent().keySet(),\n        Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN));\n  }\n\n  @Test\n  public void testBodyParam() {\n    SwaggerOperation swaggerOperation = swaggerOperations.findOperation(\"testBodyParam\");\n    io.swagger.v3.oas.models.media.Schema<?> schema = swaggerOperation.getSwagger()\n        .getPaths().get(\"/testBodyParam\").getPost().getRequestBody().getContent()\n        .get(MediaType.APPLICATION_JSON).getSchema();\n    Assertions.assertEquals(Components.COMPONENTS_SCHEMAS_REF + \"TestBodyBean\", schema.get$ref());\n    schema = swaggerOperation.getSwagger().getComponents().getSchemas().get(\"TestBodyBean\");\n    Map<String, io.swagger.v3.oas.models.media.Schema> properties = schema.getProperties();\n    Assertions.assertEquals(properties.get(\"age\").getType(), \"string\");\n    Assertions.assertEquals(properties.get(\"sexes\").getType(), \"string\");\n    Assertions.assertEquals(properties.get(\"name\").getType(), \"string\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/AllType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.schema;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\npublic class AllType {\n//  public boolean bValue;\n//\n//  public byte byteValue;\n//\n//  public Byte byteObjectValue;\n//\n//  public short sValue;\n//\n//  public Short sObjectValue;\n//\n//  public int iValue;\n//\n//  public Integer iObjectValue;\n//\n//  public long lValue;\n//\n//  public Long lObjectValue;\n//\n//  public float fValue;\n//\n//  public Float fObjectValue;\n//\n//  public double dValue;\n//\n//  public Double dObjectValue;\n//\n//  public Color enumValue;\n//\n//  public char cValue;\n//\n//  public Character cObjectValue;\n//\n//  public byte[] bytes;\n//\n//  public String strValue;\n//\n//  public Set<String> set;\n\n  public List<User> list;\n\n//  public Map<String, User> map;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/ArrayType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.schema;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\npublic class ArrayType {\n  public byte[] testBytes(byte[] value) {\n    return null;\n  }\n\n  public User[] testUsers(User[] value) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/RepeatOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.schema;\n\npublic class RepeatOperation {\n  public int add(int x, int y) {\n    return x + y;\n  }\n\n  public int add(int x, int y, int z) {\n    return x + y + z;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/Schema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.schema;\n\nimport java.util.Collections;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport jakarta.servlet.http.HttpServletRequest;\n\n@SuppressWarnings(\"all\")\npublic class Schema {\n  @Operation(method = \"\", hidden = true)\n  public void hidden() {\n\n  }\n\n  @ApiResponse(headers = {@Header(name = \"h\",\n      schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = String.class))}, responseCode = \"200\", description = \"\")\n  public void testApiResponse() {\n\n  }\n\n  @ApiResponse(headers = {@Header(name = \"h\",\n      schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = String.class))}, description = \"\")\n  public void testApiOperation() {\n\n  }\n\n  @ApiResponse(headers = {@Header(name = \"h\",\n      schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = String.class))})\n  public void testResponseHeader() {\n\n  }\n\n  public void testboolean(boolean value) {\n\n  }\n\n  public void testBoolean(Boolean value) {\n\n  }\n\n  public void testbyte(byte value) {\n\n  }\n\n  public void testByte(Byte value) {\n\n  }\n\n  public void testshort(short value) {\n\n  }\n\n  public void testShort(Short value) {\n\n  }\n\n  public void testint(int value) {\n\n  }\n\n  public void testInteger(Integer value) {\n\n  }\n\n  public void testlong(long value) {\n\n  }\n\n  public void testLong(Long value) {\n\n  }\n\n  public void testfloat(float value) {\n\n  }\n\n  public void testFloat(Float value) {\n\n  }\n\n  public void testdouble(double value) {\n\n  }\n\n  public void testDouble(Double value) {\n\n  }\n\n  public void testOneEnum(Color color) {\n\n  }\n\n  public void testEnum(Color color, Color color1) {\n\n  }\n\n  public void testchar(char value) {\n\n  }\n\n  public void testChar(Character value) {\n\n  }\n\n  public void testbytes(byte[] value) {\n\n  }\n\n  public void testBytes(Byte[] value) {\n\n  }\n\n  public void testString(String value) {\n\n  }\n\n  public void testObject(User user) {\n\n  }\n\n  public void testArray(String[] value) {\n\n  }\n\n  public void testSet(Set<String> value) {\n\n  }\n\n  public List<List<String>> nestedListString(List<List<String>> param) {\n    return param;\n  }\n\n  public void testList(List<User> value) {\n\n  }\n\n  public void testMap(Map<String, User> value) {\n\n  }\n\n  public Date testDate() {\n    return null;\n  }\n\n  public void testMapList(Map<String, List<User>> value) {\n\n  }\n\n  public CompletableFuture<String> testCompletableFuture() {\n    return null;\n  }\n\n  public Optional<String> testOptional() {\n    return Optional.empty();\n  }\n\n  public CompletableFuture<Optional<String>> testCompletableFutureOptional() {\n    return null;\n  }\n\n  public void testAllType(AllType obj) {\n  }\n\n  public List<String> testMultiParam(AllType obj,\n      boolean bValue,\n      byte byteValue,\n      short sValue,\n      int iValue,\n      long lValue,\n      float fValue,\n      double dValue,\n      Color enumValue,\n      char cValue,\n      byte[] bytes,\n      String strValue,\n      String[] strArray,\n      Set<String> set,\n      List<User> list,\n      Map<String, User> map) {\n    return Collections.emptyList();\n  }\n\n  public void wrapToBodyWithDesc(@Parameter(name = \"desc\") int value) {\n\n  }\n\n  public void ignoreRequest(HttpServletRequest request, int value) {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestMethodUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils;\n\nimport java.lang.reflect.Method;\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.AbstractBaseClass;\nimport org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.BaseInterface;\nimport org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.Hello2Endpoint;\nimport org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.HelloEndpoint;\nimport org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.ServiceInterface;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestMethodUtils {\n  @Test\n  public void testGetClassMethods() throws Exception {\n    List<Method> methods = MethodUtils.findSwaggerMethods(Hello2Endpoint.class);\n    Assertions.assertEquals(3, methods.size());\n    Assertions.assertEquals(Hello2Endpoint.class, methods.get(0).getDeclaringClass());\n    Assertions.assertEquals(Hello2Endpoint.class, methods.get(1).getDeclaringClass());\n    Assertions.assertEquals(Hello2Endpoint.class, methods.get(2).getDeclaringClass());\n\n    methods = MethodUtils.findSwaggerMethods(HelloEndpoint.class);\n    Assertions.assertEquals(2, methods.size());\n    Assertions.assertEquals(HelloEndpoint.class, methods.get(0).getDeclaringClass()); // get\n    Assertions.assertEquals(AbstractBaseClass.class, methods.get(1).getDeclaringClass()); // getBase\n\n    methods = MethodUtils.findSwaggerMethods(ServiceInterface.class);\n    Assertions.assertEquals(3, methods.size());\n    Assertions.assertEquals(BaseInterface.class, methods.get(0).getDeclaringClass()); // get\n    Assertions.assertEquals(BaseInterface.class, methods.get(1).getDeclaringClass()); // getArray\n    Assertions.assertEquals(ServiceInterface.class, methods.get(2).getDeclaringClass()); // getBase\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBaseClass.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic abstract class AbstractBaseClass<T extends AbstractBean> {\n  abstract T get(T param);\n\n  public T getBase(T param) {\n    return param;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic abstract class AbstractBean {\n  private String type;\n\n  public String getType() {\n    return type;\n  }\n\n  public void setType(String type) {\n    this.type = type;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/BaseInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic interface BaseInterface<T extends AbstractBean> {\n  T get(T param);\n\n  T[] getArray(T[] param);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/Hello2Endpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic class Hello2Endpoint implements ServiceInterface {\n  @Override\n  public HelloBean get(HelloBean param) {\n    return param;\n  }\n\n  @Override\n  public HelloBean[] getArray(HelloBean[] param) {\n    return new HelloBean[0];\n  }\n\n  @Override\n  public HelloBean getBase(HelloBean param) {\n    return param;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic class HelloBean extends AbstractBean {\n  private String hello;\n\n  public String getHello() {\n    return hello;\n  }\n\n  public void setHello(String hello) {\n    this.hello = hello;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic class HelloEndpoint extends AbstractBaseClass<HelloBean> {\n  @Override\n  public HelloBean get(HelloBean param) {\n    return param;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/ServiceInterface.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;\n\npublic interface ServiceInterface extends BaseInterface<HelloBean> {\n  HelloBean getBase(HelloBean param);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBaseService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\nimport java.util.List;\n\npublic class AbstractBaseService<T extends AbstractBean> implements IBaseService<T> {\n  private final IBaseService<T> target;\n\n  protected AbstractBaseService(IBaseService<T> t) {\n    target = t;\n  }\n\n  @Override\n  public T hello(T a) {\n    return target.hello(a);\n  }\n\n  @Override\n  public T[] helloBody(T[] a) {\n    return target.helloBody(a);\n  }\n\n  @Override\n  public List<T> helloList(List<T> a) {\n    return a;\n  }\n\n  @Override\n  public PersonBean actual(PersonBean bean) {\n    return target.actual(bean);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\npublic abstract class AbstractBean {\n  private String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IBaseService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\nimport java.util.List;\n\npublic interface IBaseService<T extends AbstractBean> {\n  T hello(T a);\n\n  T[] helloBody(T[] a);\n\n  List<T> helloList(List<T> a);\n\n  PersonBean actual(PersonBean bean);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\nimport java.util.List;\n\nimport org.springframework.web.multipart.MultipartFile;\n\npublic interface IMyService extends IBaseService<PersonBean> {\n  List<MultipartFile> parentHello(List<MultipartFile> bean);\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\npublic interface IMyServiceChild extends IMyService {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\npublic interface IMyServiceChild2 extends IMyService, IBaseService<PersonBean> {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\nimport java.util.List;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.web.multipart.MultipartFile;\n\npublic class MyEndpoint extends AbstractBaseService<PersonBean> implements IMyService {\n  public MyEndpoint(@Autowired IMyService other) {\n    super(other);\n  }\n\n  @Override\n  public List<MultipartFile> parentHello(List<MultipartFile> bean) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\nimport java.util.List;\n\nimport org.springframework.web.multipart.MultipartFile;\n\npublic class MyEndpoint2 implements IMyService {\n  @Override\n  public PersonBean hello(PersonBean a) {\n    return null;\n  }\n\n  @Override\n  public PersonBean[] helloBody(PersonBean[] a) {\n    return new PersonBean[0];\n  }\n\n  @Override\n  public List<PersonBean> helloList(List<PersonBean> a) {\n    return null;\n  }\n\n  @Override\n  public PersonBean actual(PersonBean bean) {\n    return null;\n  }\n\n  @Override\n  public List<MultipartFile> parentHello(List<MultipartFile> bean) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/PersonBean.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;\n\npublic class PersonBean extends AbstractBean {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/ParameterAnnotation.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.TestPojo$ParameterAnnotation\n  version: 1.0.0\nservers:\n- url: /ParameterAnnotation\npaths:\n  /differentName:\n    post:\n      summary: differentName\n      operationId: differentName\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/differentNameBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/differentNameBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/differentNameBody\"\n        x-name: differentNameBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: integer\n                format: int32\n            application/protobuf:\n              schema:\n                type: integer\n                format: int32\n            text/plain:\n              schema:\n                type: integer\n                format: int32\ncomponents:\n  schemas:\n    differentNameBody:\n      type: object\n      properties:\n        x:\n          type: integer\n          format: int32\n        \"y\":\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/Schema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /ignoreRequest:\n    post:\n      operationId: ignoreRequest\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/ignoreRequestBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/ignoreRequestBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/ignoreRequestBody\"\n        x-name: ignoreRequestBody\n      responses:\n        \"200\":\n          description: response of 200\n  /nestedListString:\n    post:\n      operationId: nestedListString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/nestedListStringBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/nestedListStringBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/nestedListStringBody\"\n        x-name: nestedListStringBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n            text/plain:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n  /testAllType:\n    post:\n      operationId: testAllType\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/AllType\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/AllType\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/AllType\"\n        x-name: obj\n      responses:\n        \"200\":\n          description: response of 200\n  /testApiOperation:\n    post:\n      operationId: testApiOperation\n      responses:\n        \"200\":\n          description: response of 200\n          headers:\n            h:\n              schema:\n                type: string\n                description: \"\"\n                nullable: false\n                example: \"\"\n  /testApiResponse:\n    post:\n      operationId: testApiResponse\n      responses:\n        \"200\":\n          description: response of 200\n          headers:\n            h:\n              schema:\n                type: string\n                description: \"\"\n                nullable: false\n                example: \"\"\n  /testArray:\n    post:\n      operationId: testArray\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testArrayBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testArrayBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testArrayBody\"\n        x-name: testArrayBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testBoolean:\n    post:\n      operationId: testBoolean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testBooleanBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testBooleanBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testBooleanBody\"\n        x-name: testBooleanBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testByte:\n    post:\n      operationId: testByte\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testByteBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testByteBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testByteBody\"\n        x-name: testByteBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testBytes:\n    post:\n      operationId: testBytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testBytesBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testBytesBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testBytesBody\"\n        x-name: testBytesBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testChar:\n    post:\n      operationId: testChar\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testCharBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testCharBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testCharBody\"\n        x-name: testCharBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testCompletableFuture:\n    post:\n      operationId: testCompletableFuture\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testCompletableFutureOptional:\n    post:\n      operationId: testCompletableFutureOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testDate:\n    post:\n      operationId: testDate\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n                format: date-time\n            application/protobuf:\n              schema:\n                type: string\n                format: date-time\n            text/plain:\n              schema:\n                type: string\n                format: date-time\n  /testDouble:\n    post:\n      operationId: testDouble\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testDoubleBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testDoubleBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testDoubleBody\"\n        x-name: testDoubleBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testEnum:\n    post:\n      operationId: testEnum\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testEnumBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testEnumBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testEnumBody\"\n        x-name: testEnumBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testFloat:\n    post:\n      operationId: testFloat\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testFloatBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testFloatBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testFloatBody\"\n        x-name: testFloatBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testInteger:\n    post:\n      operationId: testInteger\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testIntegerBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testIntegerBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testIntegerBody\"\n        x-name: testIntegerBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testList:\n    post:\n      operationId: testList\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testListBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testListBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testListBody\"\n        x-name: testListBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testLong:\n    post:\n      operationId: testLong\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testLongBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testLongBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testLongBody\"\n        x-name: testLongBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testMap:\n    post:\n      operationId: testMap\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testMapBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testMapBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testMapBody\"\n        x-name: testMapBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testMapList:\n    post:\n      operationId: testMapList\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testMapListBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testMapListBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testMapListBody\"\n        x-name: testMapListBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testMultiParam:\n    post:\n      operationId: testMultiParam\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testMultiParamBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testMultiParamBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testMultiParamBody\"\n        x-name: testMultiParamBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: string\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  type: string\n            text/plain:\n              schema:\n                type: array\n                items:\n                  type: string\n  /testObject:\n    post:\n      operationId: testObject\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        x-name: user\n      responses:\n        \"200\":\n          description: response of 200\n  /testOneEnum:\n    post:\n      operationId: testOneEnum\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testOneEnumBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testOneEnumBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testOneEnumBody\"\n        x-name: testOneEnumBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testOptional:\n    post:\n      operationId: testOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testResponseHeader:\n    post:\n      operationId: testResponseHeader\n      responses:\n        \"200\":\n          description: response of 200\n          headers:\n            h:\n              schema:\n                type: string\n                description: \"\"\n                nullable: false\n                example: \"\"\n  /testSet:\n    post:\n      operationId: testSet\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testSetBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testSetBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testSetBody\"\n        x-name: testSetBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testShort:\n    post:\n      operationId: testShort\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testShortBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testShortBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testShortBody\"\n        x-name: testShortBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testString:\n    post:\n      operationId: testString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testStringBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testStringBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testStringBody\"\n        x-name: testStringBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testboolean:\n    post:\n      operationId: testboolean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testbooleanBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testbooleanBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testbooleanBody\"\n        x-name: testbooleanBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testbyte:\n    post:\n      operationId: testbyte\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testbyteBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testbyteBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testbyteBody\"\n        x-name: testbyteBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testbytes:\n    post:\n      operationId: testbytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testbytesBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testbytesBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testbytesBody\"\n        x-name: testbytesBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testchar:\n    post:\n      operationId: testchar\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testcharBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testcharBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testcharBody\"\n        x-name: testcharBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testdouble:\n    post:\n      operationId: testdouble\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testdoubleBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testdoubleBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testdoubleBody\"\n        x-name: testdoubleBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testfloat:\n    post:\n      operationId: testfloat\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testfloatBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testfloatBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testfloatBody\"\n        x-name: testfloatBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testint:\n    post:\n      operationId: testint\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testintBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testintBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testintBody\"\n        x-name: testintBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testlong:\n    post:\n      operationId: testlong\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testlongBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testlongBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testlongBody\"\n        x-name: testlongBody\n      responses:\n        \"200\":\n          description: response of 200\n  /testshort:\n    post:\n      operationId: testshort\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testshortBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testshortBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testshortBody\"\n        x-name: testshortBody\n      responses:\n        \"200\":\n          description: response of 200\n  /wrapToBodyWithDesc:\n    post:\n      operationId: wrapToBodyWithDesc\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/wrapToBodyWithDescBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/wrapToBodyWithDescBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/wrapToBodyWithDescBody\"\n        x-name: wrapToBodyWithDescBody\n      responses:\n        \"200\":\n          description: response of 200\ncomponents:\n  schemas:\n    ignoreRequestBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    nestedListStringBody:\n      type: object\n      properties:\n        param:\n          type: array\n          items:\n            type: array\n            items:\n              type: string\n    AllType:\n      type: object\n      properties:\n        list:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      x-java-class: org.apache.servicecomb.swagger.generator.core.schema.AllType\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      x-java-class: org.apache.servicecomb.foundation.test.scaffolding.model.User\n    testArrayBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n    testBooleanBody:\n      type: object\n      properties:\n        value:\n          type: boolean\n    testByteBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testBytesBody:\n      type: object\n      properties:\n        value:\n          type: string\n          format: byte\n    testCharBody:\n      type: object\n      properties:\n        value:\n          type: string\n    testDoubleBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: double\n    testEnumBody:\n      type: object\n      properties:\n        color:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n        color1:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n    testFloatBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: float\n    testIntegerBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testListBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n    testLongBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int64\n    testMapBody:\n      type: object\n      properties:\n        value:\n          type: object\n          additionalProperties:\n            $ref: \"#/components/schemas/User\"\n    testMapListBody:\n      type: object\n      properties:\n        value:\n          type: object\n          additionalProperties:\n            type: array\n            items:\n              $ref: \"#/components/schemas/User\"\n    testMultiParamBody:\n      type: object\n      properties:\n        obj:\n          $ref: \"#/components/schemas/AllType\"\n        bValue:\n          type: boolean\n        byteValue:\n          type: integer\n          format: int32\n        sValue:\n          type: integer\n          format: int32\n        iValue:\n          type: integer\n          format: int32\n        lValue:\n          type: integer\n          format: int64\n        fValue:\n          type: number\n          format: float\n        dValue:\n          type: number\n          format: double\n        enumValue:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n        cValue:\n          type: string\n        bytes:\n          type: string\n          format: byte\n        strValue:\n          type: string\n        strArray:\n          type: array\n          items:\n            type: string\n        set:\n          uniqueItems: true\n          type: array\n          items:\n            type: string\n        list:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n        map:\n          type: object\n          additionalProperties:\n            $ref: \"#/components/schemas/User\"\n    testOneEnumBody:\n      type: object\n      properties:\n        color:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n    testSetBody:\n      type: object\n      properties:\n        value:\n          uniqueItems: true\n          type: array\n          items:\n            type: string\n    testShortBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testStringBody:\n      type: object\n      properties:\n        value:\n          type: string\n    testbooleanBody:\n      type: object\n      properties:\n        value:\n          type: boolean\n    testbyteBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testbytesBody:\n      type: object\n      properties:\n        value:\n          type: string\n          format: byte\n    testcharBody:\n      type: object\n      properties:\n        value:\n          type: string\n    testdoubleBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: double\n    testfloatBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: float\n    testintBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testlongBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int64\n    testshortBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    wrapToBodyWithDescBody:\n      type: object\n      properties:\n        desc:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/allMethod.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /ignoreRequest:\n    post:\n      operationId: ignoreRequest\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ignoreRequestBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /nestedListString:\n    post:\n      operationId: nestedListString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/nestedListStringBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n  /part:\n    post:\n      operationId: part\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: string\n              format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /partArray:\n    post:\n      operationId: partArray\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: array\n              items:\n                type: string\n                format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /partList:\n    post:\n      operationId: partList\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: array\n              items:\n                type: string\n                format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testAllType:\n    post:\n      operationId: testAllType\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testApiOperation:\n    post:\n      operationId: testApiOperation\n      responses:\n        default:\n          description: response of default\n          headers:\n            h:\n              description: \"\"\n              schema:\n                type: string\n                description: \"\"\n                format: \"\"\n          content: {}\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testApiResponse:\n    post:\n      operationId: testApiResponse\n      responses:\n        \"200\":\n          description: response of 200\n          headers:\n            h:\n              description: \"\"\n              schema:\n                type: string\n                description: \"\"\n                format: \"\"\n          content:\n            application/json: {}\n  /testArray:\n    post:\n      operationId: testArray\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testArrayBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testBoolean:\n    post:\n      operationId: testBoolean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testBooleanBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testByte:\n    post:\n      operationId: testByte\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testByteBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testBytes:\n    post:\n      operationId: testBytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testBytesBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testChar:\n    post:\n      operationId: testChar\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testCharBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testCompletableFuture:\n    post:\n      operationId: testCompletableFuture\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /testCompletableFutureOptional:\n    post:\n      operationId: testCompletableFutureOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /testDate:\n    post:\n      operationId: testDate\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n                format: date-time\n  /testDouble:\n    post:\n      operationId: testDouble\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testDoubleBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testEnum:\n    post:\n      operationId: testEnum\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testEnumBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testFloat:\n    post:\n      operationId: testFloat\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testFloatBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testInteger:\n    post:\n      operationId: testInteger\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testIntegerBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testList:\n    post:\n      operationId: testList\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testListBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testLong:\n    post:\n      operationId: testLong\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testLongBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testMap:\n    post:\n      operationId: testMap\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMapBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testMapList:\n    post:\n      operationId: testMapList\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMapListBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testMultiParam:\n    post:\n      operationId: testMultiParam\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMultiParamBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: string\n  /testObject:\n    post:\n      operationId: testObject\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testOneEnum:\n    post:\n      operationId: testOneEnum\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testOneEnumBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testOptional:\n    post:\n      operationId: testOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /testResponseHeader:\n    post:\n      operationId: testResponseHeader\n      responses:\n        default:\n          description: response of default\n          headers:\n            h:\n              description: \"\"\n              schema:\n                type: string\n                description: \"\"\n                format: \"\"\n          content: {}\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testSet:\n    post:\n      operationId: testSet\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testSetBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testShort:\n    post:\n      operationId: testShort\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testShortBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testString:\n    post:\n      operationId: testString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testStringBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testboolean:\n    post:\n      operationId: testboolean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testbooleanBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testbyte:\n    post:\n      operationId: testbyte\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testbyteBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testbytes:\n    post:\n      operationId: testbytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testbytesBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testchar:\n    post:\n      operationId: testchar\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testcharBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testdouble:\n    post:\n      operationId: testdouble\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testdoubleBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testfloat:\n    post:\n      operationId: testfloat\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testfloatBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testint:\n    post:\n      operationId: testint\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testintBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testlong:\n    post:\n      operationId: testlong\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testlongBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /testshort:\n    post:\n      operationId: testshort\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testshortBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n  /wrapToBodyWithDesc:\n    post:\n      operationId: wrapToBodyWithDesc\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/wrapToBodyWithDescBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    ignoreRequestBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    nestedListStringBody:\n      type: object\n      properties:\n        param:\n          type: array\n          items:\n            type: array\n            items:\n              type: string\n    AllType:\n      type: object\n      properties:\n        list:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    testArrayBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n    testBooleanBody:\n      type: object\n      properties:\n        value:\n          type: boolean\n    testByteBody:\n      type: object\n      properties:\n        value:\n          type: string\n          format: byte\n    testBytesBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n            format: byte\n    testCharBody:\n      type: object\n      properties:\n        value:\n          type: string\n    testDoubleBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: double\n    testEnumBody:\n      type: object\n      properties:\n        color:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n        color1:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n    testFloatBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: float\n    testIntegerBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testListBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    testLongBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int64\n    testMapBody:\n      type: object\n      properties:\n        value:\n          type: object\n          additionalProperties:\n            $ref: '#/components/schemas/User'\n    testMapListBody:\n      type: object\n      properties:\n        value:\n          type: object\n          additionalProperties:\n            type: array\n            items:\n              $ref: '#/components/schemas/User'\n    testMultiParamBody:\n      type: object\n      properties:\n        obj:\n          $ref: '#/components/schemas/AllType'\n        bValue:\n          type: boolean\n        byteValue:\n          type: string\n          format: byte\n        sValue:\n          type: integer\n          format: int32\n        iValue:\n          type: integer\n          format: int32\n        lValue:\n          type: integer\n          format: int64\n        fValue:\n          type: number\n          format: float\n        dValue:\n          type: number\n          format: double\n        enumValue:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n        cValue:\n          type: string\n        bytes:\n          type: array\n          items:\n            type: string\n            format: byte\n        strValue:\n          type: string\n        strArray:\n          type: array\n          items:\n            type: string\n        set:\n          uniqueItems: true\n          type: array\n          items:\n            type: string\n        list:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n        map:\n          type: object\n          additionalProperties:\n            $ref: '#/components/schemas/User'\n    testOneEnumBody:\n      type: object\n      properties:\n        color:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n    testSetBody:\n      type: object\n      properties:\n        value:\n          uniqueItems: true\n          type: array\n          items:\n            type: string\n    testShortBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testStringBody:\n      type: object\n      properties:\n        value:\n          type: string\n    testbooleanBody:\n      type: object\n      properties:\n        value:\n          type: boolean\n    testbyteBody:\n      type: object\n      properties:\n        value:\n          type: string\n          format: byte\n    testbytesBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n            format: byte\n    testcharBody:\n      type: object\n      properties:\n        value:\n          type: string\n    testdoubleBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: double\n    testfloatBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: float\n    testintBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    testlongBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int64\n    testshortBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n    wrapToBodyWithDescBody:\n      type: object\n      properties:\n        desc:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/allType.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testAllType:\n    post:\n      operationId: testAllType\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    AllType:\n      type: object\n      properties:\n        list:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/apiOperation.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testApiOperation:\n    post:\n      operationId: testApiOperation\n      responses:\n        default:\n          description: response of default\n          headers:\n            h:\n              description: \"\"\n              schema:\n                type: string\n                description: \"\"\n                format: \"\"\n          content: {}\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/apiResponse.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testApiResponse:\n    post:\n      operationId: testApiResponse\n      responses:\n        \"200\":\n          description: response of 200\n          headers:\n            h:\n              description: \"\"\n              schema:\n                type: string\n                description: \"\"\n                format: \"\"\n          content:\n            application/json: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/array.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testArray:\n    post:\n      operationId: testArray\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testArrayBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testArrayBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/boolean.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testboolean:\n    post:\n      operationId: testboolean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testbooleanBody'\n        x-name: name\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testbooleanBody:\n      type: object\n      properties:\n        value:\n          type: boolean\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/booleanObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testBoolean:\n    post:\n      operationId: testBoolean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testBooleanBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testBooleanBody:\n      type: object\n      properties:\n        value:\n          type: boolean\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/byte.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testbyte:\n    post:\n      operationId: testbyte\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testbyteBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testbyteBody:\n      type: object\n      properties:\n        value:\n          type: string\n          format: byte\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/byteObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testByte:\n    post:\n      operationId: testByte\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testByteBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testByteBody:\n      type: object\n      properties:\n        value:\n          type: string\n          format: byte\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/bytes.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testbytes:\n    post:\n      operationId: testbytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testbytesBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testbytesBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n            format: byte\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/bytesObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testBytes:\n    post:\n      operationId: testBytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testBytesBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testBytesBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            type: string\n            format: byte\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/char.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testchar:\n    post:\n      operationId: testchar\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testcharBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testcharBody:\n      type: object\n      properties:\n        value:\n          type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/charObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testChar:\n    post:\n      operationId: testChar\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testCharBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testCharBody:\n      type: object\n      properties:\n        value:\n          type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/completableFuture.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testCompletableFuture:\n    post:\n      operationId: testCompletableFuture\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/date.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testDate:\n    post:\n      operationId: testDate\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n                format: date-time\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/double.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testdouble:\n    post:\n      operationId: testdouble\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testdoubleBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testdoubleBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: double\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/doubleObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testDouble:\n    post:\n      operationId: testDouble\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testDoubleBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testDoubleBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: double\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/enum.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testEnum:\n    post:\n      operationId: testEnum\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testEnumBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testEnumBody:\n      type: object\n      properties:\n        color:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n        color1:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/float.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testfloat:\n    post:\n      operationId: testfloat\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testfloatBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testfloatBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: float\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/floatObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testFloat:\n    post:\n      operationId: testFloat\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testFloatBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testFloatBody:\n      type: object\n      properties:\n        value:\n          type: number\n          format: float\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/ignoreRequest.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /ignoreRequest:\n    post:\n      operationId: ignoreRequest\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ignoreRequestBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    ignoreRequestBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/int.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testint:\n    post:\n      operationId: testint\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testintBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testintBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/intObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testInteger:\n    post:\n      operationId: testInteger\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testIntegerBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testIntegerBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/list.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testList:\n    post:\n      operationId: testList\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testListBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    testListBody:\n      type: object\n      properties:\n        value:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/long.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testlong:\n    post:\n      operationId: testlong\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testlongBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testlongBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int64\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/longObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testLong:\n    post:\n      operationId: testLong\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testLongBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testLongBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int64\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/map.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testMap:\n    post:\n      operationId: testMap\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMapBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    testMapBody:\n      type: object\n      properties:\n        value:\n          type: object\n          additionalProperties:\n            $ref: '#/components/schemas/User'\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/mapList.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testMapList:\n    post:\n      operationId: testMapList\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMapListBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    testMapListBody:\n      type: object\n      properties:\n        value:\n          type: object\n          additionalProperties:\n            type: array\n            items:\n              $ref: '#/components/schemas/User'\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/multiParam.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testMultiParam:\n    post:\n      operationId: testMultiParam\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMultiParamBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: string\ncomponents:\n  schemas:\n    AllType:\n      type: object\n      properties:\n        list:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n    testMultiParamBody:\n      type: object\n      properties:\n        obj:\n          $ref: '#/components/schemas/AllType'\n        bValue:\n          type: boolean\n        byteValue:\n          type: string\n          format: byte\n        sValue:\n          type: integer\n          format: int32\n        iValue:\n          type: integer\n          format: int32\n        lValue:\n          type: integer\n          format: int64\n        fValue:\n          type: number\n          format: float\n        dValue:\n          type: number\n          format: double\n        enumValue:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n        cValue:\n          type: string\n        bytes:\n          type: array\n          items:\n            type: string\n            format: byte\n        strValue:\n          type: string\n        strArray:\n          type: array\n          items:\n            type: string\n        set:\n          uniqueItems: true\n          type: array\n          items:\n            type: string\n        list:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n        map:\n          type: object\n          additionalProperties:\n            $ref: '#/components/schemas/User'\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/nestedListString.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /nestedListString:\n    post:\n      operationId: nestedListString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/nestedListStringBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\ncomponents:\n  schemas:\n    nestedListStringBody:\n      type: object\n      properties:\n        param:\n          type: array\n          items:\n            type: array\n            items:\n              type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/object.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testObject:\n    post:\n      operationId: testObject\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: '#/components/schemas/User'\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/oneEnum.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testOneEnum:\n    post:\n      operationId: testOneEnum\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testOneEnumBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testOneEnumBody:\n      type: object\n      properties:\n        color:\n          type: string\n          enum:\n          - RED\n          - YELLOW\n          - BLUE\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/part.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /part:\n    post:\n      operationId: part\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: string\n              format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/partArray.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /partArray:\n    post:\n      operationId: partArray\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: array\n              items:\n                type: string\n                format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/partList.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /partList:\n    post:\n      operationId: partList\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: array\n              items:\n                type: string\n                format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/pojoExample1.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.pojo.PojoExample1\n  version: 1.0.0\nservers:\n- url: /PojoExample1\npaths:\n  /testMultiParameter:\n    post:\n      operationId: testMultiParameter\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/testMultiParameterBody\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/testMultiParameterBody\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/testMultiParameterBody\"\n        x-name: testMultiParameterBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/XXX\"\n            application/protobuf:\n              schema:\n                $ref: \"#/components/schemas/XXX\"\n            text/plain:\n              schema:\n                $ref: \"#/components/schemas/XXX\"\n  /testOneParameter:\n    post:\n      operationId: testOneParameter\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/XXX\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/XXX\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/XXX\"\n        x-name: testType1\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/XXX\"\n            application/protobuf:\n              schema:\n                $ref: \"#/components/schemas/XXX\"\n            text/plain:\n              schema:\n                $ref: \"#/components/schemas/XXX\"\ncomponents:\n  schemas:\n    XXX:\n      type: object\n      properties:\n        val1:\n          type: integer\n          format: int32\n      x-java-class: org.apache.servicecomb.swagger.generator.core.pojo.TestType1\n    testMultiParameterBody:\n      type: object\n      properties:\n        testType1:\n          $ref: \"#/components/schemas/XXX\"\n        testString:\n          type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/responseHeader.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testResponseHeader:\n    post:\n      operationId: testResponseHeader\n      responses:\n        default:\n          description: response of default\n          headers:\n            h:\n              description: \"\"\n              schema:\n                type: string\n                description: \"\"\n                format: \"\"\n          content: {}\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/set.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testSet:\n    post:\n      operationId: testSet\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testSetBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testSetBody:\n      type: object\n      properties:\n        value:\n          uniqueItems: true\n          type: array\n          items:\n            type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/short.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testshort:\n    post:\n      operationId: testshort\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testshortBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testshortBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/shortObject.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testShort:\n    post:\n      operationId: testShort\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testShortBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testShortBody:\n      type: object\n      properties:\n        value:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/string.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testString:\n    post:\n      operationId: testString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testStringBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    testStringBody:\n      type: object\n      properties:\n        value:\n          type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/testCompletableFutureOptional.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testCompletableFutureOptional:\n    post:\n      operationId: testCompletableFutureOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/testOptional.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /testOptional:\n    post:\n      operationId: testOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/schemas/wrapToBodyWithDesc.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.core.schema.Schema\n  version: 1.0.0\nservers:\n- url: /Schema\npaths:\n  /wrapToBodyWithDesc:\n    post:\n      operationId: wrapToBodyWithDesc\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/wrapToBodyWithDescBody'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json: {}\ncomponents:\n  schemas:\n    wrapToBodyWithDescBody:\n      type: object\n      properties:\n        desc:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/swagger1.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nswagger: '2.0'\ninfo:\n  title: rest test\n  version: 1.0.0\nbasePath: /springmvc/controller\nproduces:\n  - application/json\n\npaths:\n  /sayhello:\n    post:\n      operationId: sayHello\n      parameters:\n        - name: name\n          in: body\n          required: true\n          type: string\n      responses:\n        \"200\":\n          description: say hello\n          schema:\n            type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-core/src/test/resources/swagger2.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nswagger: '2.0'\ninfo:\n  title: rest test\n  version: 1.0.0\nbasePath: /springmvc/controller\nproduces:\n  - application/json\n\npaths:\n  /sayhello:\n    post:\n      operationId: sayHello\n      parameters:\n        - name: name\n          in: body\n          required: true\n          schema:\n            type: string\n      responses:\n        \"200\":\n          description: say hello\n          schema:\n            type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-generator</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-generator-jaxrs</artifactId>\n  <name>Java Chassis::Swagger::Generator::Jaxrs</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/JaxrsOperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.apache.servicecomb.swagger.generator.rest.RestOperationGenerator;\n\nimport jakarta.ws.rs.BeanParam;\n\npublic class JaxrsOperationGenerator extends RestOperationGenerator {\n  public JaxrsOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, Method method) {\n    super(swaggerGenerator, method);\n  }\n\n  @Override\n  protected void initMethodParameterGenerators(Map<String, List<Annotation>> methodAnnotationMap) {\n    super.initMethodParameterGenerators(methodAnnotationMap);\n\n    parameterGenerators.stream()\n        .filter(pg -> pg.getHttpParameterType() == null)\n        .forEach(pg -> pg.setHttpParameterType(HttpParameterType.BODY));\n  }\n\n  @Override\n  protected boolean isAggregatedParameter(ParameterGenerator parameterGenerator, Parameter methodParameter) {\n    return methodParameter.getAnnotation(BeanParam.class) != null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/JaxrsSwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\n\nimport jakarta.ws.rs.HttpMethod;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.rest.RestSwaggerGenerator;\n\npublic class JaxrsSwaggerGenerator extends RestSwaggerGenerator {\n  public JaxrsSwaggerGenerator(Class<?> cls) {\n    super(cls);\n  }\n\n  @Override\n  protected boolean isSkipMethod(Method method) {\n    if (super.isSkipMethod(method)) {\n      return true;\n    }\n\n    for (Annotation annotation : method.getAnnotations()) {\n      HttpMethod httpMethod = annotation.annotationType().getAnnotation(HttpMethod.class);\n      if (httpMethod != null) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public <T extends OperationGenerator> T createOperationGenerator(Method method) {\n    return (T) new JaxrsOperationGenerator(this, method);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/JaxrsSwaggerGeneratorFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGeneratorFactory;\n\npublic class JaxrsSwaggerGeneratorFactory implements SwaggerGeneratorFactory {\n  private static final int ORDER = 2000;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canProcess(Class<?> cls) {\n    return SwaggerUtils.hasAnnotation(cls, Path.class);\n  }\n\n  @Override\n  public SwaggerGenerator create(Class<?> cls) {\n    return new JaxrsSwaggerGenerator(cls);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.Consumes;\n\npublic class ConsumesClassAnnotationProcessor extends JaxrsClassAnnotationProcessor<Consumes> {\n  @Override\n  public Type getProcessType() {\n    return Consumes.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, Consumes consumes) {\n    if (consumes.value() != null && consumes.value().length > 0) {\n      swaggerGenerator.getSwaggerGeneratorContext().updateConsumes(Arrays.asList(consumes.value()));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.Consumes;\n\npublic class ConsumesMethodAnnotationProcessor extends JaxrsMethodAnnotationProcessor<Consumes> {\n  @Override\n  public Type getProcessType() {\n    return Consumes.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, Consumes consumes) {\n    if (consumes.value() != null && consumes.value().length > 0) {\n      operationGenerator.getOperationGeneratorContext().updateConsumes(Arrays.asList(consumes.value()));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/CookieParamParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport jakarta.ws.rs.CookieParam;\n\npublic class CookieParamParameterAnnotationProcessor extends\n    JaxrsParameterAnnotationProcessor<CookieParam> {\n  @Override\n  public Type getProcessType() {\n    return CookieParam.class;\n  }\n\n  @Override\n  public String getParameterName(CookieParam annotation) {\n    if (StringUtils.isEmpty(annotation.value())) {\n      return null;\n    }\n    return annotation.value();\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, CookieParam annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.COOKIE);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/DeleteMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.DELETE;\n\npublic class DeleteMethodAnnotationProcessor extends GetMethodAnnotationProcessor {\n  @Override\n  public Type getProcessType() {\n    return DELETE.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/FormParamParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport jakarta.ws.rs.FormParam;\n\npublic class FormParamParameterAnnotationProcessor extends JaxrsParameterAnnotationProcessor<FormParam> {\n  @Override\n  public Type getProcessType() {\n    return FormParam.class;\n  }\n\n  @Override\n  public String getParameterName(FormParam annotation) {\n    if (StringUtils.isNotEmpty(annotation.value())) {\n      return annotation.value();\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, FormParam annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.FORM);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/GetMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HttpMethod;\n\npublic class GetMethodAnnotationProcessor extends JaxrsMethodAnnotationProcessor<Annotation> {\n  @Override\n  public Type getProcessType() {\n    return GET.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, Annotation annotation) {\n    HttpMethod httpMethod = annotation.annotationType().getAnnotation(HttpMethod.class);\n\n    operationGenerator.setHttpMethod(httpMethod.value());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/HeaderParamParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport jakarta.ws.rs.HeaderParam;\n\npublic class HeaderParamParameterAnnotationProcessor extends\n    JaxrsParameterAnnotationProcessor<HeaderParam> {\n  @Override\n  public Type getProcessType() {\n    return HeaderParam.class;\n  }\n\n  @Override\n  public String getParameterName(HeaderParam annotation) {\n    if (StringUtils.isNotEmpty(annotation.value())) {\n      return annotation.value();\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, HeaderParam annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.HEADER);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/JaxrsClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;\n\n/**\n * A generic class to help classify implementations.\n */\npublic abstract class JaxrsClassAnnotationProcessor<ANNOTATION>\n    implements ClassAnnotationProcessor<ANNOTATION> {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/JaxrsMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\n\n/**\n * A generic class to help classify implementations.\n */\npublic abstract class JaxrsMethodAnnotationProcessor<ANNOTATION>\n    implements MethodAnnotationProcessor<ANNOTATION> {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/JaxrsParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor;\n\n/**\n * A generic class to help classify implementations.\n */\npublic abstract class JaxrsParameterAnnotationProcessor<ANNOTATION> implements\n    ParameterAnnotationProcessor<ANNOTATION> {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/PatchMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.PATCH;\n\npublic class PatchMethodAnnotationProcessor extends GetMethodAnnotationProcessor {\n  @Override\n  public Type getProcessType() {\n    return PATCH.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/PathClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.Path;\n\npublic class PathClassAnnotationProcessor extends JaxrsClassAnnotationProcessor<Path> {\n  @Override\n  public Type getProcessType() {\n    return Path.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, Path path) {\n    swaggerGenerator.setBasePath(path.value());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/PathMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.Path;\n\npublic class PathMethodAnnotationProcessor extends JaxrsMethodAnnotationProcessor<Path> {\n  @Override\n  public Type getProcessType() {\n    return Path.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, Path path) {\n    operationGenerator.setPath(path.value());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/PathParamParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport jakarta.ws.rs.PathParam;\n\npublic class PathParamParameterAnnotationProcessor extends JaxrsParameterAnnotationProcessor<PathParam> {\n  @Override\n  public Type getProcessType() {\n    return PathParam.class;\n  }\n\n  @Override\n  public String getParameterName(PathParam annotation) {\n    if (StringUtils.isNotEmpty(annotation.value())) {\n      return annotation.value();\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, PathParam annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.PATH);\n    parameterGenerator.getParameterGeneratorContext().setRequired(true);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/PostMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.POST;\n\npublic class PostMethodAnnotationProcessor extends GetMethodAnnotationProcessor {\n  @Override\n  public Type getProcessType() {\n    return POST.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.Produces;\n\npublic class ProducesClassAnnotationProcessor extends JaxrsClassAnnotationProcessor<Produces> {\n  @Override\n  public Type getProcessType() {\n    return Produces.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, Produces produces) {\n    if (produces.value() != null && produces.value().length > 0) {\n      swaggerGenerator.getSwaggerGeneratorContext().updateProduces(Arrays.asList(produces.value()));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\n\nimport jakarta.ws.rs.Produces;\n\npublic class ProducesMethodAnnotationProcessor extends JaxrsMethodAnnotationProcessor<Produces> {\n  @Override\n  public Type getProcessType() {\n    return Produces.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, Produces produces) {\n    if (produces.value() != null && produces.value().length > 0) {\n      operationGenerator.getOperationGeneratorContext().updateProduces(Arrays.asList(produces.value()));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/PutMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.PUT;\n\npublic class PutMethodAnnotationProcessor extends GetMethodAnnotationProcessor {\n  @Override\n  public Type getProcessType() {\n    return PUT.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/QueryParamParameterAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\n\nimport jakarta.ws.rs.QueryParam;\n\npublic class QueryParamParameterAnnotationProcessor extends JaxrsParameterAnnotationProcessor<QueryParam> {\n  @Override\n  public Type getProcessType() {\n    return QueryParam.class;\n  }\n\n  @Override\n  public String getParameterName(QueryParam annotation) {\n    if (StringUtils.isNotEmpty(annotation.value())) {\n      return annotation.value();\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, QueryParam annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.QUERY);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/response/JaxrsResponseProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.processor.response;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.processor.response.DefaultResponseTypeProcessor;\n\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport io.swagger.v3.oas.models.responses.ApiResponses;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response;\n\npublic class JaxrsResponseProcessor extends DefaultResponseTypeProcessor {\n  @Override\n  public Class<?> getProcessType() {\n    return Response.class;\n  }\n\n  @Override\n  public Type extractResponseType(Type genericResponseType) {\n    return null;\n  }\n\n  @Override\n  public Type extractResponseType(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      Type genericResponseType) {\n    ApiResponses responses = operationGenerator.getOperation().getResponses();\n    if (responses != null) {\n      ApiResponse response = responses.get(SwaggerConst.SUCCESS_KEY);\n      if (response != null && response.getContent() != null) {\n        if (response.getContent().get(MediaType.TEXT_PLAIN) != null) {\n          return String.class;\n        }\n      }\n    }\n\n    throw new IllegalStateException(\"Use ApiOperation or ApiResponses to declare response type\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.PathClassAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.ConsumesClassAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.ProducesClassAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.ConsumesMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.ProducesMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.PathMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.GetMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.PostMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.PutMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.DeleteMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.PatchMethodAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.PathParamParameterAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.QueryParamParameterAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.HeaderParamParameterAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.CookieParamParameterAnnotationProcessor\norg.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.FormParamParameterAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ResponseTypeProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.jaxrs.processor.response.JaxrsResponseProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerGeneratorFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.jaxrs.JaxrsSwaggerGeneratorFactory\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/ClassAnnotation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.Consumes;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\n@Path(\"/class\")\n@Consumes(value = {MediaType.APPLICATION_JSON})\n@Produces(value = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})\n@SuppressWarnings(\"unused\")\npublic class ClassAnnotation {\n  @Path(value = \"testBean\")\n  @POST\n  public User testBean(User user) {\n    return null;\n  }\n\n  @Path(value = \"testString\")\n  @POST\n  public String testString(String user) {\n    return null;\n  }\n\n  // This case should cause error. Must implicitly specify consumes.\n  // For JAX RS, @FormParam can be url-encoded-form or multipart.\n  @Path(value = \"testFormWrong\")\n  @POST\n  public String testFormWrong(@FormParam(\"param\") int param) {\n    return null;\n  }\n\n  // This case should cause error. Must implicitly specify consumes\n  // For JAX RS, @FormParam can be url-encoded-form or multipart.\n  @Path(value = \"testUploadWrong\")\n  @POST\n  public String testUploadWrong(@FormParam(\"part\") Part part) {\n    return null;\n  }\n\n  @Path(value = \"testForm\")\n  @POST\n  @Consumes(value = MediaType.APPLICATION_FORM_URLENCODED)\n  public String testForm(@FormParam(\"param\") int param) {\n    return null;\n  }\n\n  @Path(value = \"testUpload\")\n  @POST\n  @Consumes(value = MediaType.MULTIPART_FORM_DATA)\n  public String testUpload(@FormParam(\"part\") Part part) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/ClassMethodNoPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\n@Path(\"\")\npublic class ClassMethodNoPath {\n  @GET\n  public void p1() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.AggregatedParam;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamComplexField;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamComplexSetter;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamDefaultBody;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamWithJsonIgnoredTagged;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamWithPart;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatus;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatusBeanParam;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatusModel;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatus;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusBeanParam;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusModel;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport jakarta.ws.rs.BeanParam;\nimport jakarta.ws.rs.CookieParam;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.PATCH;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.Response;\n\n@Path(value = \"Echo\")\npublic class Echo {\n  @PATCH\n  public void patch() {\n\n  }\n\n  @POST\n  @ApiResponse(content = {\n      @Content(schema = @Schema(implementation = Integer.class))}, responseCode = \"200\", description = \"\")\n  @Path(\"response\")\n  public Response response() {\n    return null;\n  }\n\n  @POST\n  @Operation(summary = \"\")\n  @Path(\"emptyPath\")\n  public void emptyPath() {\n\n  }\n\n  @Path(value = \"echo/{targetName}\")\n  @POST\n  public String echo(User srcUser, @HeaderParam(value = \"header\") String header,\n      @PathParam(value = \"targetName\") String targetName,\n      @QueryParam(value = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @Path(value = \"cookie\")\n  @POST\n  public String cookie(@CookieParam(value = \"cookie\") String cookie) {\n    return String.format(\"%s\", cookie);\n  }\n\n  @Path(value = \"form\")\n  @POST\n  public String form(@FormParam(value = \"form\") String form) {\n    return String.format(\"%s\", form);\n  }\n\n  @Path(value = \"query\")\n  @GET\n  public String query(@QueryParam(value = \"query\") String query) {\n    return String.format(\"%s\", query);\n  }\n\n  @Path(value = \"queryComplex\")\n  @GET\n  public String queryComplex(@QueryParam(value = \"queries\") List<User> queries) {\n    return String.format(\"%s\", queries);\n  }\n\n  @Operation(summary = \"\")\n  public void ignoredNonRestful() {\n\n  }\n\n  @Path(value = \"testRawJson\")\n  @POST\n  public void rawJsonStringMethod(@RawJsonRequestBody String jsonInput) {\n  }\n\n  @Path(value = \"enumBody\")\n  @POST\n  public void enumBody(Color color) {\n  }\n\n  @Path(\"aggregatedParam\")\n  @POST\n  public void aggregatedParam(@BeanParam AggregatedParam aggregatedParam) {\n\n  }\n\n  @Path(\"beanParamWithPart\")\n  @POST\n  public void beanParamWithPart(@BeanParam BeanParamWithPart beanParamWithPart) {\n\n  }\n\n  @Path(\"beanParamComplexField\")\n  @POST\n  public void beanParamComplexField(@BeanParam BeanParamComplexField beanParamComplexField) {\n\n  }\n\n  @Path(\"beanParamComplexSetter\")\n  @POST\n  public void beanParamComplexSetter(@BeanParam BeanParamComplexSetter beanParamComplexSetter) {\n\n  }\n\n  @Path(\"beanParamDefaultBody\")\n  @POST\n  public void beanParamDefaultBody(@BeanParam BeanParamDefaultBody beanParamDefaultBody) {\n\n  }\n\n  @Path(\"beanParamWithJsonIgnoredTaggedBody\")\n  @POST\n  public void beanParamWithJsonIgnoredTagged(@BeanParam BeanParamWithJsonIgnoredTagged beanParamWithJsonIgnoredTagged) {\n\n  }\n\n  @Path(\"nestedListString\")\n  @POST\n  public List<List<String>> nestedListString(List<List<String>> param) {\n    return param;\n  }\n\n  @Path(\"/dynamicStatusEnum\")\n  @POST\n  public DynamicStatus dynamicStatusEnum(@BeanParam DynamicStatusBeanParam statusBeanParam,\n      @QueryParam(\"status\") @Parameter(description = \"dynamic desc direct\") DynamicStatus status,\n      DynamicStatusModel model) {\n    return null;\n  }\n\n  @Path(\"/jdkStatusEnum\")\n  @POST\n  public JdkStatus jdkStatusEnum(@BeanParam JdkStatusBeanParam statusBeanParam,\n      @QueryParam(\"status\") @Parameter(description = \"jdk desc direct\") JdkStatus status,\n      JdkStatusModel model) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/FullSwaggerService.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.List;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.enums.Explode;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.enums.ParameterStyle;\nimport jakarta.servlet.http.Part;\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\nimport jakarta.ws.rs.DefaultValue;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.MediaType;\n\n@Path(value = \"/FullSwaggerService\")\npublic class FullSwaggerService {\n  @Path(\"/fileUpload\")\n  @POST\n  @Produces(MediaType.TEXT_PLAIN)\n  public String fileUpload(@FormParam(\"file1\") Part file1, @FormParam(\"file2\") Part file2) throws IOException {\n    return null;\n  }\n\n  @Path(\"/queryListMULTI\")\n  @GET\n  public String queryListMULTI(\n      @Parameter(name = \"queryList\", in = ParameterIn.QUERY, style = ParameterStyle.FORM, explode = Explode.TRUE)\n      @QueryParam(\"queryList\") List<String> queryList) {\n    return queryList == null ? \"null\" : queryList.size() + \":\" + queryList;\n  }\n\n  @Path(\"/defaultValue\")\n  @GET\n  public String defaultValue(@QueryParam(\"e\") int e, @DefaultValue(\"20\") @QueryParam(\"a\") int a,\n      @DefaultValue(\"bobo\") @QueryParam(\"b\") String b,\n      @DefaultValue(\"40\") @QueryParam(\"c\") Integer c, @Min(value = 20) @Max(value = 30) @QueryParam(\"d\") int d) {\n    return \"Hello \" + a + b + c + d + e;\n  }\n\n  @Path(\"/textPlain\")\n  @GET\n  @Produces(MediaType.TEXT_PLAIN)\n  public String textPlain() {\n    return null;\n  }\n\n  @Path(\"/fileDownload\")\n  @GET\n  public File fileDownload() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/MultiDefaultPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\n@Path(\"/abc\")\npublic class MultiDefaultPath {\n  @GET\n  public void p1() {\n\n  }\n\n  @GET\n  public void p2() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/TestClassAnnotation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.junit.jupiter.api.Test;\n\npublic class TestClassAnnotation {\n  @Test\n  public void test_generate_swagger_correct() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/ClassAnnotation.yaml\", ClassAnnotation.class,\n        \"testBean\", \"testString\", \"testForm\", \"testUpload\");\n  }\n\n  @Test\n  public void test_form_wrong() {\n    UnitTestSwaggerUtils.testException(\"Generate swagger operation failed, \"\n            + \"method=ClassAnnotation:testFormWrong, cause=Consumes not provided for FORM parameter, \"\n            + \"or is empty by annotations rule.\",\n        ClassAnnotation.class,\n        \"testFormWrong\");\n  }\n\n  @Test\n  public void test_upload_wrong() {\n    UnitTestSwaggerUtils.testException(\"Generate swagger operation failed, \"\n            + \"method=ClassAnnotation:testUploadWrong, \"\n            + \"cause=Part type must declare consumes multipart/form-data\",\n        ClassAnnotation.class,\n        \"testUploadWrong\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/TestJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.jaxrs;\n\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.jaxrs.model.ConsumesAndProduces;\nimport org.junit.jupiter.api.Test;\n\npublic class TestJaxrs {\n  @Test\n  public void testMultiDefaultPath() {\n    UnitTestSwaggerUtils.testException(\n        \"Duplicate operation path detected. method=org.apache.servicecomb.swagger.generator.jaxrs.MultiDefaultPath:p2.\",\n        MultiDefaultPath.class);\n  }\n\n  @Test\n  public void testEcho() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/echo.yaml\", Echo.class);\n  }\n\n\n  @Test\n  public void testClassMethodNoPath() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, \"\n            + \"method=ClassMethodNoPath:p1, cause=Path must not both be empty in class and method\",\n        ClassMethodNoPath.class);\n  }\n\n  @Test\n  public void testFullSwaggerService() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/FullSwaggerService.yaml\", FullSwaggerService.class);\n  }\n\n  @Test\n  public void consumesAndProduces_exception_testSingleMediaType() {\n    UnitTestSwaggerUtils.testException(\"Generate swagger operation failed, \"\n            + \"method=ConsumesAndProduces:testSingleMediaType, \"\n            + \"cause=Not support media type application/xml\",\n        ConsumesAndProduces.class, \"testSingleMediaType\");\n  }\n\n  @Test\n  public void consumesAndProduces_exception_testMultipleMediaType() {\n    UnitTestSwaggerUtils.testException(\"Generate swagger operation failed, \"\n            + \"method=ConsumesAndProduces:testMultipleMediaType, \"\n            + \"cause=Not support media type application/xml\",\n        ConsumesAndProduces.class, \"testMultipleMediaType\");\n  }\n\n  @Test\n  public void consumesAndProduces_exception_testBlankMediaType() {\n    UnitTestSwaggerUtils.testException(\"Generate swagger operation failed, \"\n            + \"method=ConsumesAndProduces:testBlankMediaType, cause=Not support media type \",\n        ConsumesAndProduces.class, \"testBlankMediaType\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/AggregatedParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\nimport java.util.List;\n\nimport jakarta.ws.rs.CookieParam;\nimport jakarta.ws.rs.DefaultValue;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.QueryParam;\n\npublic class AggregatedParam {\n  @DefaultValue(\"pa\")\n  @PathParam(\"path0\")\n  private String strVal;\n\n  @QueryParam(\"query1\")\n  private int intVal;\n\n  private long longVal;\n\n  private long cookieVal;\n\n  @HeaderParam(\"header2\")\n  private String headerVal;\n\n  @QueryParam(\"query-array\")\n  private String[] queryArray;\n\n  @QueryParam(\"query-list\")\n  private List<String> queryList;\n\n  public String getStrVal() {\n    return strVal;\n  }\n\n  public void setStrVal(String strVal) {\n    this.strVal = strVal;\n  }\n\n  public int getIntVal() {\n    return intVal;\n  }\n\n  public void setIntVal(int intVal) {\n    this.intVal = intVal;\n  }\n\n  public long getLongVal() {\n    return longVal;\n  }\n\n  @DefaultValue(\"12\")\n  @FormParam(\"form3\")\n  public void setLongVal(long longVal) {\n    this.longVal = longVal;\n  }\n\n  public long getCookieVal() {\n    return cookieVal;\n  }\n\n  @CookieParam(\"cookie4\")\n  public void setCookieVal(long cookieVal) {\n    this.cookieVal = cookieVal;\n  }\n\n  public String getHeaderVal() {\n    return headerVal;\n  }\n\n  public void setHeaderVal(String headerVal) {\n    this.headerVal = headerVal;\n  }\n\n  public String[] getQueryArray() {\n    return queryArray;\n  }\n\n  public AggregatedParam setQueryArray(String[] queryArray) {\n    this.queryArray = queryArray;\n    return this;\n  }\n\n  public List<String> getQueryList() {\n    return queryList;\n  }\n\n  public AggregatedParam setQueryList(List<String> queryList) {\n    this.queryList = queryList;\n    return this;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/BeanParamComplexField.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\nimport jakarta.ws.rs.QueryParam;\n\npublic class BeanParamComplexField {\n  @QueryParam(\"q\")\n  private AggregatedParam complex;\n\n  public AggregatedParam getComplex() {\n    return complex;\n  }\n\n  public void setComplex(AggregatedParam complex) {\n    this.complex = complex;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/BeanParamComplexSetter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\nimport jakarta.ws.rs.HeaderParam;\n\npublic class BeanParamComplexSetter {\n  private AggregatedParam complex;\n\n  public AggregatedParam getComplex() {\n    return complex;\n  }\n\n  @HeaderParam(\"h\")\n  public void setComplex(AggregatedParam complex) {\n    this.complex = complex;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/BeanParamDefaultBody.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\npublic class BeanParamDefaultBody {\n  private String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/BeanParamInvalidDefaultBody.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\npublic class BeanParamInvalidDefaultBody {\n  private String name;\n\n  private int age;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/BeanParamWithJsonIgnoredTagged.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\nimport jakarta.ws.rs.QueryParam;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\npublic class BeanParamWithJsonIgnoredTagged {\n  @QueryParam(\"name\")\n  private String name;\n\n  @JsonIgnore\n  private AggregatedParam ignored;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public AggregatedParam getIgnored() {\n    return ignored;\n  }\n\n  public void setIgnored(\n      AggregatedParam ignored) {\n    this.ignored = ignored;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/BeanParamWithPart.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.QueryParam;\n\npublic class BeanParamWithPart {\n  @QueryParam(\"queryStr\")\n  private boolean queryStr;\n\n  @FormParam(\"up0\")\n  private Part up0;\n\n  private Part up1;\n\n  public boolean isQueryStr() {\n    return queryStr;\n  }\n\n  public void setQueryStr(boolean queryStr) {\n    this.queryStr = queryStr;\n  }\n\n  public Part getUp0() {\n    return up0;\n  }\n\n  public void setUp0(Part up0) {\n    this.up0 = up0;\n  }\n\n  public Part getUp1() {\n    return up1;\n  }\n\n  @FormParam(\"up1\")\n  public void setUp1(Part up1) {\n    this.up1 = up1;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/ConsumesAndProduces.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model;\n\nimport jakarta.ws.rs.Consumes;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class ConsumesAndProduces {\n  @Consumes(MediaType.APPLICATION_JSON)\n  @Produces(MediaType.APPLICATION_XML)\n  public String testSingleMediaType(String input) {\n    return input;\n  }\n\n  @Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})\n  @Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML})\n  public String testMultipleMediaType(String input) {\n    return input;\n  }\n\n  @Consumes(\"\")\n  @Produces(\"\")\n  public String testBlankMediaType(String input) {\n    return input;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model.enums;\n\nimport org.apache.servicecomb.foundation.common.base.DynamicEnum;\nimport org.apache.servicecomb.foundation.common.base.DynamicEnumCache;\n\nimport com.fasterxml.jackson.annotation.JsonCreator;\n\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic class DynamicStatus extends DynamicEnum<Integer> {\n  @Parameter(description = \"dynamic bad request\")\n  public static final DynamicStatus BAD_REQUEST = new DynamicStatus(400);\n\n  @Parameter(description = \"dynamic not found\")\n  public static final DynamicStatus NOT_FOUND = new DynamicStatus(404);\n\n  private static final DynamicEnumCache<DynamicStatus> CACHE = new DynamicEnumCache<>(DynamicStatus.class);\n\n  public DynamicStatus(Integer value) {\n    super(value);\n  }\n\n  @JsonCreator\n  public static DynamicStatus fromValue(int value) {\n    return CACHE.fromValue(value);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusBeanParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model.enums;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport jakarta.ws.rs.QueryParam;\n\npublic class DynamicStatusBeanParam {\n  @Parameter(description = \"dynamic desc aggr\")\n  @QueryParam(\"status-aggr\")\n  public DynamicStatus queryStatus;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model.enums;\n\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic class DynamicStatusModel {\n  @Parameter(description = \"dynamic status model\")\n  public DynamicStatus status;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model.enums;\n\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic enum JdkStatus {\n  @Parameter(description = \"jdk bad request\")\n  BAD_REQUEST,\n\n  @Parameter(description = \"jdk not found\")\n  NOT_FOUND\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusBeanParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model.enums;\n\nimport io.swagger.v3.oas.annotations.Parameter;\nimport jakarta.ws.rs.QueryParam;\n\npublic class JdkStatusBeanParam {\n  @Parameter(description = \"jdk desc aggr\")\n  @QueryParam(\"status-aggr\")\n  public JdkStatus queryStatus;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.jaxrs.model.enums;\n\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic class JdkStatusModel {\n  @Parameter(description = \"jdk status model\")\n  public JdkStatus status;\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/ClassAnnotation.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.ClassAnnotation\n  version: 1.0.0\nservers:\n- url: /class\npaths:\n  /testBean:\n    post:\n      operationId: testBean\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        x-name: user\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                $ref: \"#/components/schemas/User\"\n  /testForm:\n    post:\n      operationId: testForm\n      requestBody:\n        content:\n          application/x-www-form-urlencoded:\n            schema:\n              type: object\n              properties:\n                param:\n                  type: integer\n                  format: int32\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testString:\n    post:\n      operationId: testString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n        x-name: user\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testUpload:\n    post:\n      operationId: testUpload\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      x-java-class: org.apache.servicecomb.foundation.test.scaffolding.model.User\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/FullSwaggerService.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.FullSwaggerService\n  version: 1.0.0\nservers:\n- url: /FullSwaggerService\npaths:\n  /defaultValue:\n    get:\n      operationId: defaultValue\n      parameters:\n      - name: e\n        in: query\n        schema:\n          type: integer\n          format: int32\n      - name: a\n        in: query\n        schema:\n          type: integer\n          format: int32\n          default: 20\n      - name: b\n        in: query\n        schema:\n          type: string\n          default: bobo\n      - name: c\n        in: query\n        schema:\n          type: integer\n          format: int32\n          default: 40\n      - name: d\n        in: query\n        schema:\n          maximum: 30\n          minimum: 20\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /fileDownload:\n    get:\n      operationId: fileDownload\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            '*/*':\n              schema:\n                type: string\n                format: binary\n  /fileUpload:\n    post:\n      operationId: fileUpload\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                file1:\n                  type: string\n                  format: binary\n                file2:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n  /queryListMULTI:\n    get:\n      operationId: queryListMULTI\n      parameters:\n      - name: queryList\n        in: query\n        required: false\n        style: form\n        explode: true\n        schema:\n          type: array\n          items:\n            type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /textPlain:\n    get:\n      operationId: textPlain\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/aggregatedParam.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /aggregatedParam:\n    post:\n      operationId: \"aggregatedParam\"\n      parameters:\n      - name: \"path0\"\n        in: \"path\"\n        required: true\n        type: \"string\"\n        default: \"pa\"\n      - name: \"query1\"\n        in: \"query\"\n        required: false\n        type: \"integer\"\n        default: 0\n        format: \"int32\"\n      - name: \"form3\"\n        in: \"formData\"\n        required: false\n        type: \"integer\"\n        default: 12\n        format: \"int64\"\n      - name: \"cookie4\"\n        in: \"cookie\"\n        required: false\n        type: \"integer\"\n        default: 0\n        format: \"int64\"\n      - name: \"header2\"\n        in: \"header\"\n        required: false\n        type: \"string\"\n      - name: \"query-array\"\n        in: \"query\"\n        required: false\n        type: \"array\"\n        items:\n          type: \"string\"\n        collectionFormat: \"multi\"\n      - name: \"query-list\"\n        in: \"query\"\n        required: false\n        type: \"array\"\n        items:\n          type: \"string\"\n        collectionFormat: \"multi\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/beanParamDefaultBody.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /beanParamDefaultBody:\n    post:\n      operationId: \"beanParamDefaultBody\"\n      parameters:\n      - in: \"body\"\n        name: \"name\"\n        required: false\n        schema:\n          type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/beanParamWithJsonIgnoredTagged.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /beanParamWithJsonIgnoredTaggedBody:\n    post:\n      operationId: \"beanParamWithJsonIgnoredTagged\"\n      parameters:\n      - name: \"name\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/beanParamWithPart.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /beanParamWithPart:\n    post:\n      operationId: \"beanParamWithPart\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"queryStr\"\n        in: \"query\"\n        required: false\n        type: \"boolean\"\n        default: false\n      - name: \"up0\"\n        in: \"formData\"\n        required: false\n        type: \"file\"\n      - name: \"up1\"\n        in: \"formData\"\n        required: false\n        type: \"file\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/consumes.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.model.ConsumesAndProduces\n  version: 1.0.0\nservers:\n- url: /ConsumesAndProduces\npaths:\n  /testBlankMediaType:\n    post:\n      operationId: testBlankMediaType\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testBlankMediaTypeBody'\n        x-name: testBlankMediaTypeBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /testMultipleMediaType:\n    post:\n      operationId: testMultipleMediaType\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testMultipleMediaTypeBody'\n        x-name: testMultipleMediaTypeBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /testSingleMediaType:\n    post:\n      operationId: testSingleMediaType\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/testSingleMediaTypeBody'\n        x-name: testSingleMediaTypeBody\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas:\n    testBlankMediaTypeBody:\n      type: object\n      properties:\n        input:\n          type: string\n    testMultipleMediaTypeBody:\n      type: object\n      properties:\n        input:\n          type: string\n    testSingleMediaTypeBody:\n      type: object\n      properties:\n        input:\n          type: string\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/cookie.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /cookie:\n    post:\n      operationId: \"cookie\"\n      parameters:\n      - name: \"cookie\"\n        in: \"cookie\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/dynamicStatusEnum.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\n  version: 1.0.0\nservers:\n- url: Echo\npaths:\n  /dynamicStatusEnum:\n    post:\n      operationId: dynamicStatusEnum\n      parameters:\n      - name: status-aggr\n        in: query\n        description: |\n          dynamic desc aggr\n          - 400: dynamic bad request\n          - 404: dynamic not found\n      - name: status\n        in: query\n        description: |\n          dynamic desc direct\n          - 400: dynamic bad request\n          - 404: dynamic not found\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/DynamicStatusModel'\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: integer\n                description: |\n                  - 400: dynamic bad request\n                  - 404: dynamic not found\n                format: int32\ncomponents:\n  schemas:\n    DynamicStatusModel:\n      type: object\n      properties:\n        status:\n          type: integer\n          format: int32\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/echo.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\n  version: 1.0.0\nservers:\n- url: Echo\npaths:\n  /aggregatedParam:\n    post:\n      operationId: aggregatedParam\n      parameters:\n      - name: path0\n        in: path\n        required: true\n        schema:\n          type: string\n          default: pa\n      - name: query1\n        in: query\n        schema:\n          type: integer\n          format: int32\n      - name: cookie4\n        in: cookie\n        schema:\n          type: integer\n          format: int64\n      - name: header2\n        in: header\n        schema:\n          type: string\n      - name: query-array\n        in: query\n        schema:\n          type: array\n          items:\n            type: string\n      - name: query-list\n        in: query\n        schema:\n          type: array\n          items:\n            type: string\n      requestBody:\n        content:\n          application/x-www-form-urlencoded:\n            schema:\n              type: object\n              properties:\n                form3:\n                  type: integer\n                  format: int64\n      responses:\n        \"200\":\n          description: response of 200\n  /beanParamComplexField:\n    post:\n      operationId: beanParamComplexField\n      parameters:\n      - name: q\n        in: query\n        schema:\n          $ref: \"#/components/schemas/AggregatedParam\"\n      responses:\n        \"200\":\n          description: response of 200\n  /beanParamComplexSetter:\n    post:\n      operationId: beanParamComplexSetter\n      parameters:\n      - name: h\n        in: header\n        schema:\n          $ref: \"#/components/schemas/AggregatedParam\"\n      responses:\n        \"200\":\n          description: response of 200\n  /beanParamDefaultBody:\n    post:\n      operationId: beanParamDefaultBody\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n          application/protobuf:\n            schema:\n              type: string\n          text/plain:\n            schema:\n              type: string\n        x-name: name\n      responses:\n        \"200\":\n          description: response of 200\n  /beanParamWithJsonIgnoredTaggedBody:\n    post:\n      operationId: beanParamWithJsonIgnoredTagged\n      parameters:\n      - name: name\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n  /beanParamWithPart:\n    post:\n      operationId: beanParamWithPart\n      parameters:\n      - name: queryStr\n        in: query\n        schema:\n          type: boolean\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                up0:\n                  type: string\n                  format: binary\n                up1:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /cookie:\n    post:\n      operationId: cookie\n      parameters:\n      - name: cookie\n        in: cookie\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /dynamicStatusEnum:\n    post:\n      operationId: dynamicStatusEnum\n      parameters:\n      - name: status-aggr\n        in: query\n        description: dynamic desc aggr\n        required: false\n        schema:\n          type: integer\n          format: int32\n      - name: status\n        in: query\n        description: dynamic desc direct\n        required: false\n        schema:\n          type: integer\n          format: int32\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/DynamicStatusModel\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/DynamicStatusModel\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/DynamicStatusModel\"\n        x-name: model\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: integer\n                format: int32\n            application/protobuf:\n              schema:\n                type: integer\n                format: int32\n            text/plain:\n              schema:\n                type: integer\n                format: int32\n  /echo/{targetName}:\n    post:\n      operationId: echo\n      parameters:\n      - name: header\n        in: header\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        schema:\n          type: string\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /emptyPath:\n    post:\n      operationId: emptyPath\n      responses:\n        \"200\":\n          description: response of 200\n  /enumBody:\n    post:\n      operationId: enumBody\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n              enum:\n              - RED\n              - YELLOW\n              - BLUE\n          application/protobuf:\n            schema:\n              type: string\n              enum:\n              - RED\n              - YELLOW\n              - BLUE\n          text/plain:\n            schema:\n              type: string\n              enum:\n              - RED\n              - YELLOW\n              - BLUE\n        x-name: color\n      responses:\n        \"200\":\n          description: response of 200\n  /form:\n    post:\n      operationId: form\n      requestBody:\n        content:\n          application/x-www-form-urlencoded:\n            schema:\n              type: object\n              properties:\n                form:\n                  type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /jdkStatusEnum:\n    post:\n      operationId: jdkStatusEnum\n      parameters:\n      - name: status-aggr\n        in: query\n        description: jdk desc aggr\n        required: false\n        schema:\n          type: string\n          enum:\n          - BAD_REQUEST\n          - NOT_FOUND\n      - name: status\n        in: query\n        description: jdk desc direct\n        required: false\n        schema:\n          type: string\n          enum:\n          - BAD_REQUEST\n          - NOT_FOUND\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/JdkStatusModel\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/JdkStatusModel\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/JdkStatusModel\"\n        x-name: model\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n                enum:\n                - BAD_REQUEST\n                - NOT_FOUND\n            application/protobuf:\n              schema:\n                type: string\n                enum:\n                - BAD_REQUEST\n                - NOT_FOUND\n            text/plain:\n              schema:\n                type: string\n                enum:\n                - BAD_REQUEST\n                - NOT_FOUND\n  /nestedListString:\n    post:\n      operationId: nestedListString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: array\n              items:\n                type: array\n                items:\n                  type: string\n          application/protobuf:\n            schema:\n              type: array\n              items:\n                type: array\n                items:\n                  type: string\n          text/plain:\n            schema:\n              type: array\n              items:\n                type: array\n                items:\n                  type: string\n        x-name: param\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n            text/plain:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n  /:\n    patch:\n      operationId: patch\n      responses:\n        \"200\":\n          description: response of 200\n  /query:\n    get:\n      operationId: query\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /queryComplex:\n    get:\n      operationId: queryComplex\n      parameters:\n      - name: queries\n        in: query\n        schema:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testRawJson:\n    post:\n      operationId: rawJsonStringMethod\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n          text/plain:\n            schema:\n              type: string\n        required: true\n        x-raw-json: true\n        x-name: jsonInput\n      responses:\n        \"200\":\n          description: response of 200\n  /response:\n    post:\n      operationId: response\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: integer\n                format: int32\n            application/protobuf:\n              schema:\n                type: integer\n                format: int32\n            text/plain:\n              schema:\n                type: integer\n                format: int32\ncomponents:\n  schemas:\n    AggregatedParam:\n      type: object\n      properties:\n        strVal:\n          type: string\n        intVal:\n          type: integer\n          format: int32\n        longVal:\n          type: integer\n          format: int64\n        cookieVal:\n          type: integer\n          format: int64\n        headerVal:\n          type: string\n        queryArray:\n          type: array\n          items:\n            type: string\n        queryList:\n          type: array\n          items:\n            type: string\n      x-java-class: org.apache.servicecomb.swagger.generator.jaxrs.model.AggregatedParam\n    DynamicStatusModel:\n      type: object\n      properties:\n        status:\n          type: integer\n          format: int32\n      x-java-class: org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatusModel\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      x-java-class: org.apache.servicecomb.foundation.test.scaffolding.model.User\n    JdkStatusModel:\n      type: object\n      properties:\n        status:\n          type: string\n          enum:\n          - BAD_REQUEST\n          - NOT_FOUND\n      x-java-class: org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusModel\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/emptyContract.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/emptyPath.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    post:\n      operationId: \"emptyPath\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/enumBody.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /enumBody:\n    post:\n      operationId: \"enumBody\"\n      parameters:\n      - in: \"body\"\n        name: \"color\"\n        required: false\n        schema:\n          type: \"string\"\n          enum:\n          - \"RED\"\n          - \"YELLOW\"\n          - \"BLUE\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/form.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /form:\n    post:\n      operationId: \"form\"\n      parameters:\n      - name: \"form\"\n        in: \"formData\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/jdkStatusEnum.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /jdkStatusEnum:\n    post:\n      operationId: \"jdkStatusEnum\"\n      parameters:\n      - name: \"status-aggr\"\n        in: \"query\"\n        description: \"jdk desc aggr\\n- BAD_REQUEST: jdk bad request\\n- NOT_FOUND:\\\n          \\ jdk not found\\n\"\n        required: false\n        type: \"string\"\n        enum:\n        - \"BAD_REQUEST\"\n        - \"NOT_FOUND\"\n      - name: \"status\"\n        in: \"query\"\n        description: \"jdk desc direct\\n- BAD_REQUEST: jdk bad request\\n- NOT_FOUND:\\\n          \\ jdk not found\\n\"\n        required: false\n        type: \"string\"\n        enum:\n        - \"BAD_REQUEST\"\n        - \"NOT_FOUND\"\n      - in: \"body\"\n        name: \"model\"\n        required: false\n        schema:\n          $ref: \"#/definitions/JdkStatusModel\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n            description: \"- BAD_REQUEST: jdk bad request\\n- NOT_FOUND: jdk not found\\n\"\n            enum:\n            - \"BAD_REQUEST\"\n            - \"NOT_FOUND\"\n            x-java-class: \"org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatus\"\ndefinitions:\n  JdkStatusModel:\n    type: \"object\"\n    properties:\n      status:\n        type: \"string\"\n        description: \"jdk status model\\n- BAD_REQUEST: jdk bad request\\n- NOT_FOUND:\\\n          \\ jdk not found\\n\"\n        enum:\n        - \"BAD_REQUEST\"\n        - \"NOT_FOUND\"\n    x-java-class: \"org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusModel\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/nestedListString.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\n  version: 1.0.0\nservers:\n- url: Echo\npaths:\n  /nestedListString:\n    post:\n      operationId: nestedListString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: array\n              items:\n                type: array\n                items:\n                  type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\ncomponents:\n  schemas: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/patch.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    patch:\n      operationId: \"patch\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/query.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /query:\n    get:\n      operationId: \"query\"\n      parameters:\n      - name: \"query\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/rawJsonStringMethod.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /testRawJson:\n    post:\n      operationId: \"rawJsonStringMethod\"\n      parameters:\n      - in: \"body\"\n        name: \"jsonInput\"\n        required: true\n        schema:\n          type: \"string\"\n        x-raw-json: true\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/response.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    post:\n      operationId: \"response\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"integer\"\n            format: \"int32\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/responseText.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    get:\n      operationId: \"responseText\"\n      produces:\n      - \"text/plain\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-generator</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>swagger-generator-spring-data</artifactId>\n  <name>Java Chassis::Swagger::Generator::Spring data</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework.data</groupId>\n      <artifactId>spring-data-commons</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/src/main/java/org/apache/servicecomb/swagger/generator/springdata/SpringDataConcreteTypeRegister.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springdata;\n\nimport java.lang.reflect.Type;\nimport java.util.Set;\n\nimport org.apache.servicecomb.swagger.extend.ConcreteTypeRegister;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\n\npublic class SpringDataConcreteTypeRegister implements ConcreteTypeRegister {\n  @Override\n  public void register(Set<Type> types) {\n    types.add(Page.class);\n    types.add(Pageable.class);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/src/main/java/org/apache/servicecomb/swagger/generator/springdata/SpringDataModule.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springdata;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.PageImpl;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.data.domain.Sort.Order;\n\nimport com.fasterxml.jackson.annotation.JsonCreator;\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport com.fasterxml.jackson.annotation.JsonPropertyOrder;\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.annotation.JsonDeserialize;\nimport com.fasterxml.jackson.databind.annotation.JsonSerialize;\nimport com.fasterxml.jackson.databind.module.SimpleModule;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.fasterxml.jackson.databind.util.Converter;\n\npublic class SpringDataModule extends SimpleModule implements SPIOrder {\n  private static final long serialVersionUID = 1L;\n\n  @JsonDeserialize(as = PageImpl.class)\n  @JsonPropertyOrder(alphabetic = true)\n  public static class PageMixin<T> {\n    @JsonCreator\n    public PageMixin(@JsonProperty(value = \"content\") List<T> content,\n        @JsonProperty(\"pageable\") Pageable pageable,\n        @JsonProperty(\"total\") long total) {\n    }\n  }\n\n  @JsonDeserialize(as = PageRequest.class)\n  @JsonPropertyOrder(alphabetic = true)\n  public static class PageableMixin {\n    @JsonCreator\n    public PageableMixin(@JsonProperty(value = \"pageNumber\") int page,\n        @JsonProperty(\"pageSize\") int size, @JsonProperty(value = \"sort\") Sort sort) {\n    }\n  }\n\n  public static class SortConverter implements Converter<SortMixin, Sort> {\n    @Override\n    public Sort convert(SortMixin value) {\n      return Sort.by(value.getProperties());\n    }\n\n    @Override\n    public JavaType getInputType(TypeFactory typeFactory) {\n      return typeFactory.constructType(SortMixin.class);\n    }\n\n    @Override\n    public JavaType getOutputType(TypeFactory typeFactory) {\n      return typeFactory.constructType(Sort.class);\n    }\n  }\n\n  public static class SortMixinConverter implements Converter<Sort, SortMixin> {\n    @Override\n    public SortMixin convert(Sort value) {\n      List<String> properties = new ArrayList<>();\n      for (Order order : value) {\n        properties.add(order.getProperty());\n      }\n      SortMixin result = new SortMixin();\n      result.setProperties(properties.toArray(new String[0]));\n      return result;\n    }\n\n    @Override\n    public JavaType getInputType(TypeFactory typeFactory) {\n      return typeFactory.constructType(Sort.class);\n    }\n\n    @Override\n    public JavaType getOutputType(TypeFactory typeFactory) {\n      return typeFactory.constructType(SortMixin.class);\n    }\n  }\n\n  @JsonPropertyOrder(alphabetic = true)\n  @JsonDeserialize(converter = SortConverter.class)\n  @JsonSerialize(converter = SortMixinConverter.class)\n  public static class SortMixin {\n    private String[] properties;\n\n    @JsonCreator\n    public SortMixin() {\n    }\n\n    public void setProperties(String[] properties) {\n      this.properties = properties;\n    }\n\n    public String[] getProperties() {\n      return this.properties;\n    }\n  }\n\n  public SpringDataModule() {\n    super(\"springData\");\n\n    setMixInAnnotation(Page.class, PageMixin.class);\n    setMixInAnnotation(Pageable.class, PageableMixin.class);\n    setMixInAnnotation(Sort.class, SortMixin.class);\n\n    setMixInAnnotation(PageImpl.class, PageMixin.class);\n    setMixInAnnotation(PageRequest.class, PageableMixin.class);\n  }\n\n  @Override\n  public Object getTypeId() {\n    return getModuleName();\n  }\n\n  @Override\n  public int getOrder() {\n    return Short.MAX_VALUE;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springdata.SpringDataModule\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.extend.ConcreteTypeRegister",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springdata.SpringDataConcreteTypeRegister\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/src/test/java/org/apache/servicecomb/swagger/generator/springdata/TestPageResponseTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springdata;\n\nimport java.io.IOException;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.PageImpl;\nimport org.springframework.data.domain.PageRequest;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.domain.Sort;\nimport org.springframework.data.domain.Sort.Direction;\n\nimport io.swagger.v3.core.util.Json;\n\npublic class TestPageResponseTypeProcessor {\n  interface PageSchema {\n    Page<String> test(Page<String> page);\n  }\n\n  @Test\n  public void swagger() {\n    UnitTestSwaggerUtils.testSwagger(\"pageSchema.yaml\", PageSchema.class);\n  }\n\n  @Test\n  public void deserialize() throws IOException {\n    Json.mapper().registerModule(new SpringDataModule());\n\n    Sort sort = Sort.by(Direction.ASC, \"name\");\n    Pageable pageable = PageRequest.of(1, 10, sort);\n    Page<String> page = new PageImpl<>(Arrays.asList(\"c1\", \"c2\"), pageable, 2);\n    String json = Json.mapper().writeValueAsString(page);\n    Assertions.assertEquals(\n        \"{\\\"content\\\":[\\\"c1\\\",\\\"c2\\\"],\\\"pageable\\\":{\\\"pageNumber\\\":1,\\\"pageSize\\\":10,\\\"sort\\\":{\\\"properties\\\":[\\\"name\\\"]},\\\"offset\\\":10,\\\"paged\\\":true,\\\"unpaged\\\":false},\\\"empty\\\":false,\\\"first\\\":false,\\\"last\\\":true,\\\"number\\\":1,\\\"numberOfElements\\\":2,\\\"size\\\":10,\\\"sort\\\":{\\\"properties\\\":[\\\"name\\\"]},\\\"totalElements\\\":12,\\\"totalPages\\\":2}\",\n        json);\n\n    Page<?> page2 = Json.mapper().readValue(json, Page.class);\n\n    Assertions.assertEquals(json,\n        Json.mapper().writeValueAsString(page2));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-spring-data/src/test/resources/pageSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springdata.TestPageResponseTypeProcessor$PageSchema\n  version: 1.0.0\nservers:\n- url: /PageSchema\npaths:\n  /test:\n    post:\n      operationId: test\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/PageString\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/PageString\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/PageString\"\n        x-name: page\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/PageString\"\n            application/protobuf:\n              schema:\n                $ref: \"#/components/schemas/PageString\"\n            text/plain:\n              schema:\n                $ref: \"#/components/schemas/PageString\"\ncomponents:\n  schemas:\n    PageString:\n      type: object\n      properties:\n        content:\n          type: array\n          items:\n            type: string\n        empty:\n          type: boolean\n        first:\n          type: boolean\n        last:\n          type: boolean\n        number:\n          type: integer\n          format: int32\n        numberOfElements:\n          type: integer\n          format: int32\n        pageable:\n          $ref: \"#/components/schemas/Pageable\"\n        size:\n          type: integer\n          format: int32\n        sort:\n          $ref: \"#/components/schemas/Sort\"\n        totalElements:\n          type: integer\n          format: int64\n        totalPages:\n          type: integer\n          format: int32\n      x-java-class: org.springframework.data.domain.Page<java.lang.String>\n    Pageable:\n      type: object\n      properties:\n        offset:\n          type: integer\n          format: int64\n        pageNumber:\n          type: integer\n          format: int32\n        pageSize:\n          type: integer\n          format: int32\n        paged:\n          type: boolean\n        sort:\n          $ref: \"#/components/schemas/Sort\"\n        unpaged:\n          type: boolean\n      x-java-class: org.springframework.data.domain.Pageable\n    Sort:\n      type: object\n      properties:\n        empty:\n          type: boolean\n        sorted:\n          type: boolean\n        unsorted:\n          type: boolean\n      x-java-class: org.springframework.data.domain.Sort\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-generator</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-generator-springmvc</artifactId>\n  <name>Java Chassis::Swagger::Generator::Spring MVC</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-webmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/SpringmvcOperationGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.apache.servicecomb.swagger.generator.rest.RestOperationGenerator;\nimport org.springframework.web.bind.annotation.RequestBody;\n\npublic class SpringmvcOperationGenerator extends RestOperationGenerator {\n  public SpringmvcOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, Method method) {\n    super(swaggerGenerator, method);\n  }\n\n  @Override\n  protected void initMethodParameterGenerators(Map<String, List<Annotation>> methodAnnotationMap) {\n    super.initMethodParameterGenerators(methodAnnotationMap);\n\n    parameterGenerators.stream()\n        .filter(pg -> pg.getHttpParameterType() == null)\n        .forEach(pg -> pg.setHttpParameterType(HttpParameterType.QUERY));\n  }\n\n  @Override\n  protected boolean isAggregatedParameter(ParameterGenerator parameterGenerator, Parameter methodParameter) {\n    return !isRequestBody(parameterGenerator)\n        && SwaggerUtils.isBean(methodParameter.getParameterizedType());\n  }\n\n  private boolean isRequestBody(ParameterGenerator parameterGenerator) {\n    for (Annotation annotation : parameterGenerator.getAnnotations()) {\n      if (annotation.annotationType() == RequestBody.class) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/SpringmvcSwaggerGenerator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport java.lang.reflect.Method;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.rest.RestSwaggerGenerator;\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\npublic class SpringmvcSwaggerGenerator extends RestSwaggerGenerator {\n  public SpringmvcSwaggerGenerator(Class<?> cls) {\n    super(cls);\n  }\n\n  @Override\n  protected boolean isSkipMethod(Method method) {\n    if (super.isSkipMethod(method)) {\n      return true;\n    }\n\n    return method.getAnnotation(RequestMapping.class) == null &&\n        method.getAnnotation(GetMapping.class) == null &&\n        method.getAnnotation(PutMapping.class) == null &&\n        method.getAnnotation(PostMapping.class) == null &&\n        method.getAnnotation(PatchMapping.class) == null &&\n        method.getAnnotation(DeleteMapping.class) == null;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public <T extends OperationGenerator> T createOperationGenerator(Method method) {\n    return (T) new SpringmvcOperationGenerator(this, method);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/SpringmvcSwaggerGeneratorFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGeneratorFactory;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\npublic class SpringmvcSwaggerGeneratorFactory implements SwaggerGeneratorFactory {\n  private static final int ORDER = 1000;\n\n  @Override\n  public int getOrder() {\n    return ORDER;\n  }\n\n  @Override\n  public boolean canProcess(Class<?> cls) {\n    return SwaggerUtils.hasAnnotation(cls, RequestMapping.class) || SwaggerUtils\n        .hasAnnotation(cls, RestController.class);\n  }\n\n  @Override\n  public SwaggerGenerator create(Class<?> cls) {\n    return new SpringmvcSwaggerGenerator(cls);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n\nabstract class AbstractHttpMethodMappingAnnotationProcessor<ANNOTATION> implements\n    MethodAnnotationProcessor<ANNOTATION> {\n  protected void doProcess(OperationGenerator operationGenerator, String[] paths, String[] pathValues,\n      RequestMethod requestMethod, String[] consumes, String[] produces) {\n    // paths same to pathValues\n    this.processPath(operationGenerator, paths);\n    this.processPath(operationGenerator, pathValues);\n\n    if (requestMethod != null) {\n      operationGenerator.setHttpMethod(requestMethod.name());\n    }\n    if (consumes.length > 0) {\n      operationGenerator.getOperationGeneratorContext().updateConsumes(Arrays.asList(consumes));\n    }\n    if (produces.length > 0) {\n      operationGenerator.getOperationGeneratorContext().updateProduces(Arrays.asList(produces));\n    }\n  }\n\n  protected void processPath(OperationGenerator operationGenerator, String[] paths) {\n    if (null == paths || paths.length == 0) {\n      return;\n    }\n\n    // swagger仅支持配一个path，否则将会出现重复的operationId\n    if (paths.length > 1) {\n      throw new IllegalStateException(\"not allowed multi path.\");\n    }\n\n    operationGenerator.setPath(paths[0]);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/CookieValueAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.CookieValue;\nimport org.springframework.web.bind.annotation.ValueConstants;\n\npublic class CookieValueAnnotationProcessor extends\n    SpringmvcParameterAnnotationsProcessor<CookieValue> {\n  @Override\n  public Type getProcessType() {\n    return CookieValue.class;\n  }\n\n  @Override\n  public String getParameterName(CookieValue annotation) {\n    String value = annotation.value();\n    if (value.isEmpty()) {\n      value = annotation.name();\n    }\n    if (StringUtils.isNotEmpty(value)) {\n      return value;\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, CookieValue annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.COOKIE);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n    if (!ValueConstants.DEFAULT_NONE.equals(annotation.defaultValue())) {\n      parameterGenerator.getParameterGeneratorContext()\n          .setDefaultValue(annotation.defaultValue());\n      // if default value is set, must be required false.\n      parameterGenerator.getParameterGeneratorContext().setRequired(false);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/DeleteMappingMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class DeleteMappingMethodAnnotationProcessor extends\n    AbstractHttpMethodMappingAnnotationProcessor<DeleteMapping> {\n  @Override\n  public Type getProcessType() {\n    return DeleteMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      DeleteMapping deleteMapping) {\n    doProcess(operationGenerator,\n        deleteMapping.path(), deleteMapping.value(),\n        RequestMethod.DELETE,\n        deleteMapping.consumes(), deleteMapping.produces());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/GetMappingMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class GetMappingMethodAnnotationProcessor extends AbstractHttpMethodMappingAnnotationProcessor<GetMapping> {\n  @Override\n  public Type getProcessType() {\n    return GetMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, GetMapping getMapping) {\n    doProcess(operationGenerator,\n        getMapping.path(), getMapping.value(), RequestMethod.GET, getMapping.consumes(), getMapping.produces());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/PatchMappingMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class PatchMappingMethodAnnotationProcessor extends AbstractHttpMethodMappingAnnotationProcessor<PatchMapping> {\n  @Override\n  public Type getProcessType() {\n    return PatchMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      PatchMapping patchMapping) {\n    doProcess(operationGenerator,\n        patchMapping.path(), patchMapping.value(),\n        RequestMethod.PATCH,\n        patchMapping.consumes(), patchMapping.produces());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/PathVariableAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.PathVariable;\n\npublic class PathVariableAnnotationProcessor extends\n    SpringmvcParameterAnnotationsProcessor<PathVariable> {\n  @Override\n  public Type getProcessType() {\n    return PathVariable.class;\n  }\n\n  @Override\n  public String getParameterName(PathVariable annotation) {\n    String value = annotation.value();\n    if (value.isEmpty()) {\n      value = annotation.name();\n    }\n    if (StringUtils.isNotEmpty(value)) {\n      return value;\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, PathVariable annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.PATH);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/PostMappingMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class PostMappingMethodAnnotationProcessor extends AbstractHttpMethodMappingAnnotationProcessor<PostMapping> {\n  @Override\n  public Type getProcessType() {\n    return PostMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      PostMapping postMapping) {\n    doProcess(operationGenerator,\n        postMapping.path(), postMapping.value(), RequestMethod.POST, postMapping.consumes(), postMapping.produces());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/PutMappingMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class PutMappingMethodAnnotationProcessor extends AbstractHttpMethodMappingAnnotationProcessor<PutMapping> {\n  @Override\n  public Type getProcessType() {\n    return PutMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator, PutMapping putMapping) {\n    doProcess(operationGenerator,\n        putMapping.path(), putMapping.value(), RequestMethod.PUT, putMapping.consumes(), putMapping.produces());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestAttributeAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.RequestAttribute;\n\n/**\n * Use RequestAttribute to annotate a Form parameter.\n *\n * NOTICE: In spring-web, RequestAttribute is used to annotate request attribute, and use RequestParam\n * to annotate query param and form param. This is implementation based. We can't use RequestParam to express\n * both query and form in OpenAPI 3.0. And there is no request attribute.\n */\npublic class RequestAttributeAnnotationProcessor extends\n    SpringmvcParameterAnnotationsProcessor<RequestAttribute> {\n  @Override\n  public Type getProcessType() {\n    return RequestAttribute.class;\n  }\n\n  @Override\n  public String getParameterName(RequestAttribute annotation) {\n    String value = annotation.value();\n    if (value.isEmpty()) {\n      value = annotation.name();\n    }\n    if (StringUtils.isNotEmpty(value)) {\n      return value;\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, RequestAttribute annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.FORM);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestBodyAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.RequestBody;\n\npublic class RequestBodyAnnotationProcessor extends\n    SpringmvcParameterAnnotationsProcessor<RequestBody> {\n  @Override\n  public Type getProcessType() {\n    return RequestBody.class;\n  }\n\n  @Override\n  public String getParameterName(RequestBody annotation) {\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, RequestBody annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.BODY);\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestHeaderAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.ValueConstants;\n\npublic class RequestHeaderAnnotationProcessor extends\n    SpringmvcParameterAnnotationsProcessor<RequestHeader> {\n  @Override\n  public Type getProcessType() {\n    return RequestHeader.class;\n  }\n\n  @Override\n  public String getParameterName(RequestHeader annotation) {\n    String value = annotation.value();\n    if (value.isEmpty()) {\n      value = annotation.name();\n    }\n    if (StringUtils.isNotEmpty(value)) {\n      return value;\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, RequestHeader annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.HEADER);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n    if (!ValueConstants.DEFAULT_NONE.equals(annotation.defaultValue())) {\n      parameterGenerator.getParameterGeneratorContext()\n          .setDefaultValue(annotation.defaultValue());\n      // if default value is set, must be required false.\n      parameterGenerator.getParameterGeneratorContext().setRequired(false);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\nimport java.util.Arrays;\n\nimport org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class RequestMappingClassAnnotationProcessor implements ClassAnnotationProcessor<RequestMapping> {\n  @Override\n  public Type getProcessType() {\n    return RequestMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, RequestMapping requestMapping) {\n    this.processMethod(requestMapping.method(), swaggerGenerator);\n\n    // path/value是等同的\n    this.processPath(requestMapping.path(), swaggerGenerator);\n    this.processPath(requestMapping.value(), swaggerGenerator);\n\n    if (requestMapping.consumes().length > 0) {\n      swaggerGenerator.getSwaggerGeneratorContext().updateConsumes(Arrays.asList(requestMapping.consumes()));\n    }\n    if (requestMapping.produces().length > 0) {\n      swaggerGenerator.getSwaggerGeneratorContext().updateProduces(Arrays.asList(requestMapping.produces()));\n    }\n  }\n\n  protected void processPath(String[] paths, SwaggerGenerator swaggerGenerator) {\n    if (null == paths || paths.length == 0) {\n      return;\n    }\n\n    // swagger仅支持配一个basePath\n    if (paths.length > 1) {\n      throw new IllegalStateException(\n          String.format(\"not support multi path, class=%s.\", swaggerGenerator.getClazz().getName()));\n    }\n\n    swaggerGenerator.setBasePath(paths[0]);\n  }\n\n  protected void processMethod(RequestMethod[] requestMethods, SwaggerGenerator swaggerGenerator) {\n    if (null == requestMethods || requestMethods.length == 0) {\n      return;\n    }\n\n    if (requestMethods.length > 1) {\n      throw new IllegalStateException(\n          String.format(\"not support multi http method, class=%s.\", swaggerGenerator.getClazz().getName()));\n    }\n\n    swaggerGenerator.setHttpMethod(requestMethods[0].name());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingMethodAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\npublic class RequestMappingMethodAnnotationProcessor extends\n    AbstractHttpMethodMappingAnnotationProcessor<RequestMapping> {\n  @Override\n  public Type getProcessType() {\n    return RequestMapping.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      RequestMapping requestMapping) {\n    if (requestMapping.method().length > 1) {\n      throw new IllegalStateException(\"not allowed multi http method.\");\n    }\n\n    doProcess(operationGenerator,\n        requestMapping.path(), requestMapping.value(),\n        requestMapping.method().length == 0 ?\n            (StringUtils.isEmpty(operationGenerator.getHttpMethod()) ? RequestMethod.GET : null) :\n            requestMapping.method()[0],\n        requestMapping.consumes(), requestMapping.produces());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestParamParameterProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ValueConstants;\n\n/**\n * Use RequestParam to annotate a Query parameter.\n *\n * NOTICE: In spring-web, RequestParam is used to annotate query param and form param.\n * This is implementation based. We can't use RequestParam to express\n * both query and form in OpenAPI 3.0.\n */\npublic class RequestParamParameterProcessor extends\n    SpringmvcParameterAnnotationsProcessor<RequestParam> {\n  @Override\n  public Type getProcessType() {\n    return RequestParam.class;\n  }\n\n  @Override\n  public String getParameterName(RequestParam annotation) {\n    String value = annotation.value();\n    if (value.isEmpty()) {\n      value = annotation.name();\n    }\n    if (StringUtils.isNotEmpty(value)) {\n      return value;\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, RequestParam annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.QUERY);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n    if (!ValueConstants.DEFAULT_NONE.equals(annotation.defaultValue())) {\n      parameterGenerator.getParameterGeneratorContext()\n          .setDefaultValue(annotation.defaultValue());\n      // if default value is set, must be required false.\n      parameterGenerator.getParameterGeneratorContext().setRequired(false);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.ParameterGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;\nimport org.springframework.web.bind.annotation.RequestPart;\n\npublic class RequestPartAnnotationProcessor extends\n    SpringmvcParameterAnnotationsProcessor<RequestPart> {\n  @Override\n  public Type getProcessType() {\n    return RequestPart.class;\n  }\n\n  @Override\n  public String getParameterName(RequestPart annotation) {\n    String value = annotation.value();\n    if (value.isEmpty()) {\n      value = annotation.name();\n    }\n    if (StringUtils.isNotEmpty(value)) {\n      return value;\n    }\n    return null;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      ParameterGenerator parameterGenerator, RequestPart annotation) {\n    parameterGenerator.setHttpParameterType(HttpParameterType.FORM);\n    if (StringUtils.isNotEmpty(getParameterName(annotation))) {\n      parameterGenerator.getParameterGeneratorContext().setParameterName(getParameterName(annotation));\n    }\n    parameterGenerator.getParameterGeneratorContext().setRequired(annotation.required());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RestControllerClassAnnotationProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.springframework.web.bind.annotation.RestController;\n\npublic class RestControllerClassAnnotationProcessor implements ClassAnnotationProcessor<RestController> {\n  @Override\n  public Type getProcessType() {\n    return RestController.class;\n  }\n\n  @Override\n  public void process(SwaggerGenerator swaggerGenerator, RestController restController) {\n    if (SwaggerUtils.getBasePath(swaggerGenerator.getOpenAPI()) == null) {\n      swaggerGenerator.setBasePath(\"/\");\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/SpringmvcParameterAnnotationsProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor;\n\n/**\n * A generic class to help classify implementations.\n */\npublic abstract class SpringmvcParameterAnnotationsProcessor<ANNOTATION> implements\n    ParameterAnnotationProcessor<ANNOTATION> {\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/MultipartFileArrayProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.parameter;\n\nimport org.apache.servicecomb.swagger.generator.core.processor.parameter.PartArrayParameterTypeProcessor;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\npublic class MultipartFileArrayProcessor extends PartArrayParameterTypeProcessor {\n  @Override\n  public JavaType getProcessType() {\n    return TypeFactory.defaultInstance().constructType(MultipartFile[].class);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/MultipartFileListProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.parameter;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\nimport org.apache.servicecomb.swagger.generator.core.processor.parameter.PartArrayParameterTypeProcessor;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\npublic class MultipartFileListProcessor extends PartArrayParameterTypeProcessor {\n  @Override\n  public JavaType getProcessType() {\n    return TypeFactory.defaultInstance().constructType(\n        ParameterizedTypeUtil.make(List.class, MultipartFile.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/MultipartFileTypeProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.parameter;\n\nimport org.apache.servicecomb.swagger.generator.core.processor.parameter.PartParameterTypeProcessor;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\npublic class MultipartFileTypeProcessor extends PartParameterTypeProcessor {\n  @Override\n  public JavaType getProcessType() {\n    return TypeFactory.defaultInstance().constructType(MultipartFile.class);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/response/ResponseEntityProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.response;\n\nimport org.apache.servicecomb.swagger.generator.core.processor.response.DefaultResponseTypeProcessor;\nimport org.springframework.http.ResponseEntity;\n\npublic class ResponseEntityProcessor extends DefaultResponseTypeProcessor {\n  public ResponseEntityProcessor() {\n    extractActualType = true;\n  }\n\n  @Override\n  public Class<?> getProcessType() {\n    return ResponseEntity.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.property.creator;\n\nimport org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport io.swagger.v3.oas.models.media.FileSchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic class MultipartFilePropertyCreator implements PropertyCreator {\n  private final Class<?>[] classes = {MultipartFile.class};\n\n  @Override\n  public Schema<?> createProperty() {\n    return new FileSchema();\n  }\n\n  @Override\n  public Class<?>[] classes() {\n    return classes;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.property.creator.MultipartFilePropertyCreator\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RestControllerClassAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestMappingClassAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestMappingMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.GetMappingMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.DeleteMappingMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.PostMappingMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.PutMappingMethodAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.PatchMappingMethodAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.CookieValueAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.PathVariableAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestBodyAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestParamParameterProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestHeaderAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestPartAnnotationProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestAttributeAnnotationProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ParameterTypeProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.processor.parameter.MultipartFileTypeProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.parameter.MultipartFileArrayProcessor\norg.apache.servicecomb.swagger.generator.springmvc.processor.parameter.MultipartFileListProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ResponseTypeProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.processor.response.ResponseEntityProcessor\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerGeneratorFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGeneratorFactory\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/ClassMethodNoHttpMethod.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping(path = \"c\")\npublic class ClassMethodNoHttpMethod {\n  @RequestMapping(path = \"m\")\n  public void noHttpMethod() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/ClassMethodNoPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping\npublic class ClassMethodNoPath {\n  @RequestMapping(method = RequestMethod.GET)\n  public void noPath() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/ClassMultiHttpMethod.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(path = \"Echo\", method = {RequestMethod.GET, RequestMethod.POST})\npublic class ClassMultiHttpMethod {\n\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/ClassMultiPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping(path = {\"a\", \"b\"})\npublic class ClassMultiPath {\n\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/Echo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.CookieValue;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RequestMapping(\n    path = \"Echo\",\n    method = {RequestMethod.PUT},\n    consumes = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN},\n    produces = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})\npublic class Echo {\n\n  @RequestMapping(\"emptyPath\")\n  public void emptyPath() {\n  }\n\n  @RequestMapping(\"inheritHttpMethod\")\n  public void inheritHttpMethod(int query) {\n  }\n\n  @RequestMapping(\"cookie\")\n  public void cookie(@CookieValue(value = \"cookie\", required = false) int cookie) {\n  }\n\n  @RequestMapping(\"rawJsonStringMethod\")\n  public void rawJsonStringMethod(@RawJsonRequestBody String jsonInput) {\n  }\n\n  @RequestMapping(\"enumBody\")\n  public void enumBody(@RequestBody Color color) {\n  }\n\n  @RequestMapping(\"asyncResponseEntity\")\n  public CompletableFuture<ResponseEntity<List<String>>> asyncResponseEntity() {\n    return null;\n  }\n\n  @RequestMapping(\"testResponseEntityOptional\")\n  public ResponseEntity<Optional<String>> testResponseEntityOptional() {\n    return null;\n  }\n\n  @RequestMapping(\"testCompletableFutureResponseEntityOptional\")\n  public CompletableFuture<ResponseEntity<Optional<String>>> testCompletableFutureResponseEntityOptional() {\n    return null;\n  }\n\n  @RequestMapping(value = \"part\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public void part(@RequestPart MultipartFile part) {\n\n  }\n\n  @RequestMapping(value = \"partArray\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public void partArray(@RequestPart MultipartFile[] part) {\n\n  }\n\n  @RequestMapping(value = \"partList\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public void partList(@RequestPart List<MultipartFile> part) {\n\n  }\n\n  @RequestMapping(value = \"partAnnotation\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public void partAnnotation(@RequestPart MultipartFile part) {\n\n  }\n\n  @RequestMapping(value = \"partArrayAnnotation\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public void partArrayAnnotation(@RequestPart MultipartFile[] part) {\n\n  }\n\n  @RequestMapping(value = \"partListAnnotation\", consumes = MediaType.MULTIPART_FORM_DATA)\n  public void partListAnnotation(@RequestPart List<MultipartFile> part) {\n\n  }\n\n  @RequestMapping(\"nestedListString\")\n  public List<List<String>> nestedListString(@RequestBody List<List<String>> param) {\n    return param;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/MethodDefaultParameter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(path = \"MethodDefaultParameter\")\npublic class MethodDefaultParameter {\n\n  @RequestMapping(method = RequestMethod.PUT, path = \"usingRequestMapping\")\n  public void usingRequestMapping(int query) {\n  }\n\n  @GetMapping(path = \"usingGetMapping\")\n  public void usingGetMapping(int query) {\n  }\n\n  @PutMapping(path = \"usingPutMapping\")\n  public void usingPutMapping(int query) {\n  }\n\n  @PostMapping(path = \"usingPostMapping\")\n  public void usingPostMapping(int query) {\n  }\n\n  @PatchMapping(path = \"usingPatchMapping\")\n  public void usingPatchMapping(int query) {\n  }\n\n  @DeleteMapping(path = \"usingDeleteMapping\")\n  public void usingDeleteMapping(int query) {\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/MethodEmptyPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\n@RequestMapping(path = \"MethodEmptyPath\")\npublic class MethodEmptyPath {\n\n  @GetMapping\n  public void usingGetMapping() {\n\n  }\n\n  @PostMapping\n  public void usingPostMapping() {\n\n  }\n\n  @PutMapping\n  public void usingPutMapping() {\n\n  }\n\n  @DeleteMapping\n  public void usingDeleteMapping() {\n\n  }\n\n  @PatchMapping\n  public void usingPatchMapping() {\n\n  }\n\n  // this will be ignored in the generation of service contract\n  // as ApiOperation is not a restful annotation\n  @Operation(summary = \"\")\n  public void ignoredNonRestful() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/MethodMixupAnnotations.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport java.time.LocalDateTime;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.springframework.http.MediaType;\nimport org.springframework.web.bind.annotation.CookieValue;\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport io.swagger.v3.oas.annotations.Operation;\nimport io.swagger.v3.oas.annotations.Parameter;\nimport io.swagger.v3.oas.annotations.Parameters;\nimport io.swagger.v3.oas.annotations.enums.ParameterIn;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.validation.constraints.Max;\nimport jakarta.validation.constraints.Min;\n\n@SuppressWarnings(\"unused\")\n@RequestMapping(path = \"MethodMixupAnnotations\")\npublic class MethodMixupAnnotations {\n  @RequestMapping(\n      path = \"usingRequestMapping/{targetName}\",\n      method = {RequestMethod.POST},\n      consumes = {\"text/plain\", \"application/json\"},\n      produces = {\"text/plain\", \"application/json\"})\n  public String usingRequestMapping(@RequestBody User srcUser, @RequestHeader String header,\n      @PathVariable String targetName, @RequestParam(name = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @GetMapping(\n      path = \"usingGetMapping/{targetName}\",\n      consumes = {\"text/plain\", \"application/json\"},\n      produces = {\"text/plain\", \"application/json\"})\n  public String usingGetMapping(@RequestBody User srcUser, @RequestHeader String header,\n      @PathVariable String targetName, @RequestParam(name = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @PutMapping(\n      path = \"usingPutMapping/{targetName}\",\n      consumes = {\"text/plain\", \"application/json\"},\n      produces = {\"text/plain\", \"application/json\"})\n  public String usingPutMapping(@RequestBody User srcUser, @RequestHeader String header,\n      @PathVariable String targetName, @RequestParam(name = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @PostMapping(\n      path = \"usingPostMapping/{targetName}\",\n      consumes = {\"text/plain\", \"application/json\"},\n      produces = {\"text/plain\", \"application/json\"})\n  public String usingPostMapping(@RequestBody User srcUser, @RequestHeader String header,\n      @PathVariable String targetName, @RequestParam(name = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @PatchMapping(\n      path = \"usingPatchMapping/{targetName}\",\n      consumes = {\"text/plain\", \"application/json\"},\n      produces = {\"text/plain\", \"application/json\"})\n  public String usingPatchMapping(@RequestBody User srcUser, @RequestHeader String header,\n      @PathVariable String targetName, @RequestParam(name = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @DeleteMapping(\n      path = \"usingDeleteMapping/{targetName}\",\n      consumes = {\"text/plain\", \"application/json\"},\n      produces = {\"text/plain\", \"application/json\"})\n  public String usingDeleteMapping(@RequestBody User srcUser, @RequestHeader String header,\n      @PathVariable String targetName, @RequestParam(name = \"word\") String word) {\n    return String.format(\"%s %s %s %s\", srcUser.name, header, targetName, word);\n  }\n\n  @PostMapping(path = \"/uploadFileAndAttribute\")\n  public String uploadFileAndAttribute(@RequestPart(name = \"file\") MultipartFile file,\n      @RequestPart(name = \"attribute\") String attribute) {\n    return null;\n  }\n\n  @PostMapping(path = \"/uploadFilesAndAttribute\")\n  public String uploadFilesAndAttribute(@RequestPart(name = \"files\") MultipartFile[] files,\n      @RequestPart(name = \"attribute\") String attribute) {\n    return null;\n  }\n\n  @GetMapping(path = \"/reduce\")\n  @Parameters({@Parameter(name = \"a\", schema = @Schema(implementation = String.class), in = ParameterIn.QUERY)})\n  public int reduce(HttpServletRequest request, @CookieValue(name = \"b\") int b) {\n    return 0;\n  }\n\n  @RequestMapping(path = \"/defaultQueryParam\", method = RequestMethod.POST)\n  public String defaultQueryParam(String prefix, @RequestBody User user) {\n    return null;\n  }\n\n  @GetMapping(path = \"/diffNames\")\n  @Operation(summary = \"differentName\", operationId = \"differentName\")\n  public int diffNames(@RequestParam(\"x\") int a, @RequestParam(\"y\") int b) {\n    return a * 2 + b;\n  }\n\n  @GetMapping(path = \"/bytes\")\n  public byte[] bytes(@RequestBody byte[] value) {\n    return null;\n  }\n\n  @PostMapping(path = \"/upload\", produces = MediaType.TEXT_PLAIN_VALUE)\n  public String fileUpload(@RequestPart(name = \"file1\") MultipartFile file1,\n      @RequestPart(name = \"someFile\") Part file2) {\n    return null;\n  }\n\n  @PostMapping(path = \"/testImplicitForm\")\n  @io.swagger.v3.oas.annotations.parameters.RequestBody(\n      content = {@Content(mediaType = SwaggerConst.FORM_MEDIA_TYPE,\n          schema = @Schema(name = \"form1\", implementation = String.class,\n              nullable = false, description = \"a required form param\")),\n          @Content(mediaType = SwaggerConst.FORM_MEDIA_TYPE,\n              schema = @Schema(name = \"form2\", implementation = String.class,\n                  nullable = true, description = \"an optional form param\"))})\n  public String testImplicitForm(HttpServletRequest request) {\n    return null;\n  }\n\n  @GetMapping(\"/testDefaultValue\")\n  public String testDefaultValue(@RequestParam(name = \"e\", required = false) int e,\n      @RequestHeader(name = \"a\", defaultValue = \"20\") int a,\n      @CookieValue(name = \"b\", defaultValue = \"bobo\") String b,\n      @RequestParam(name = \"c\", defaultValue = \"40\") Integer c,\n      @Min(value = 20) @Max(value = 30) @RequestParam(name = \"d\", required = false) int d) {\n    return \"Hello \" + a + b + c + d + e;\n  }\n\n  @GetMapping(path = \"/testLocalDateTime\")\n  public LocalDateTime testLocalDateTime(@RequestParam(\"date\") LocalDateTime date) {\n    return date;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/MethodMultiPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping\npublic class MethodMultiPath {\n  @RequestMapping(method = RequestMethod.GET, path = {\"a\", \"b\"})\n  public void usingRequestMapping() {\n  }\n\n  @GetMapping(path = {\"a\", \"b\"})\n  public void usingGetMapping() {\n\n  }\n\n  @PutMapping(path = {\"a\", \"b\"})\n  public void usingPutMapping() {\n\n  }\n\n  @PostMapping(path = {\"a\", \"b\"})\n  public void usingPostMapping() {\n\n  }\n\n  @PatchMapping(path = {\"a\", \"b\"})\n  public void usingPatchMapping() {\n\n  }\n\n  @DeleteMapping(path = {\"a\", \"b\"})\n  public void usingDeleteMapping() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/MethodResponseEntity.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.springframework.http.ResponseEntity;\nimport org.springframework.web.bind.annotation.DeleteMapping;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PatchMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.PutMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(path = \"MethodResponseEntity\", method = RequestMethod.POST)\npublic class MethodResponseEntity {\n\n  @RequestMapping(method = RequestMethod.PUT, path = \"usingRequestMapping\")\n  public ResponseEntity<List<User>> usingRequestMapping() {\n    return null;\n  }\n\n  @GetMapping(path = \"usingGetMapping\")\n  public ResponseEntity<List<User>> usingGetMapping() {\n    return null;\n  }\n\n  @PutMapping(path = \"usingPutMapping\")\n  public ResponseEntity<List<User>> usingPutMapping() {\n    return null;\n  }\n\n  @PostMapping(path = \"usingPostMapping\")\n  public ResponseEntity<List<User>> usingPostMapping() {\n    return null;\n  }\n\n  @PatchMapping(path = \"usingPatchMapping\")\n  public ResponseEntity<List<User>> usingPatchMapping() {\n    return null;\n  }\n\n  @DeleteMapping(path = \"usingDeleteMapping\")\n  public ResponseEntity<List<User>> usingDeleteMapping() {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/MultiDefaultPath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(path = \"abc\", method = RequestMethod.POST)\npublic class MultiDefaultPath {\n  @GetMapping\n  public void p1() {\n\n  }\n\n  @RequestMapping(method = RequestMethod.GET)\n  public void p2() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/TestSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.springmvc.model.DefaultParameterSchema;\nimport org.apache.servicecomb.swagger.generator.springmvc.model.RestControllerWithPathSchema;\nimport org.apache.servicecomb.swagger.generator.springmvc.model.SwaggerTestTarget;\nimport org.apache.servicecomb.swagger.generator.springmvc.model.SwaggerTestTarget_ValueOverWritePath;\nimport org.junit.jupiter.api.Test;\n\npublic class TestSpringmvc {\n  @Test\n  public void testMultiDefaultPath() {\n    UnitTestSwaggerUtils.testException(\n        \"Duplicate operation path detected. method=org.apache.servicecomb.swagger.generator.springmvc.MultiDefaultPath:p2.\",\n        MultiDefaultPath.class);\n  }\n\n  @Test\n  public void testResponseEntity() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/responseEntity.yaml\", MethodResponseEntity.class);\n  }\n\n  @Test\n  public void testEcho() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/echo.yaml\", Echo.class);\n  }\n\n  @Test\n  public void testMixupAnnotations() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/mixupAnnotations.yaml\", MethodMixupAnnotations.class);\n  }\n\n  @Test\n  public void testDefaultParameter() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/defaultParameter.yaml\", MethodDefaultParameter.class);\n  }\n\n\n  @Test\n  public void testClassMethodNoPath() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=ClassMethodNoPath:noPath, \"\n            + \"cause=Path must not both be empty in class and method\",\n        ClassMethodNoPath.class,\n        \"noPath\");\n  }\n\n  @Test\n  public void testClassMethodNoHttpMethod() {\n    UnitTestSwaggerUtils\n        .testSwagger(\"schemas/requestMappingHttpMethod.yaml\", ClassMethodNoHttpMethod.class, \"noHttpMethod\");\n  }\n\n\n  @Test\n  public void testClassMultiHttpMethod() {\n    UnitTestSwaggerUtils.testException(\n        \"not support multi http method, class=org.apache.servicecomb.swagger.generator.springmvc.ClassMultiHttpMethod.\",\n        ClassMultiHttpMethod.class);\n  }\n\n  @Test\n  public void testMethodMultiPathUsingRequestMapping() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=MethodMultiPath:usingRequestMapping, cause=not allowed multi path.\",\n        MethodMultiPath.class,\n        \"usingRequestMapping\");\n  }\n\n  @Test\n  public void testMethodMultiPathUsingGetMapping() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=MethodMultiPath:usingGetMapping, cause=not allowed multi path.\",\n        MethodMultiPath.class,\n        \"usingGetMapping\");\n  }\n\n  @Test\n  public void testMethodMultiPathUsingPutMapping() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=MethodMultiPath:usingPutMapping, cause=not allowed multi path.\",\n        MethodMultiPath.class,\n        \"usingPutMapping\");\n  }\n\n  @Test\n  public void testMethodMultiPathUsingPostMapping() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=MethodMultiPath:usingPostMapping, cause=not allowed multi path.\",\n        MethodMultiPath.class,\n        \"usingPostMapping\");\n  }\n\n  @Test\n  public void testMethodMultiPathUsingPatchMapping() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=MethodMultiPath:usingPatchMapping, cause=not allowed multi path.\",\n        MethodMultiPath.class,\n        \"usingPatchMapping\");\n  }\n\n  @Test\n  public void testMethodMultiPathUsingDeleteMapping() {\n    UnitTestSwaggerUtils.testException(\n        \"Generate swagger operation failed, method=MethodMultiPath:usingDeleteMapping, cause=not allowed multi path.\",\n        MethodMultiPath.class,\n        \"usingDeleteMapping\");\n  }\n\n  @Test\n  public void testClassMultiPath() {\n    UnitTestSwaggerUtils.testException(\n        \"not support multi path, class=org.apache.servicecomb.swagger.generator.springmvc.ClassMultiPath.\",\n        ClassMultiPath.class);\n  }\n\n\n  @Test\n  public void testDefaultParameterSchema() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/DefaultParameterSchema.yaml\", DefaultParameterSchema.class);\n  }\n\n  @Test\n  public void testRestControllerWithPathSchema() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/RestControllerWithPathSchema.yaml\", RestControllerWithPathSchema.class);\n  }\n\n  @Test\n  public void swaggerTestTarget() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/swaggerTestTarget.yaml\", SwaggerTestTarget.class);\n  }\n\n  @Test\n  public void swaggerTestTarget_ValueOverWritePath() {\n    UnitTestSwaggerUtils\n        .testSwagger(\"schemas/swaggerTestTarget_ValueOverWritePath.yaml\", SwaggerTestTarget_ValueOverWritePath.class);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/TestTwoSameNameModels.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.springmvc.model.Generic;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class TestTwoSameNameModels {\n  private static final String SCHEMA_CONTENT = \"\"\"\n      openapi: 3.0.1\n      info:\n        title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.TestTwoSameNameModels$TwoSameModelService\n        version: 1.0.0\n      servers:\n      - url: /TwoSameModelService\n      paths:\n        /sameGeneric:\n          post:\n            operationId: genericService\n            requestBody:\n              content:\n                application/json:\n                  schema:\n                    $ref: \"#/components/schemas/GenericSameModel\"\n              required: true\n              x-name: param\n            responses:\n              \"200\":\n                description: response of 200\n                content:\n                  application/json:\n                    schema:\n                      $ref: \"#/components/schemas/GenericSameModel\"\n        /same:\n          post:\n            operationId: service\n            requestBody:\n              content:\n                application/json:\n                  schema:\n                    $ref: \"#/components/schemas/SameModel\"\n              required: true\n              x-name: param\n            responses:\n              \"200\":\n                description: response of 200\n                content:\n                  application/json:\n                    schema:\n                      $ref: \"#/components/schemas/SameModel\"\n      components:\n        schemas:\n          GenericSameModel:\n            type: object\n            properties:\n              data:\n                $ref: \"#/components/schemas/SameModel\"\n            x-java-class: org.apache.servicecomb.swagger.generator.springmvc.model.Generic<org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel>\n          SameModel:\n            type: object\n            properties:\n              name:\n                type: string\n            x-java-class: org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel\n      \"\"\";\n\n  interface TwoSameModelService {\n    @RequestMapping(\n        path = \"/same\",\n        method = {RequestMethod.POST},\n        consumes = {MediaType.APPLICATION_JSON},\n        produces = {MediaType.APPLICATION_JSON})\n    org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel service\n        (@RequestBody org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel param);\n\n    @RequestMapping(\n        path = \"/sameGeneric\",\n        method = {RequestMethod.POST},\n        consumes = {MediaType.APPLICATION_JSON},\n        produces = {MediaType.APPLICATION_JSON})\n    Generic<org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel> genericService\n        (@RequestBody Generic<org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel> param);\n  }\n\n  interface SameModelService {\n    @RequestMapping(\n        path = \"/same\",\n        method = {RequestMethod.POST},\n        consumes = {MediaType.APPLICATION_JSON},\n        produces = {MediaType.APPLICATION_JSON})\n    org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModel service\n        (@RequestBody org.apache.servicecomb.swagger.generator.springmvc.model.same2.SameModel param);\n  }\n\n  interface SameModelThrowService {\n    @RequestMapping(\n        path = \"/same\",\n        method = {RequestMethod.POST},\n        consumes = {MediaType.APPLICATION_JSON},\n        produces = {MediaType.APPLICATION_JSON})\n    org.apache.servicecomb.swagger.generator.springmvc.model.same1.SameModelThrow service\n        (@RequestBody org.apache.servicecomb.swagger.generator.springmvc.model.same2.SameModelThrow param);\n  }\n\n  @Test\n  public void testTwoSameModelWork() {\n    SwaggerGenerator generator = SwaggerGenerator.create(TwoSameModelService.class);\n    OpenAPI openAPI = generator.generate();\n    Assertions.assertEquals(SCHEMA_CONTENT, SwaggerUtils.swaggerToString(openAPI));\n  }\n\n  @Test\n  public void testSameModelThrowThrowException() {\n    SwaggerGenerator generator = SwaggerGenerator.create(SameModelThrowService.class);\n    Assertions.assertThrows(IllegalStateException.class, () -> generator.generate());\n  }\n\n  @Test\n  public void testSameModelThrowException() {\n    SwaggerGenerator generator = SwaggerGenerator.create(SameModelService.class);\n    Assertions.assertThrows(IllegalStateException.class, () -> generator.generate());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/DefaultParameterSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RestController;\n\nimport jakarta.ws.rs.core.MediaType;\n\n@RestController\npublic class DefaultParameterSchema {\n  @GetMapping(\"/testSimpleParam\")\n  public String testSimpleParam(String strParam) {\n    return strParam;\n  }\n\n  @GetMapping(\"/testObjectParam\")\n  public String testObjectParam(TestParam objParam) {\n    return objParam.toString();\n  }\n\n  @GetMapping(\"/testUnsupportedParamType\")\n  public String testUnsupportedParamType(int i, List<TestParam> integerList, Map<String, String> stringMap) {\n    return null;\n  }\n\n  @RequestMapping(path = \"testSingleMediaType\", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)\n  public String testSingleMediaType(String input) {\n    return input;\n  }\n\n  @RequestMapping(path = \"testMultipleMediaType\", method = RequestMethod.PUT, consumes = {MediaType.TEXT_PLAIN,\n      MediaType.APPLICATION_JSON},\n      produces = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})\n  public String testMultipleMediaType(String input) {\n    return input;\n  }\n\n  @RequestMapping(path = \"testBlankMediaType\", method = RequestMethod.POST)\n  public String testBlankMediaType(String input) {\n    return input;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/Generic.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\npublic class Generic <T> {\n  private T data;\n\n  public T getData() {\n    return data;\n  }\n\n  public void setData(T data) {\n    this.data = data;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/RestControllerWithPathSchema.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\n@RestController\n@RequestMapping(\"/prefix\")\npublic class RestControllerWithPathSchema {\n  @GetMapping(\"/testSimpleParam\")\n  public String testSimpleParam(String strParam) {\n    return strParam;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/SwaggerTestTarget.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(path = \"/test\", method = RequestMethod.POST,\n    consumes = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON},\n    produces = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})\npublic class SwaggerTestTarget {\n  @RequestMapping\n  public void method() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/SwaggerTestTarget_ValueOverWritePath.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(value = \"/testValue\", path = \"/testPath\", method = RequestMethod.GET)\npublic class SwaggerTestTarget_ValueOverWritePath {\n  @RequestMapping\n  public void method() {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/TestParam.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\npublic class TestParam {\n  private String name;\n\n  private int age;\n\n  public String getName() {\n    return name;\n  }\n\n  public TestParam setName(String name) {\n    this.name = name;\n    return this;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public TestParam setAge(int age) {\n    this.age = age;\n    return this;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/TestProducer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model;\n\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\n\n@RequestMapping(path = \"/\")\npublic class TestProducer {\n  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_XML, produces = MediaType.APPLICATION_XML)\n  public String testSingleMediaType(String input) {\n    return input;\n  }\n\n  @RequestMapping(method = RequestMethod.PUT, consumes = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON},\n      produces = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})\n  public String testMultipleMediaType(String input) {\n    return input;\n  }\n\n  @RequestMapping(method = RequestMethod.POST, consumes = \"\", produces = \"\")\n  public String testBlankMediaType(String input) {\n    return input;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/same1/SameModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model.same1;\n\npublic class SameModel {\n  private String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/same1/SameModelThrow.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model.same1;\n\npublic class SameModelThrow {\n  private String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/same2/SameModel.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model.same2;\n\npublic class SameModel {\n  private String name;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/model/same2/SameModelThrow.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.generator.springmvc.model.same2;\n\npublic class SameModelThrow {\n  private String name;\n\n  private int age;\n\n  public String getName() {\n    return name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public int getAge() {\n    return age;\n  }\n\n  public void setAge(int age) {\n    this.age = age;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;\n\nimport java.util.List;\n\nimport org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestPart;\nimport org.springframework.web.multipart.MultipartFile;\n\npublic class RequestPartAnnotationProcessorTest {\n  @Test\n  public void testDemoRest() {\n    UnitTestSwaggerUtils.testSwagger(\"schemas/DemoRest.yaml\", DemoRest.class);\n  }\n\n  @RequestMapping(\"/\")\n  public static class DemoRest {\n    @RequestMapping(method = RequestMethod.POST, path = \"/fun\")\n    public void fun(@RequestPart(\"stringParam\") String stringParam,\n        @RequestPart(name = \"intParam\") int intParam,\n        @RequestPart(\"stringParamArray\") String[] stringParamArray,\n        @RequestPart(\"stringParamCollection\") List<String> stringParamCollection,\n        @RequestPart(\"file\") MultipartFile file,\n        @RequestPart(\"fileArray\") MultipartFile[] fileArray,\n        @RequestPart(\"fileCollection\") List<MultipartFile> fileCollection) {\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreatorTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.generator.springmvc.property.creator;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport io.swagger.v3.oas.models.media.FileSchema;\nimport io.swagger.v3.oas.models.media.Schema;\n\npublic class MultipartFilePropertyCreatorTest {\n  private final MultipartFilePropertyCreator multipartFilePropertyCreator = new MultipartFilePropertyCreator();\n\n  @Test\n  public void createProperty() {\n    Schema property = multipartFilePropertyCreator.createProperty();\n    MatcherAssert.assertThat(property, Matchers.instanceOf(FileSchema.class));\n  }\n\n  @Test\n  public void classes() {\n    Class<?>[] classes = multipartFilePropertyCreator.classes();\n    MatcherAssert.assertThat(classes, Matchers.arrayContaining(MultipartFile.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/DefaultParameterSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.DefaultParameterSchema\n  version: 1.0.0\nservers:\n- url: /\npaths:\n  /testBlankMediaType:\n    post:\n      operationId: testBlankMediaType\n      parameters:\n      - name: input\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testMultipleMediaType:\n    put:\n      operationId: testMultipleMediaType\n      parameters:\n      - name: input\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\n  /testObjectParam:\n    get:\n      operationId: testObjectParam\n      parameters:\n      - name: name\n        in: query\n        schema:\n          type: string\n      - name: age\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testSimpleParam:\n    get:\n      operationId: testSimpleParam\n      parameters:\n      - name: strParam\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testSingleMediaType:\n    post:\n      operationId: testSingleMediaType\n      parameters:\n      - name: input\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n  /testUnsupportedParamType:\n    get:\n      operationId: testUnsupportedParamType\n      parameters:\n      - name: i\n        in: query\n        schema:\n          type: integer\n          format: int32\n      - name: integerList\n        in: query\n        schema:\n          type: array\n          items:\n            $ref: \"#/components/schemas/TestParam\"\n      - name: stringMap\n        in: query\n        schema:\n          type: object\n          additionalProperties:\n            type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\ncomponents:\n  schemas:\n    TestParam:\n      type: object\n      properties:\n        name:\n          type: string\n        age:\n          type: integer\n          format: int32\n      x-java-class: org.apache.servicecomb.swagger.generator.springmvc.model.TestParam\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/DemoRest.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.processor.annotation.RequestPartAnnotationProcessorTest$DemoRest\n  version: 1.0.0\nservers:\n- url: /\npaths:\n  /fun:\n    post:\n      operationId: fun\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                stringParam:\n                  type: string\n                intParam:\n                  type: integer\n                  format: int32\n                stringParamArray:\n                  type: array\n                  items:\n                    type: string\n                stringParamCollection:\n                  type: array\n                  items:\n                    type: string\n                file:\n                  type: string\n                  format: binary\n                fileArray:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n                fileCollection:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n      responses:\n        \"200\":\n          description: response of 200\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/MethodEmptyPath.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.MethodEmptyPath\"\n  x-java-interface: \"gen.cse.ms.ut.MethodEmptyPathIntf\"\nbasePath: \"/MethodEmptyPath\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    get:\n      operationId: \"usingGetMapping\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n    post:\n      operationId: \"usingPostMapping\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n    put:\n      operationId: \"usingPutMapping\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n    delete:\n      operationId: \"usingDeleteMapping\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n    patch:\n      operationId: \"usingPatchMapping\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/RestControllerWithPathSchema.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.RestControllerWithPathSchema\n  version: 1.0.0\nservers:\n- url: /prefix\npaths:\n  /testSimpleParam:\n    get:\n      operationId: testSimpleParam\n      parameters:\n      - name: strParam\n        in: query\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/asyncResponseEntity.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"asyncResponseEntity\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"array\"\n            items:\n              type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/cookie.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"cookie\"\n      parameters:\n      - name: \"cookie\"\n        in: \"cookie\"\n        required: false\n        type: \"integer\"\n        format: \"int32\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/defaultParameter.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.MethodDefaultParameter\n  version: 1.0.0\nservers:\n- url: MethodDefaultParameter\npaths:\n  /usingDeleteMapping:\n    delete:\n      operationId: usingDeleteMapping\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /usingGetMapping:\n    get:\n      operationId: usingGetMapping\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /usingPatchMapping:\n    patch:\n      operationId: usingPatchMapping\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /usingPostMapping:\n    post:\n      operationId: usingPostMapping\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /usingPutMapping:\n    put:\n      operationId: usingPutMapping\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /usingRequestMapping:\n    put:\n      operationId: usingRequestMapping\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/echo.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\n  version: 1.0.0\nservers:\n- url: Echo\npaths:\n  /asyncResponseEntity:\n    put:\n      operationId: asyncResponseEntity\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: string\n            text/plain:\n              schema:\n                type: array\n                items:\n                  type: string\n  /cookie:\n    put:\n      operationId: cookie\n      parameters:\n      - name: cookie\n        in: cookie\n        required: false\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /emptyPath:\n    put:\n      operationId: emptyPath\n      responses:\n        \"200\":\n          description: response of 200\n  /enumBody:\n    put:\n      operationId: enumBody\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n              enum:\n              - RED\n              - YELLOW\n              - BLUE\n          text/plain:\n            schema:\n              type: string\n              enum:\n              - RED\n              - YELLOW\n              - BLUE\n        required: true\n        x-name: color\n      responses:\n        \"200\":\n          description: response of 200\n  /inheritHttpMethod:\n    put:\n      operationId: inheritHttpMethod\n      parameters:\n      - name: query\n        in: query\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n  /nestedListString:\n    put:\n      operationId: nestedListString\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: array\n              items:\n                type: array\n                items:\n                  type: string\n          text/plain:\n            schema:\n              type: array\n              items:\n                type: array\n                items:\n                  type: string\n        required: true\n        x-name: param\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n            text/plain:\n              schema:\n                type: array\n                items:\n                  type: array\n                  items:\n                    type: string\n  /part:\n    put:\n      operationId: part\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /partAnnotation:\n    put:\n      operationId: partAnnotation\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /partArray:\n    put:\n      operationId: partArray\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /partArrayAnnotation:\n    put:\n      operationId: partArrayAnnotation\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /partList:\n    put:\n      operationId: partList\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /partListAnnotation:\n    put:\n      operationId: partListAnnotation\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                part:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n      responses:\n        \"200\":\n          description: response of 200\n  /rawJsonStringMethod:\n    put:\n      operationId: rawJsonStringMethod\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n          text/plain:\n            schema:\n              type: string\n        required: true\n        x-raw-json: true\n        x-name: jsonInput\n      responses:\n        \"200\":\n          description: response of 200\n  /testCompletableFutureResponseEntityOptional:\n    put:\n      operationId: testCompletableFutureResponseEntityOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testResponseEntityOptional:\n    put:\n      operationId: testResponseEntityOptional\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/emptyPath.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\n  version: 1.0.0\nservers:\n- url: Echo\npaths:\n  /:\n    put:\n      operationId: emptyPath\n      responses:\n        \"200\":\n          description: response of 200\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/enumBody.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"enumBody\"\n      parameters:\n      - in: \"body\"\n        name: \"color\"\n        required: true\n        schema:\n          type: \"string\"\n          enum:\n          - \"RED\"\n          - \"YELLOW\"\n          - \"BLUE\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/inheritHttpMethod.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"inheritHttpMethod\"\n      parameters:\n      - name: \"query\"\n        in: \"query\"\n        required: false\n        type: \"integer\"\n        format: \"int32\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/mixupAnnotations.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.MethodMixupAnnotations\n  version: 1.0.0\nservers:\n- url: MethodMixupAnnotations\npaths:\n  /bytes:\n    get:\n      operationId: bytes\n      requestBody:\n        content:\n          application/json:\n            schema:\n              type: string\n              format: byte\n          application/protobuf:\n            schema:\n              type: string\n              format: byte\n          text/plain:\n            schema:\n              type: string\n              format: byte\n        required: true\n        x-name: value\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n                format: byte\n            application/protobuf:\n              schema:\n                type: string\n                format: byte\n            text/plain:\n              schema:\n                type: string\n                format: byte\n  /defaultQueryParam:\n    post:\n      operationId: defaultQueryParam\n      parameters:\n      - name: prefix\n        in: query\n        schema:\n          type: string\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/protobuf:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: user\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /diffNames:\n    get:\n      summary: differentName\n      operationId: differentName\n      parameters:\n      - name: x\n        in: query\n        required: true\n        schema:\n          type: integer\n          format: int32\n      - name: \"y\"\n        in: query\n        required: true\n        schema:\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: integer\n                format: int32\n            application/protobuf:\n              schema:\n                type: integer\n                format: int32\n            text/plain:\n              schema:\n                type: integer\n                format: int32\n  /upload:\n    post:\n      operationId: fileUpload\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                file1:\n                  type: string\n                  format: binary\n                someFile:\n                  type: string\n                  format: binary\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n  /reduce:\n    get:\n      operationId: reduce\n      parameters:\n      - name: b\n        in: cookie\n        required: true\n        schema:\n          type: integer\n          format: int32\n      - name: a\n        in: query\n        required: false\n        schema:\n          type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: integer\n                format: int32\n            application/protobuf:\n              schema:\n                type: integer\n                format: int32\n            text/plain:\n              schema:\n                type: integer\n                format: int32\n  /testDefaultValue:\n    get:\n      operationId: testDefaultValue\n      parameters:\n      - name: e\n        in: query\n        required: false\n        schema:\n          type: integer\n          format: int32\n      - name: a\n        in: header\n        required: false\n        schema:\n          type: integer\n          format: int32\n          default: 20\n      - name: b\n        in: cookie\n        required: false\n        schema:\n          type: string\n          default: bobo\n      - name: c\n        in: query\n        required: false\n        schema:\n          type: integer\n          format: int32\n          default: 40\n      - name: d\n        in: query\n        required: false\n        schema:\n          maximum: 30\n          minimum: 20\n          type: integer\n          format: int32\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testImplicitForm:\n    post:\n      operationId: testImplicitForm\n      requestBody:\n        content:\n          application/x-www-form-urlencoded:\n            schema:\n              properties:\n                form1:\n                  type: string\n                  description: a required form param\n                  nullable: false\n                  example: \"\"\n                form2:\n                  type: string\n                  description: an optional form param\n                  nullable: true\n                  example: \"\"\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /testLocalDateTime:\n    get:\n      operationId: testLocalDateTime\n      parameters:\n      - name: date\n        in: query\n        required: true\n        schema:\n          type: string\n          format: date-time\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n                format: date-time\n            application/protobuf:\n              schema:\n                type: string\n                format: date-time\n            text/plain:\n              schema:\n                type: string\n                format: date-time\n  /uploadFileAndAttribute:\n    post:\n      operationId: uploadFileAndAttribute\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                file:\n                  type: string\n                  format: binary\n                attribute:\n                  type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /uploadFilesAndAttribute:\n    post:\n      operationId: uploadFilesAndAttribute\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              properties:\n                files:\n                  type: array\n                  items:\n                    type: string\n                    format: binary\n                attribute:\n                  type: string\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: string\n            application/protobuf:\n              schema:\n                type: string\n            text/plain:\n              schema:\n                type: string\n  /usingDeleteMapping/{targetName}:\n    delete:\n      operationId: usingDeleteMapping\n      parameters:\n      - name: header\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\n  /usingGetMapping/{targetName}:\n    get:\n      operationId: usingGetMapping\n      parameters:\n      - name: header\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\n  /usingPatchMapping/{targetName}:\n    patch:\n      operationId: usingPatchMapping\n      parameters:\n      - name: header\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\n  /usingPostMapping/{targetName}:\n    post:\n      operationId: usingPostMapping\n      parameters:\n      - name: header\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\n  /usingPutMapping/{targetName}:\n    put:\n      operationId: usingPutMapping\n      parameters:\n      - name: header\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\n  /usingRequestMapping/{targetName}:\n    post:\n      operationId: usingRequestMapping\n      parameters:\n      - name: header\n        in: header\n        required: true\n        schema:\n          type: string\n      - name: targetName\n        in: path\n        required: true\n        schema:\n          type: string\n      - name: word\n        in: query\n        required: true\n        schema:\n          type: string\n      requestBody:\n        content:\n          text/plain:\n            schema:\n              $ref: \"#/components/schemas/User\"\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/User\"\n        required: true\n        x-name: srcUser\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            text/plain:\n              schema:\n                type: string\n            application/json:\n              schema:\n                type: string\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      x-java-class: org.apache.servicecomb.foundation.test.scaffolding.model.User\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/nestedListString.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /nestedListString:\n    post:\n      operationId: \"nestedListString\"\n      parameters:\n      - in: \"body\"\n        name: \"param\"\n        required: true\n        schema:\n          type: \"array\"\n          items:\n            type: \"array\"\n            items:\n              type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"array\"\n            items:\n              type: \"array\"\n              items:\n                type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/part.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"part\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"part\"\n        in: \"formData\"\n        required: false\n        type: \"file\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/partAnnotation.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"partAnnotation\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"part\"\n        in: \"formData\"\n        required: true\n        type: \"file\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/partArray.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"partArray\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"part\"\n        in: \"formData\"\n        required: false\n        type: \"array\"\n        items:\n          type: \"file\"\n        collectionFormat: \"multi\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/partArrayAnnotation.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"partArrayAnnotation\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"part\"\n        in: \"formData\"\n        required: true\n        type: \"array\"\n        items:\n          type: \"file\"\n        collectionFormat: \"multi\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/partList.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"partList\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"part\"\n        in: \"formData\"\n        required: false\n        type: \"array\"\n        items:\n          type: \"file\"\n        collectionFormat: \"multi\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/partListAnnotation.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"partListAnnotation\"\n      consumes:\n      - \"multipart/form-data\"\n      parameters:\n      - name: \"part\"\n        in: \"formData\"\n        required: true\n        type: \"array\"\n        items:\n          type: \"file\"\n        collectionFormat: \"multi\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/rawJsonStringMethod.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"rawJsonStringMethod\"\n      parameters:\n      - in: \"body\"\n        name: \"jsonInput\"\n        required: true\n        schema:\n          type: \"string\"\n        x-raw-json: true\n      responses:\n        \"200\":\n          description: \"response of 200\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/requestMappingHttpMethod.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.ClassMethodNoHttpMethod\n  version: 1.0.0\nservers:\n- url: c\npaths:\n  /m:\n    get:\n      operationId: noHttpMethod\n      responses:\n        \"200\":\n          description: response of 200\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/responseEntity.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.MethodResponseEntity\n  version: 1.0.0\nservers:\n- url: MethodResponseEntity\npaths:\n  /usingDeleteMapping:\n    delete:\n      operationId: usingDeleteMapping\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n  /usingGetMapping:\n    get:\n      operationId: usingGetMapping\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n  /usingPatchMapping:\n    patch:\n      operationId: usingPatchMapping\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n  /usingPostMapping:\n    post:\n      operationId: usingPostMapping\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n  /usingPutMapping:\n    put:\n      operationId: usingPutMapping\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n  /usingRequestMapping:\n    put:\n      operationId: usingRequestMapping\n      responses:\n        \"200\":\n          description: response of 200\n          content:\n            application/json:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            application/protobuf:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\n            text/plain:\n              schema:\n                type: array\n                items:\n                  $ref: \"#/components/schemas/User\"\ncomponents:\n  schemas:\n    User:\n      type: object\n      properties:\n        name:\n          type: string\n        friends:\n          type: array\n          items:\n            $ref: \"#/components/schemas/User\"\n      x-java-class: org.apache.servicecomb.foundation.test.scaffolding.model.User\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/swaggerTestTarget.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.SwaggerTestTarget\n  version: 1.0.0\nservers:\n- url: /test\npaths:\n  /:\n    post:\n      operationId: method\n      responses:\n        \"200\":\n          description: response of 200\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/swaggerTestTarget_ValueOverWritePath.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nopenapi: 3.0.1\ninfo:\n  title: swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.SwaggerTestTarget_ValueOverWritePath\n  version: 1.0.0\nservers:\n- url: /testValue\npaths:\n  /:\n    get:\n      operationId: method\n      responses:\n        \"200\":\n          description: response of 200\ncomponents: {}\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testBlankMediaType.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.TestProducer\"\n  x-java-interface: \"gen.cse.ms.ut.TestProducerIntf\"\nbasePath: \"/\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    post:\n      operationId: \"testBlankMediaType\"\n      parameters:\n      - name: \"input\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testCompletableFutureResponseEntityOptional.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"testCompletableFutureResponseEntityOptional\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testMultipleMediaType.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.TestProducer\"\n  x-java-interface: \"gen.cse.ms.ut.TestProducerIntf\"\nbasePath: \"/\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    put:\n      operationId: \"testMultipleMediaType\"\n      consumes:\n      - \"text/plain\"\n      - \"application/json\"\n      produces:\n      - \"text/plain\"\n      - \"application/json\"\n      parameters:\n      - name: \"input\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testObjectParam.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.DefaultParameterSchema\"\n  x-java-interface: \"gen.cse.ms.ut.DefaultParameterSchemaIntf\"\nbasePath: \"/\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /testObjectParam:\n    get:\n      operationId: \"testObjectParam\"\n      parameters:\n      - name: \"name\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      - name: \"age\"\n        in: \"query\"\n        required: false\n        type: \"integer\"\n        format: \"int32\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testResponseEntityOptional.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.Echo\"\n  x-java-interface: \"gen.cse.ms.ut.EchoIntf\"\nbasePath: \"/Echo\"\nconsumes:\n- \"a\"\n- \"b\"\nproduces:\n- \"a\"\n- \"b\"\npaths:\n  /:\n    put:\n      operationId: \"testResponseEntityOptional\"\n      parameters: []\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testSimpleParam.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.DefaultParameterSchema\"\n  x-java-interface: \"gen.cse.ms.ut.DefaultParameterSchemaIntf\"\nbasePath: \"/\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /testSimpleParam:\n    get:\n      operationId: \"testSimpleParam\"\n      parameters:\n      - name: \"strParam\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/testSingleMediaType.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\n---\nswagger: \"2.0\"\ninfo:\n  version: \"1.0.0\"\n  title: \"swagger definition for org.apache.servicecomb.swagger.generator.springmvc.model.TestProducer\"\n  x-java-interface: \"gen.cse.ms.ut.TestProducerIntf\"\nbasePath: \"/\"\nconsumes:\n- \"application/json\"\nproduces:\n- \"application/json\"\npaths:\n  /:\n    post:\n      operationId: \"testSingleMediaType\"\n      consumes:\n      - \"application/xml\"\n      produces:\n      - \"application/xml\"\n      parameters:\n      - name: \"input\"\n        in: \"query\"\n        required: false\n        type: \"string\"\n      responses:\n        \"200\":\n          description: \"response of 200\"\n          schema:\n            type: \"string\"\n"
  },
  {
    "path": "swagger/swagger-generator/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-generator</artifactId>\n  <name>Java Chassis::Swagger::Generator</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>generator-core</module>\n    <module>generator-jaxrs</module>\n    <module>generator-springmvc</module>\n    <module>generator-spring-data</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-invocation</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-invocation-core</artifactId>\n  <name>Java Chassis::Swagger::Invocation::Core</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-core</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-springmvc</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerConsumer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.engine;\n\nimport java.lang.reflect.Method;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport com.google.common.annotations.VisibleForTesting;\n\npublic class SwaggerConsumer {\n  private Class<?> consumerIntf;\n\n  // key is consumer method name\n  private final Map<Method, SwaggerConsumerOperation> operations = new HashMap<>();\n\n  public Class<?> getConsumerIntf() {\n    return consumerIntf;\n  }\n\n  public void setConsumerIntf(Class<?> consumerIntf) {\n    this.consumerIntf = consumerIntf;\n  }\n\n  public void addOperation(SwaggerConsumerOperation op) {\n    operations.put(op.getConsumerMethod(), op);\n  }\n\n  @VisibleForTesting\n  public SwaggerConsumerOperation findOperation(String consumerMethodName) {\n    for (Entry<Method, SwaggerConsumerOperation> operationEntry : operations.entrySet()) {\n      if (operationEntry.getKey().getName().equals(consumerMethodName)) {\n        return operationEntry.getValue();\n      }\n    }\n    return null;\n  }\n\n  public SwaggerConsumerOperation findOperation(Method consumerMethod) {\n    return operations.get(consumerMethod);\n  }\n\n  public Map<Method, SwaggerConsumerOperation> getOperations() {\n    return operations;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerConsumerOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.engine;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;\n\npublic class SwaggerConsumerOperation {\n  private Class<?> consumerClass;\n\n  private Method consumerMethod;\n\n  private String[] consumerParameterNames;\n\n  private SwaggerOperation swaggerOperation;\n\n  private ArgumentsMapper argumentsMapper;\n\n  private ConsumerResponseMapper responseMapper;\n\n  public Method getConsumerMethod() {\n    return consumerMethod;\n  }\n\n  public void setConsumerMethod(Method consumerMethod) {\n    this.consumerMethod = consumerMethod;\n\n    this.consumerParameterNames = Arrays.stream(consumerMethod.getParameters())\n        .map(Parameter::getName)\n        .toArray(String[]::new);\n  }\n\n  public Class<?> getConsumerClass() {\n    return consumerClass;\n  }\n\n  public void setConsumerClass(Class<?> consumerClass) {\n    this.consumerClass = consumerClass;\n  }\n\n  public SwaggerOperation getSwaggerOperation() {\n    return swaggerOperation;\n  }\n\n  public void setSwaggerOperation(SwaggerOperation swaggerOperation) {\n    this.swaggerOperation = swaggerOperation;\n  }\n\n  public ArgumentsMapper getArgumentsMapper() {\n    return argumentsMapper;\n  }\n\n  public void setArgumentsMapper(ArgumentsMapper argumentsMapper) {\n    this.argumentsMapper = argumentsMapper;\n  }\n\n  public ConsumerResponseMapper getResponseMapper() {\n    return responseMapper;\n  }\n\n  public void setResponseMapper(ConsumerResponseMapper responseMapper) {\n    this.responseMapper = responseMapper;\n  }\n\n  public Map<String, Object> toInvocationArguments(Object[] args) {\n    Map<String, Object> arguments = new HashMap<>();\n    for (int i = 0; i < consumerParameterNames.length; i++) {\n      arguments.put(consumerParameterNames[i], args[i]);\n    }\n    return arguments;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.engine;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;\nimport org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;\nimport org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgumentsMapperCreator;\nimport org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerContextArgumentMapperFactory;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapperCreator;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory;\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.swagger.v3.core.util.Json;\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class SwaggerEnvironment {\n  private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerEnvironment.class);\n\n  /*\n   * For Consumer, first load swagger from resources. Generate one if not exists.\n   */\n  public SwaggerConsumer createConsumer(Class<?> consumerIntf, OpenAPI swagger) {\n    swagger = checkAndGenerateSwagger(consumerIntf, swagger);\n\n    Map<Class<?>, ContextArgumentMapperFactory> contextFactories = SPIServiceUtils\n        .getOrLoadSortedService(ConsumerContextArgumentMapperFactory.class)\n        .stream()\n        .collect(Collectors.toMap(ConsumerContextArgumentMapperFactory::getContextClass, Function.identity()));\n    ResponseMapperFactories<ConsumerResponseMapper> consumerResponseMapperFactories =\n        new ResponseMapperFactories<>(ConsumerResponseMapperFactory.class);\n\n    SwaggerOperations swaggerOperations = new SwaggerOperations(swagger);\n\n    SwaggerConsumer consumer = new SwaggerConsumer();\n    consumer.setConsumerIntf(consumerIntf);\n    for (Method consumerMethod : MethodUtils.findSwaggerMethods(consumerIntf)) {\n      String operationId = findOperationId(consumerMethod);\n      SwaggerOperation swaggerOperation = swaggerOperations.findOperation(operationId);\n      if (swaggerOperation == null) {\n        // consumer method set is bigger than contract, it's invalid\n        // but we need to support consumer upgrade before producer, so only log and ignore it.\n        LOGGER.warn(\"consumer method {}:{} not exist in contract.\",\n            consumerIntf.getName(),\n            consumerMethod.getName());\n        continue;\n      }\n\n      ConsumerArgumentsMapperCreator creator = new ConsumerArgumentsMapperCreator(\n          Json.mapper().getSerializationConfig(),\n          contextFactories,\n          consumerIntf,\n          consumerMethod,\n          swaggerOperation);\n      ArgumentsMapper argsMapper = creator.createArgumentsMapper();\n      ConsumerResponseMapper responseMapper = consumerResponseMapperFactories\n          .createResponseMapper(consumerMethod.getGenericReturnType());\n\n      SwaggerConsumerOperation op = new SwaggerConsumerOperation();\n      op.setConsumerClass(consumerIntf);\n      op.setConsumerMethod(consumerMethod);\n      op.setSwaggerOperation(swaggerOperation);\n      op.setArgumentsMapper(argsMapper);\n      op.setResponseMapper(responseMapper);\n\n      consumer.addOperation(op);\n    }\n\n    return consumer;\n  }\n\n  protected String findOperationId(Method consumerMethod) {\n    return MethodUtils.findSwaggerMethodName(consumerMethod);\n  }\n\n  /*\n   * For producer, always generate swagger from code.\n   */\n  public SwaggerProducer createProducer(Object producerInstance) {\n    return createProducer(producerInstance, null);\n  }\n\n  /*\n   * For producer, always generate swagger from code.\n   */\n  public SwaggerProducer createProducer(Object producerInstance, Class<?> schemaInterface) {\n    Class<?> producerCls = targetSwaggerClass(producerInstance, schemaInterface);\n\n    OpenAPI swagger = SwaggerGenerator.generate(producerCls);\n\n    Map<Class<?>, ContextArgumentMapperFactory> contextFactories = SPIServiceUtils\n        .getOrLoadSortedService(ProducerContextArgumentMapperFactory.class)\n        .stream()\n        .collect(Collectors.toMap(ProducerContextArgumentMapperFactory::getContextClass, Function.identity()));\n    ResponseMapperFactories<ProducerResponseMapper> producerResponseMapperFactories =\n        new ResponseMapperFactories<>(ProducerResponseMapperFactory.class);\n\n    SwaggerOperations swaggerOperations = new SwaggerOperations(swagger);\n\n    Map<String, Method> visibleProducerMethods = MethodUtils.findSwaggerMethodsMapOfOperationId(producerCls);\n\n    SwaggerProducer producer = new SwaggerProducer();\n    producer.setSwagger(swagger);\n    producer.setProducerCls(producerCls);\n    producer.setProducerInstance(producerInstance);\n    for (SwaggerOperation swaggerOperation : swaggerOperations.getOperations().values()) {\n      String operationId = swaggerOperation.getOperationId();\n      // producer参数不一定等于swagger参数\n      Method producerMethod = visibleProducerMethods.getOrDefault(operationId, null);\n      if (producerMethod == null) {\n        // producer未实现契约，非法\n        String msg = String.format(\"operationId %s not exist in producer %s.\",\n            operationId,\n            producerInstance.getClass().getName());\n        throw new IllegalStateException(msg);\n      }\n\n      ProducerArgumentsMapperCreator creator = new ProducerArgumentsMapperCreator(\n          Json.mapper().getSerializationConfig(),\n          contextFactories,\n          producerCls,\n          producerMethod,\n          swaggerOperation);\n      ProducerArgumentsMapper argsMapper = creator.createArgumentsMapper();\n      ProducerResponseMapper responseMapper = producerResponseMapperFactories.createResponseMapper(\n          producerMethod.getGenericReturnType());\n\n      SwaggerProducerOperation op = new SwaggerProducerOperation();\n      op.setProducerClass(producerCls);\n      op.setProducerInstance(producerInstance);\n      op.setProducerMethod(producerMethod);\n      op.setSwaggerOperation(swaggerOperation);\n      op.setSwaggerParameterTypes(creator.getSwaggerParameterTypes());\n      op.setArgumentsMapper(argsMapper);\n      op.setResponseMapper(responseMapper);\n\n      producer.addOperation(op);\n    }\n\n    return producer;\n  }\n\n  private OpenAPI checkAndGenerateSwagger(Class<?> swaggerClass, OpenAPI swagger) {\n    if (swagger == null) {\n      swagger = SwaggerGenerator.generate(swaggerClass);\n    }\n    return swagger;\n  }\n\n  private Class<?> targetSwaggerClass(Object producerInstance, Class<?> schemaInterface) {\n    if (schemaInterface != null && !Object.class.equals(schemaInterface)) {\n      return schemaInterface;\n    }\n    return BeanUtils.getImplClassFromBean(producerInstance);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.engine;\n\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class SwaggerProducer {\n  private Class<?> producerCls;\n\n  private Object producerInstance;\n\n  private OpenAPI swagger;\n\n  // key is operationId\n  private final Map<String, SwaggerProducerOperation> opMap = new HashMap<>();\n\n  public Class<?> getProducerCls() {\n    return producerCls;\n  }\n\n  public void setProducerCls(Class<?> producerCls) {\n    this.producerCls = producerCls;\n  }\n\n  public Object getProducerInstance() {\n    return producerInstance;\n  }\n\n  public void setProducerInstance(Object producerInstance) {\n    this.producerInstance = producerInstance;\n  }\n\n  public OpenAPI getSwagger() {\n    return swagger;\n  }\n\n  public void setSwagger(OpenAPI swagger) {\n    this.swagger = swagger;\n  }\n\n  public void addOperation(SwaggerProducerOperation op) {\n    opMap.put(op.getOperationId(), op);\n  }\n\n  public SwaggerProducerOperation findOperation(String operationId) {\n    return opMap.get(operationId);\n  }\n\n  public Collection<SwaggerProducerOperation> getAllOperations() {\n    return opMap.values();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.engine;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\n\npublic class SwaggerProducerOperation {\n\n  // 因为存在aop场景，所以，producerClass不一定等于producerInstance.getClass()\n  private Class<?> producerClass;\n\n  private Object producerInstance;\n\n  private Method producerMethod;\n\n  private SwaggerOperation swaggerOperation;\n\n  // swagger parameter types relate to producer\n  // because features of @BeanParam/query wrapper/rpc mode parameter wrapper\n  // types is not direct equals to producerMethod parameter types\n  private Map<String, Type> swaggerParameterTypes;\n\n  private ProducerArgumentsMapper argumentsMapper;\n\n  private ProducerResponseMapper responseMapper;\n\n  public String getOperationId() {\n    return swaggerOperation.getOperationId();\n  }\n\n  public Class<?> getProducerClass() {\n    return producerClass;\n  }\n\n  public void setProducerClass(Class<?> producerClass) {\n    this.producerClass = producerClass;\n  }\n\n  public Object getProducerInstance() {\n    return producerInstance;\n  }\n\n  public void setProducerInstance(Object producerInstance) {\n    this.producerInstance = producerInstance;\n  }\n\n  public Method getProducerMethod() {\n    return producerMethod;\n  }\n\n  public void setProducerMethod(Method producerMethod) {\n    this.producerMethod = producerMethod;\n  }\n\n  public SwaggerOperation getSwaggerOperation() {\n    return swaggerOperation;\n  }\n\n  public void setSwaggerOperation(SwaggerOperation swaggerOperation) {\n    this.swaggerOperation = swaggerOperation;\n  }\n\n\n  public Map<String, Type> getSwaggerParameterTypes() {\n    return swaggerParameterTypes;\n  }\n\n  public void setSwaggerParameterTypes(Map<String, Type> swaggerParameterTypes) {\n    this.swaggerParameterTypes = swaggerParameterTypes;\n  }\n\n  public ProducerArgumentsMapper getArgumentsMapper() {\n    return argumentsMapper;\n  }\n\n  public void setArgumentsMapper(ProducerArgumentsMapper argumentsMapper) {\n    this.argumentsMapper = argumentsMapper;\n  }\n\n  public ProducerResponseMapper getResponseMapper() {\n    return responseMapper;\n  }\n\n  public void setResponseMapper(ProducerResponseMapper responseMapper) {\n    this.responseMapper = responseMapper;\n  }\n\n  public Type getSwaggerParameterType(String name) {\n    return this.swaggerParameterTypes.get(name);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/AsyncResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic interface AsyncResponse {\n  void handle(Response response);\n\n  default void success(StatusType status, Object result) {\n    handle(Response.status(status).entity(result));\n  }\n\n  default void success(Object result) {\n    handle(Response.ok(result));\n  }\n\n  default void consumerFail(Throwable e) {\n    handle(Response.createConsumerFail(e));\n  }\n\n  default void producerFail(Throwable e) {\n    handle(Response.createProducerFail(e));\n  }\n\n  default void fail(InvocationType type, Throwable e) {\n    handle(Response.createFail(type, e));\n  }\n\n  default void complete(Response resp) {\n    handle(resp);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/InvocationType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation;\n\npublic enum InvocationType {\n  CONSUMER,\n  PROVIDER,\n  EDGE\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/Response.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation;\n\nimport java.util.List;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport io.vertx.core.MultiMap;\n\n/**\n * 用jaxrs的Response能表达所有概念\n * 但是那个是abstract类，在不引入jersey之类的库的情况下，我们需要补充的功能太多\n *\n * 所以，使用一个简单的归一化类\n */\npublic class Response {\n  private StatusType status;\n\n  private MultiMap headers;\n\n  // 失败场景中，result是Throwable\n  private Object result;\n\n  public boolean isSucceed() {\n    return HttpStatus.isSuccess(status);\n  }\n\n  public boolean isFailed() {\n    return !isSucceed();\n  }\n\n  public int getStatusCode() {\n    return status.getStatusCode();\n  }\n\n  public String getReasonPhrase() {\n    return status.getReasonPhrase();\n  }\n\n  public StatusType getStatus() {\n    return status;\n  }\n\n  public void setStatus(StatusType status) {\n    this.status = status;\n  }\n\n  public String getHeader(String name) {\n    if (headers == null) {\n      return null;\n    }\n\n    return headers.get(name);\n  }\n\n  public List<String> getHeaders(String name) {\n    if (headers == null) {\n      return null;\n    }\n\n    return headers.getAll(name);\n  }\n\n  public MultiMap getHeaders() {\n    return headers;\n  }\n\n  public Response setHeaders(MultiMap headers) {\n    this.headers = headers;\n    return this;\n  }\n\n  public Response addHeader(String name, String value) {\n    if (value == null) {\n      return this;\n    }\n    if (headers == null) {\n      headers = MultiMap.caseInsensitiveMultiMap();\n    }\n\n    headers.add(name, value);\n    return this;\n  }\n\n  public Response setHeader(String name, String value) {\n    if (value == null) {\n      return this;\n    }\n    if (headers == null) {\n      headers = MultiMap.caseInsensitiveMultiMap();\n    }\n\n    headers.set(name, value);\n    return this;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getResult() {\n    return (T) result;\n  }\n\n  public void setResult(Object result) {\n    this.result = result;\n  }\n\n  // 如果是成功，body即是result\n  // 如果是失败，body可能是InvocationException，也可能是InvocationException中的errorData\n  public static Response create(int statusCode, String reasonPhrase, Object result) {\n    StatusType status = new HttpStatus(statusCode, reasonPhrase);\n    return create(status, result);\n  }\n\n  public static Response create(StatusType status, Object result) {\n    Response response = Response.status(status);\n    if (response.isFailed()) {\n      result = ExceptionFactory.create(status, result);\n    }\n    return response.entity(result);\n  }\n\n  // 有的场景下，需要返回非200的，其他2xx状态码，所以需要支持指定\n  public static Response createSuccess(StatusType status, Object result) {\n    return Response.status(status).entity(result);\n  }\n\n  public static Response createSuccess(Object result) {\n    return Response.status(Status.OK).entity(result);\n  }\n\n  public static Response createFail(InvocationException exception) {\n    return Response.status(exception.getStatus()).entity(exception);\n  }\n\n  public static Response createFail(InvocationType invocationType, String errorMsg) {\n    CommonExceptionData errorData = new CommonExceptionData(errorMsg);\n    if (InvocationType.CONSUMER.equals(invocationType)) {\n      return createFail(ExceptionFactory.createConsumerException(errorData));\n    }\n\n    return createFail(ExceptionFactory.createProducerException(errorData));\n  }\n\n  public static Response createFail(InvocationType invocationType, Throwable throwable) {\n    if (InvocationType.CONSUMER.equals(invocationType)) {\n      return createConsumerFail(throwable);\n    }\n\n    return createProducerFail(throwable);\n  }\n\n  public static Response createConsumerFail(Throwable throwable) {\n    InvocationException exception = ExceptionFactory.convertConsumerException(throwable);\n    return createFail(exception);\n  }\n\n  public static Response createConsumerFail(Throwable throwable, String message) {\n    InvocationException exception = ExceptionFactory.convertConsumerException(throwable, message);\n    return createFail(exception);\n  }\n\n  public static Response createProducerFail(Throwable throwable) {\n    InvocationException exception = ExceptionFactory.convertProducerException(throwable);\n    return createFail(exception);\n  }\n\n  // 兼容接口\n\n  public static Response consumerFailResp(Throwable e) {\n    return createConsumerFail(e);\n  }\n\n  public static Response producerFailResp(Throwable e) {\n    return createProducerFail(e);\n  }\n\n  public static Response providerFailResp(Throwable e) {\n    return createProducerFail(e);\n  }\n\n  public static Response success(Object result, StatusType status) {\n    return createSuccess(status, result);\n  }\n\n  public static Response succResp(Object result) {\n    return createSuccess(result);\n  }\n\n  public static Response failResp(InvocationException e) {\n    return createFail(e);\n  }\n\n  public static Response failResp(InvocationType invocationType, Throwable e) {\n    return createFail(invocationType, e);\n  }\n\n  // 下面是jaxrs Response的一些常见用法，照搬过来\n  public Response entity(Object result) {\n    setResult(result);\n    return this;\n  }\n\n  public Response build() {\n    return this;\n  }\n\n  public static Response status(StatusType status) {\n    Response response = new Response();\n    response.setStatus(status);\n    return response;\n  }\n\n  public static Response ok(Object result) {\n    Response response = new Response();\n    response.setStatus(Status.OK);\n    response.setResult(result);\n    return response;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation;\n\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic class SwaggerInvocation extends InvocationContext {\n  // 本实例是在consumer端，还是在provider端\n  protected InvocationType invocationType;\n\n  protected InvocationContext parentContext;\n\n  public SwaggerInvocation() {\n    parentContext = ContextUtils.getInvocationContext();\n    if (parentContext != null) {\n      addContext(parentContext.getContext());\n      addLocalContext(parentContext.getLocalContext());\n    }\n  }\n\n  public InvocationContext getParentContext() {\n    return parentContext;\n  }\n\n  public InvocationType getInvocationType() {\n    return invocationType;\n  }\n\n  public String getInvocationQualifiedName() {\n    return invocationType.name();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/AbstractArgumentsMapperCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectParameterName;\n\nimport java.lang.reflect.Method;\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\n\nimport com.fasterxml.jackson.databind.SerializationConfig;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\n/**\n * <pre>\n *   1.common\n *     context type parameter is not swagger parameter:\n *       InvocationContext\n *       HttpServletRequest\n *\n *   2.same version\n *     1) direct map (most scenes)\n *       interface method:\n *         class AddParam {\n *           int x;\n *           int y;\n *         }\n *         int add(InvocationContext context, AddParam param)\n *       swagger parameters:\n *         param\n *\n *       interface method:\n *         int add(int x, int y)\n *       swagger parameters:\n *         x, y\n *    2) swagger only one POJO parameter, extract all field to method parameters (POJO dev mode)\n *      interface method:\n *        int add(int x, int y)\n *      swagger parameters:\n *        param\n *    3) wrap some simple continuously swagger parameters to POJO (springmvc query parameters)\n *      interface method:\n *        int add(String name, AddParam param, Body body)\n *      swagger parameters:\n *        name, x, y, body\n *    4) wrap some simple and complex continuously swagger parameters to POJO  (JaxRS BeanParam)\n *      interface method:\n *        class BeanWrapper {\n *          int x;\n *          int y;\n *          Body body;\n *        }\n *        int add(String name, AddParam param, Body body)\n *      swagger parameters:\n *        name, x, y, body\n *  2. invoke old version\n *    interface method:\n *      int add(int x, int y, int z)\n *    swagger parameter:\n *      x, y\n *  3. invoke new version\n *    interface method:\n *      int add(int x, int y)\n *    swagger parameter:\n *      x, y, z\n * </pre>\n */\n@SuppressWarnings({\"rawtypes\", \"unchecked\"})\npublic abstract class AbstractArgumentsMapperCreator {\n  protected boolean isSwaggerBodyField = false;\n\n  protected SerializationConfig serializationConfig;\n\n  // key is context class\n  protected Map<Class<?>, ContextArgumentMapperFactory> contextFactories;\n\n  // consumer or producer\n  protected Method providerMethod;\n\n  protected Class<?> providerClass;\n\n  protected SwaggerOperation swaggerOperation;\n\n  protected List<ArgumentMapper> mappers = new ArrayList<>();\n\n  protected List<Parameter> swaggerParameters;\n\n  protected RequestBody bodyParameter;\n\n  // For pojo wrapped bodies only\n  protected Map<String, Schema> swaggerBodyProperties;\n\n  protected Set<String> processedSwaggerParameters;\n\n  public AbstractArgumentsMapperCreator(SerializationConfig serializationConfig,\n      Map<Class<?>, ContextArgumentMapperFactory> contextFactories, Class<?> providerClass,\n      Method providerMethod, SwaggerOperation swaggerOperation) {\n    this.serializationConfig = serializationConfig;\n    this.contextFactories = contextFactories;\n    this.providerClass = providerClass;\n    this.providerMethod = providerMethod;\n    this.swaggerOperation = swaggerOperation;\n\n    this.swaggerParameters = this.swaggerOperation.getOperation().getParameters();\n\n    this.bodyParameter = this.swaggerOperation.getOperation().getRequestBody();\n    this.swaggerBodyProperties = readSwaggerBodyProperties();\n    this.processedSwaggerParameters = new HashSet<>();\n  }\n\n  private Map<String, Schema> readSwaggerBodyProperties() {\n    if (bodyParameter == null || bodyParameter.getContent() == null\n        || bodyParameter.getContent().size() == 0) {\n      return null;\n    }\n    // For pojo wrapped bodies only\n    if (bodyParameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE) != null ||\n        bodyParameter.getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null) {\n      return null;\n    }\n    Schema schema = bodyParameter.getContent().entrySet().iterator().next().getValue().getSchema();\n    if (schema != null && schema.get$ref() != null) {\n      schema = SwaggerUtils.getSchema(swaggerOperation.getSwagger(), schema.get$ref());\n    }\n    if (schema != null && schema.getProperties() != null) {\n      return schema.getProperties();\n    }\n    return null;\n  }\n\n  protected void doCreateArgumentsMapper() {\n    java.lang.reflect.Parameter[] providerParameters = providerMethod.getParameters();\n    for (int providerParamIdx = 0; providerParamIdx < providerParameters.length; providerParamIdx++) {\n      java.lang.reflect.Parameter providerParameter = providerParameters[providerParamIdx];\n      if (processContextParameter(providerParameter)) {\n        continue;\n      }\n\n      String parameterName = collectParameterName(providerParameter);\n      if (processKnownParameter(providerParamIdx, parameterName)) {\n        processedSwaggerParameters.add(parameterName);\n        continue;\n      }\n\n      if (processSwaggerBodyField(providerParamIdx, parameterName)) {\n        processedSwaggerParameters.add(parameterName);\n        isSwaggerBodyField = true;\n        continue;\n      }\n\n      if (processBeanParameter(providerParamIdx, providerParameter)) {\n        continue;\n      }\n\n      processUnknownParameter(providerParamIdx, providerParameter, parameterName);\n    }\n\n    // Process swagger parameters that not in method parameters\n    if (swaggerParameters != null) {\n      for (Parameter parameter : swaggerParameters) {\n        if (!processedSwaggerParameters.contains(parameter.getName())) {\n          processPendingSwaggerParameter(parameter);\n        }\n      }\n    }\n    if (bodyParameter != null) {\n      processPendingBodyParameter(bodyParameter);\n    }\n  }\n\n  /**\n   *\n   * @param providerParameter processing provider parameter\n   * @return true means processed\n   */\n  protected boolean processContextParameter(java.lang.reflect.Parameter providerParameter) {\n    ContextArgumentMapperFactory contextFactory = contextFactories.get(providerParameter.getType());\n    if (contextFactory == null) {\n      return false;\n    }\n\n    mappers.add(contextFactory\n        .create(providerParameter.getName(), providerParameter.getName()));\n    return true;\n  }\n\n  /**\n   * Parameters has the same name in method and swagger.\n   */\n  protected boolean processKnownParameter(int providerParamIdx, String invocationArgumentName) {\n    if (!parameterNameExistsInSwagger(invocationArgumentName)) {\n      return false;\n    }\n\n    ArgumentMapper mapper = createKnownParameterMapper(providerParamIdx, invocationArgumentName);\n    mappers.add(mapper);\n    return true;\n  }\n\n  protected boolean parameterNameExistsInSwagger(String parameterName) {\n    if (this.swaggerParameters != null) {\n      for (Parameter parameter : this.swaggerParameters) {\n        if (parameterName.equals(parameter.getName())) {\n          return true;\n        }\n      }\n    }\n    if (this.bodyParameter != null && this.bodyParameter.getContent() != null) {\n      if (this.bodyParameter.getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null &&\n          this.bodyParameter.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema() != null &&\n          this.bodyParameter.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties() != null) {\n        return this.bodyParameter.getContent()\n            .get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties().get(parameterName) != null;\n      }\n      if (this.bodyParameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE) != null &&\n          this.bodyParameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE).getSchema() != null &&\n          this.bodyParameter.getContent().get(SwaggerConst.FILE_MEDIA_TYPE).getSchema().getProperties() != null) {\n        return this.bodyParameter.getContent()\n            .get(SwaggerConst.FILE_MEDIA_TYPE).getSchema().getProperties().get(parameterName) != null;\n      }\n    }\n    if (this.bodyParameter != null && this.bodyParameter.getExtensions() != null) {\n      return parameterName.equals(this.bodyParameter.getExtensions().get(SwaggerConst.EXT_BODY_NAME));\n    }\n    return false;\n  }\n\n  protected abstract ArgumentMapper createKnownParameterMapper(int providerParamIdx, String parameterName);\n\n  /**\n   * Process POJO wrapped parameters, e.g.\n   *   method(int foo, int bar)\n   * and Form parameters, e.g.\n   *   method(@FormParam(\"foo\") int foo, @FormParam(\"bar\") int bar)\n   */\n  protected boolean processSwaggerBodyField(int providerParamIdx, String parameterName) {\n    if (swaggerBodyProperties == null || swaggerBodyProperties.get(parameterName) == null) {\n      return false;\n    }\n\n    ArgumentMapper mapper = createSwaggerBodyFieldMapper(providerParamIdx, parameterName);\n    mappers.add(mapper);\n    return true;\n  }\n\n  protected abstract ArgumentMapper createSwaggerBodyFieldMapper(int providerParamIdx, String parameterName);\n\n  /**\n   * Bean parameters, e.g.\n   *\n   *   method(QueryModels queries)\n   *\n   * where swagger should be:\n   *    - in: query\n   *      name: foo\n   *    - in: query\n   *      name: bar\n   */\n  protected abstract boolean processBeanParameter(int providerParamIdx, java.lang.reflect.Parameter providerParameter);\n\n  protected abstract void processUnknownParameter(int providerParamIdx, java.lang.reflect.Parameter providerParameter,\n      String parameterName);\n\n  /**\n   * Process parameters that in swagger but not in method.\n   */\n  protected abstract void processPendingSwaggerParameter(Parameter parameter);\n\n  /**\n   * Process body parameter that in swagger but not in method.\n   */\n  protected abstract void processPendingBodyParameter(RequestBody parameter);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic interface ArgumentMapper {\n  void swaggerArgumentToInvocationArguments(SwaggerInvocation swaggerInvocation, Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments);\n\n  void invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation, Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic interface ArgumentsMapper {\n  default Map<String, Object> swaggerArgumentToInvocationArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments) {\n    throw new IllegalStateException(\"not implemented.\");\n  }\n\n  /**\n   * <pre>\n   * for scenes that consumer arguments not same to contract arguments, eg:\n   * 1.consumer: int add(QueryWrapper query)\n   *             class QueryWrapper {\n   *               public int x;\n   *               public int y;\n   *             }\n   *   contract: int add(int x, int y)\n   *\n   * 2.consumer: int add(InvocationContext context, int x, int y);\n   *   contract: int add(int x, int y)\n   *\n   * 3.consumer: int add(int x, int y)\n   *   contract: int add(BodyRequest body)\n   *             class BodyRequest {\n   *               public int x;\n   *               public int y;\n   *             }\n   *\n   * notice:\n   *   no convert logic when map arguments\n   *   map arguments by name, DO NOT use duplicated contract argument names\n   * </pre>\n   *\n   */\n  default Map<String, Object> invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> invocationArguments) {\n    throw new IllegalStateException(\"not implemented.\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ContextArgumentMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments;\n\npublic interface ContextArgumentMapperFactory {\n  Class<?> getContextClass();\n\n  ArgumentMapper create(String invocationArgumentName, String swaggerArgumentName);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ArgumentsMapperCommon.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\n\n/**\n * map consumer arguments to swagger arguments\n */\npublic class ArgumentsMapperCommon implements ArgumentsMapper {\n  private final List<ArgumentMapper> mappers;\n\n  public ArgumentsMapperCommon(List<ArgumentMapper> mappers) {\n    this.mappers = mappers;\n  }\n\n  @Override\n  public Map<String, Object> invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> invocationArguments) {\n    Map<String, Object> swaggerParameters = new HashMap<>(invocationArguments.size());\n    for (ArgumentMapper argMapper : mappers) {\n      argMapper.invocationArgumentToSwaggerArguments(swaggerInvocation, swaggerParameters, invocationArguments);\n    }\n    return swaggerParameters;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ArgumentsMapperDirectReuse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\n\npublic class ArgumentsMapperDirectReuse implements ArgumentsMapper {\n  @Override\n  public Map<String, Object> invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> invocationArguments) {\n    return invocationArguments;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\n\npublic abstract class ConsumerArgumentMapper implements ArgumentMapper {\n  public void swaggerArgumentToInvocationArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments) {\n    throw new IllegalStateException(\"not expected\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentSame.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic final class ConsumerArgumentSame extends ConsumerArgumentMapper {\n  private final String invocationArgumentName;\n\n  private final String swaggerArgumentName;\n\n  public ConsumerArgumentSame(String invocationArgumentName, String swaggerArgumentName) {\n    this.invocationArgumentName = invocationArgumentName;\n    this.swaggerArgumentName = swaggerArgumentName;\n  }\n\n  public boolean isSameMapping() {\n    return this.invocationArgumentName.equals(this.swaggerArgumentName);\n  }\n\n  @Override\n  public void invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments) {\n    swaggerArguments.put(swaggerArgumentName, invocationArguments.get(invocationArgumentName));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentToBodyField.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\n/**\n * <pre>\n * Typical scene of transparent RPC\n * all parameters of consumer method wrapped to a bean in contract\n * </pre>\n */\npublic final class ConsumerArgumentToBodyField extends ConsumerArgumentMapper {\n  private final String invocationArgumentName;\n\n  private final String parameterName;\n\n  private final String swaggerArgumentName;\n\n  public ConsumerArgumentToBodyField(String invocationArgumentName,\n      String swaggerArgumentName, String parameterName) {\n    this.invocationArgumentName = invocationArgumentName;\n    this.parameterName = parameterName;\n    this.swaggerArgumentName = swaggerArgumentName;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public void invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments) {\n    Object consumerArgument = invocationArguments.get(invocationArgumentName);\n    swaggerArguments.computeIfAbsent(swaggerArgumentName, k -> new LinkedHashMap<String, Object>());\n    if (consumerArgument != null) {\n      ((Map<String, Object>) swaggerArguments.get(swaggerArgumentName)).put(parameterName, consumerArgument);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectParameterName;\n\nimport java.lang.reflect.Method;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.invocation.arguments.AbstractArgumentsMapperCreator;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.SerializationConfig;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\npublic class ConsumerArgumentsMapperCreator extends AbstractArgumentsMapperCreator {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerArgumentsMapperCreator.class);\n\n  private int unknownConsumerParams = 0;\n\n  public ConsumerArgumentsMapperCreator(SerializationConfig serializationConfig,\n      Map<Class<?>, ContextArgumentMapperFactory> contextFactories, Class<?> consumerClass,\n      Method consumerMethod, SwaggerOperation swaggerOperation) {\n    super(serializationConfig, contextFactories, consumerClass, consumerMethod, swaggerOperation);\n  }\n\n  private boolean isAllSameMapper() {\n    for (ArgumentMapper mapper : mappers) {\n      if (mapper instanceof ConsumerArgumentSame && ((ConsumerArgumentSame) mapper).isSameMapping()) {\n        continue;\n      }\n\n      return false;\n    }\n\n    return true;\n  }\n\n  public ArgumentsMapper createArgumentsMapper() {\n    doCreateArgumentsMapper();\n\n    // if all mappers are SameMapper, then no need any mapper\n    if (unknownConsumerParams == 0\n        && mappers.size() == swaggerOperation.parameterCount()\n        && isAllSameMapper()) {\n      return new ArgumentsMapperDirectReuse();\n    }\n\n    return new ArgumentsMapperCommon(mappers);\n  }\n\n  @Override\n  protected void processUnknownParameter(int providerParamIdx, java.lang.reflect.Parameter providerParameter,\n      String parameterName) {\n    LOGGER.warn(\"Consumer parameter({}) is not exist in contract, method={}:{}.\",\n        parameterName, providerMethod.getDeclaringClass().getName(), providerMethod.getName());\n    unknownConsumerParams++;\n  }\n\n  @Override\n  protected void processPendingSwaggerParameter(Parameter parameter) {\n\n  }\n\n  @Override\n  protected void processPendingBodyParameter(RequestBody parameter) {\n\n  }\n\n  @Override\n  protected ArgumentMapper createKnownParameterMapper(int providerParamIdx, String invocationArgumentName) {\n    return new ConsumerArgumentSame(this.providerMethod.getParameters()[providerParamIdx].getName(),\n        invocationArgumentName);\n  }\n\n  @Override\n  protected ArgumentMapper createSwaggerBodyFieldMapper(int consumerParamIdx, String parameterName) {\n    return new ConsumerArgumentToBodyField(this.providerMethod.getParameters()[consumerParamIdx].getName(),\n        (String) this.bodyParameter.getExtensions().get(SwaggerConst.EXT_BODY_NAME), parameterName);\n  }\n\n  @Override\n  protected boolean processBeanParameter(int consumerParamIdx, java.lang.reflect.Parameter consumerParameter) {\n    JavaType consumerType = TypeFactory.defaultInstance().constructType(consumerParameter.getParameterizedType());\n    if (!SwaggerUtils.isBean(consumerType)) {\n      return false;\n    }\n    boolean result = false;\n    ConsumerBeanParamMapper mapper = new ConsumerBeanParamMapper(\n        this.providerMethod.getParameters()[consumerParamIdx].getName());\n    for (BeanPropertyDefinition propertyDefinition : serializationConfig.introspect(consumerType).findProperties()) {\n      String parameterName = collectParameterName(providerMethod, propertyDefinition);\n      if (!parameterNameExistsInSwagger(parameterName)) {\n        continue;\n      }\n\n      mapper.addField(parameterName, LambdaMetafactoryUtils.createObjectGetter(propertyDefinition));\n      processedSwaggerParameters.add(parameterName);\n      result = true;\n    }\n    mappers.add(mapper);\n    return result;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerBeanParamMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Getter;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\n/**\n * <pre>\n * consumer: void add(QueryWrapper query)\n *           class QueryWrapper {\n *             int x;\n *             int y;\n *           }\n * contract; void add(int x, int y)\n * </pre>\n */\npublic final class ConsumerBeanParamMapper extends ConsumerArgumentMapper {\n  private static class FieldMeta {\n    String swaggerArgumentName;\n\n    Getter<Object, Object> getter;\n\n    public FieldMeta(String swaggerArgumentName, Getter<Object, Object> getter) {\n      this.swaggerArgumentName = swaggerArgumentName;\n      this.getter = getter;\n    }\n  }\n\n  private final String invocationArgumentName;\n\n  private final List<FieldMeta> fields = new ArrayList<>();\n\n  public ConsumerBeanParamMapper(String invocationArgumentName) {\n    this.invocationArgumentName = invocationArgumentName;\n  }\n\n  public void addField(String invocationArgumentName, Getter<Object, Object> getter) {\n    fields.add(new FieldMeta(invocationArgumentName, getter));\n  }\n\n  @Override\n  public void invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments) {\n    Object consumerArgument = invocationArguments.get(invocationArgumentName);\n    if (consumerArgument == null) {\n      return;\n    }\n    for (FieldMeta fieldMeta : fields) {\n      swaggerArguments.put(fieldMeta.swaggerArgumentName, fieldMeta.getter.get(consumerArgument));\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerContextArgumentMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;\n\npublic interface ConsumerContextArgumentMapperFactory extends ContextArgumentMapperFactory {\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerInvocationContextMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic class ConsumerInvocationContextMapper extends ConsumerArgumentMapper {\n  protected String invocationArgumentName;\n\n  public ConsumerInvocationContextMapper(String invocationArgumentName) {\n    this.invocationArgumentName = invocationArgumentName;\n  }\n\n  @Override\n  public void invocationArgumentToSwaggerArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments) {\n    InvocationContext context = (InvocationContext) invocationArguments.get(invocationArgumentName);\n    invocation.addContext(context.getContext());\n    invocation.addLocalContext(context.getLocalContext());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerInvocationContextMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic class ConsumerInvocationContextMapperFactory implements ConsumerContextArgumentMapperFactory {\n  @Override\n  public Class<?> getContextClass() {\n    return InvocationContext.class;\n  }\n\n  @Override\n  public ArgumentMapper create(String invocationArgumentName, String swaggerArgumentName) {\n    return new ConsumerInvocationContextMapper(invocationArgumentName);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/AbstractProducerContextArgMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic abstract class AbstractProducerContextArgMapper extends ProducerArgumentMapper {\n  protected String invocationArgumentName;\n\n  protected String swaggerArgumentName;\n\n  public AbstractProducerContextArgMapper(String invocationArgumentName, String swaggerArgumentName) {\n    this.invocationArgumentName = invocationArgumentName;\n    this.swaggerArgumentName = swaggerArgumentName;\n  }\n\n  @Override\n  public void swaggerArgumentToInvocationArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments, Map<String, Object> invocationArguments) {\n    Object producerArg = createContextArg(invocation);\n    invocationArguments.put(this.invocationArgumentName, producerArg);\n  }\n\n  public abstract Object createContextArg(SwaggerInvocation invocation);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\n\npublic abstract class ProducerArgumentMapper implements ArgumentMapper {\n  public void invocationArgumentToSwaggerArguments(SwaggerInvocation swaggerInvocation,\n      Map<String, Object> swaggerArguments,\n      Map<String, Object> invocationArguments) {\n    throw new IllegalStateException(\"not expected\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic class ProducerArgumentSame extends ProducerArgumentMapper {\n  protected String invocationArgumentName;\n\n  protected String swaggerArgumentName;\n\n  public ProducerArgumentSame(String invocationArgumentName, String swaggerArgumentName) {\n    this.invocationArgumentName = invocationArgumentName;\n    this.swaggerArgumentName = swaggerArgumentName;\n  }\n\n  @Override\n  public void swaggerArgumentToInvocationArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments, Map<String, Object> invocationArguments) {\n    invocationArguments.put(invocationArgumentName, swaggerArguments.get(swaggerArgumentName));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\n\n/**\n * map swagger arguments to producer arguments\n */\npublic class ProducerArgumentsMapper implements ArgumentsMapper {\n  private final List<ArgumentMapper> producerArgMapperList;\n\n  public ProducerArgumentsMapper(List<ArgumentMapper> producerArgMapperList) {\n    this.producerArgMapperList = producerArgMapperList;\n  }\n\n  @Override\n  public Map<String, Object> swaggerArgumentToInvocationArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments) {\n    Map<String, Object> invocationArguments = new HashMap<>(swaggerArguments.size());\n    for (ArgumentMapper argMapper : producerArgMapperList) {\n      argMapper.swaggerArgumentToInvocationArguments(invocation, swaggerArguments, invocationArguments);\n    }\n\n    return invocationArguments;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectParameterName;\n\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.lang.reflect.Type;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;\nimport org.apache.servicecomb.swagger.invocation.arguments.AbstractArgumentsMapperCreator;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.SerializationConfig;\nimport com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\nimport com.google.common.reflect.TypeToken;\n\nimport io.swagger.v3.oas.models.parameters.RequestBody;\n\n@SuppressWarnings(\"unchecked\")\npublic class ProducerArgumentsMapperCreator extends AbstractArgumentsMapperCreator {\n  // swagger parameter types relate to producer\n  // because features of @BeanParam/query, and rpc mode parameter wrapper\n  // types is not always equals to producerMethod parameter types directly\n  private final Map<String, Type> swaggerParameterTypes;\n\n  public ProducerArgumentsMapperCreator(SerializationConfig serializationConfig,\n      Map<Class<?>, ContextArgumentMapperFactory> contextFactories, Class<?> producerClass,\n      Method producerMethod, SwaggerOperation swaggerOperation) {\n    super(serializationConfig, contextFactories, producerClass, producerMethod, swaggerOperation);\n\n    swaggerParameterTypes = new HashMap<>();\n  }\n\n  public Map<String, Type> getSwaggerParameterTypes() {\n    return swaggerParameterTypes;\n  }\n\n  public ProducerArgumentsMapper createArgumentsMapper() {\n    doCreateArgumentsMapper();\n    return new ProducerArgumentsMapper(mappers);\n  }\n\n  @Override\n  protected void processUnknownParameter(int providerParamIdx, java.lang.reflect.Parameter providerParameter,\n      String parameterName) {\n    throw new IllegalStateException(String\n        .format(\"failed to find producer parameter in contract, method=%s:%s, parameter name=%s.\",\n            providerMethod.getDeclaringClass().getSimpleName(), providerMethod.getName(), parameterName));\n  }\n\n  @Override\n  protected void processPendingSwaggerParameter(io.swagger.v3.oas.models.parameters.Parameter parameter) {\n    swaggerParameterTypes.put(parameter.getName(), Object.class);\n  }\n\n  @Override\n  protected void processPendingBodyParameter(RequestBody bodyParameter) {\n    if (bodyParameter.getContent().get(SwaggerConst.DEFAULT_MEDIA_TYPE) != null\n        && !processedSwaggerParameters.contains(\n        (String) bodyParameter.getExtensions().get(SwaggerConst.EXT_BODY_NAME))) {\n      swaggerParameterTypes.put((String) bodyParameter\n          .getExtensions().get(SwaggerConst.EXT_BODY_NAME), Object.class);\n    }\n    if (bodyParameter.getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null) {\n      bodyParameter.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties().forEach((k, v) -> {\n        if (!processedSwaggerParameters.contains((String) k)) {\n          swaggerParameterTypes.put((String) k, Object.class);\n        }\n      });\n    }\n  }\n\n  @Override\n  protected ArgumentMapper createKnownParameterMapper(int providerParamIdx, String invocationArgumentName) {\n    Type providerType = TypeToken.of(providerClass)\n        .resolveType(providerMethod.getGenericParameterTypes()[providerParamIdx])\n        .getType();\n    swaggerParameterTypes\n        .put(invocationArgumentName, providerType);\n    return new ProducerArgumentSame(providerMethod.getParameters()[providerParamIdx].getName(), invocationArgumentName);\n  }\n\n  @Override\n  protected ArgumentMapper createSwaggerBodyFieldMapper(int producerParamIdx, String parameterName) {\n    String swaggerArgumentName = (String) this.bodyParameter.getExtensions().get(SwaggerConst.EXT_BODY_NAME);\n    swaggerParameterTypes.put(swaggerArgumentName, Object.class);\n    Type parameterType = TypeToken.of(providerClass)\n        .resolveType(providerMethod.getGenericParameterTypes()[producerParamIdx])\n        .getType();\n    return new SwaggerBodyFieldToProducerArgument(providerMethod.getParameters()[producerParamIdx].getName(),\n        swaggerArgumentName,\n        parameterName, parameterType);\n  }\n\n  @Override\n  protected boolean processBeanParameter(int producerParamIdx, Parameter producerParameter) {\n    JavaType providerType = TypeFactory.defaultInstance().constructType(producerParameter.getParameterizedType());\n    if (!SwaggerUtils.isBean(providerType)) {\n      return false;\n    }\n    ProducerBeanParamMapper mapper = new ProducerBeanParamMapper(\n        providerMethod.getParameters()[producerParamIdx].getName(), producerParameter.getType());\n    boolean result = false;\n    for (BeanPropertyDefinition propertyDefinition : serializationConfig.introspect(providerType)\n        .findProperties()) {\n      String parameterName = collectParameterName(providerMethod, propertyDefinition);\n\n      if (!parameterNameExistsInSwagger(parameterName)) {\n        continue;\n      }\n\n      swaggerParameterTypes.put(parameterName, propertyDefinition.getPrimaryType());\n      mapper.addField(parameterName, LambdaMetafactoryUtils.createObjectSetter(propertyDefinition));\n      processedSwaggerParameters.add(parameterName);\n      result = true;\n    }\n    mappers.add(mapper);\n    return result;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerBeanParamMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.bean.Setter;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic class ProducerBeanParamMapper extends ProducerArgumentMapper {\n  private static class FieldMeta {\n    String swaggerParameterName;\n\n    Setter<Object, Object> setter;\n\n    public FieldMeta(String swaggerParameterName, Setter<Object, Object> setter) {\n      this.swaggerParameterName = swaggerParameterName;\n      this.setter = setter;\n    }\n  }\n\n  protected String invocationArgumentName;\n\n  private final Class<?> producerParamType;\n\n  private final List<FieldMeta> fields = new ArrayList<>();\n\n  public ProducerBeanParamMapper(String invocationArgumentName, Class<?> producerParamType) {\n    this.invocationArgumentName = invocationArgumentName;\n    this.producerParamType = producerParamType;\n  }\n\n  public void addField(String swaggerParameterName, Setter<Object, Object> setter) {\n    fields.add(new FieldMeta(swaggerParameterName, setter));\n  }\n\n  @Override\n  public void swaggerArgumentToInvocationArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments, Map<String, Object> invocationArguments) {\n    try {\n      Object paramInstance = producerParamType.getDeclaredConstructor().newInstance();\n      invocationArguments.put(invocationArgumentName, paramInstance);\n\n      for (FieldMeta fieldMeta : fields) {\n        Object value = swaggerArguments.get(fieldMeta.swaggerParameterName);\n        if (value != null) {\n          // can not set primitive data\n          fieldMeta.setter.set(paramInstance, value);\n        }\n      }\n    } catch (Throwable e) {\n      throw new IllegalStateException(\"failed to map bean param.\", e);\n    }\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerContextArgumentMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;\n\npublic interface ProducerContextArgumentMapperFactory extends ContextArgumentMapperFactory {\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\npublic class ProducerInvocationContextMapper extends AbstractProducerContextArgMapper {\n  public ProducerInvocationContextMapper(String invocationArgumentName, String swaggerArgumentName) {\n    super(invocationArgumentName, swaggerArgumentName);\n  }\n\n  @Override\n  public Object createContextArg(SwaggerInvocation invocation) {\n    return invocation;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic class ProducerInvocationContextMapperFactory implements ProducerContextArgumentMapperFactory {\n  @Override\n  public Class<?> getContextClass() {\n    return InvocationContext.class;\n  }\n\n  @Override\n  public ArgumentMapper create(String invocationArgumentName, String swaggerArgumentName) {\n    return new ProducerInvocationContextMapper(invocationArgumentName, swaggerArgumentName);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerBodyFieldToProducerArgument.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.type.TypeFactory;\n\npublic class SwaggerBodyFieldToProducerArgument extends ProducerArgumentMapper {\n  public static ObjectMapper mapper = JsonUtils.OBJ_MAPPER;\n\n  private final String invocationArgumentName;\n\n  private final String parameterName;\n\n  private final JavaType producerParamType;\n\n  private final String swaggerArgumentName;\n\n  public SwaggerBodyFieldToProducerArgument(String invocationArgumentName,\n      String swaggerArgumentName, String parameterName, Type producerParamType) {\n    this.invocationArgumentName = invocationArgumentName;\n    this.parameterName = parameterName;\n    this.producerParamType = TypeFactory.defaultInstance().constructType(producerParamType);\n    this.swaggerArgumentName = swaggerArgumentName;\n  }\n\n  @Override\n  @SuppressWarnings(\"unchecked\")\n  public void swaggerArgumentToInvocationArguments(SwaggerInvocation invocation,\n      Map<String, Object> swaggerArguments, Map<String, Object> invocationArguments) {\n    Map<String, Object> body = (Map<String, Object>) swaggerArguments.get(swaggerArgumentName);\n    invocationArguments.put(invocationArgumentName,\n        body == null ? null : mapper.convertValue(body.get(parameterName), producerParamType));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/ContextUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.context;\n\nimport java.util.concurrent.CompletableFuture;\n\n/**\n * 传递调用过程的上下文数据\n */\npublic final class ContextUtils {\n  private ContextUtils() {\n  }\n\n  private static final ThreadLocal<InvocationContext> contextMgr = new ThreadLocal<>();\n\n  public static InvocationContext getInvocationContext() {\n    return contextMgr.get();\n  }\n\n  public static InvocationContext getAndRemoveInvocationContext() {\n    InvocationContext context = contextMgr.get();\n    if (context != null) {\n      contextMgr.remove();\n    }\n    return context;\n  }\n\n  public static void setInvocationContext(InvocationContext invocationContext) {\n    contextMgr.set(invocationContext);\n  }\n\n  public static void removeInvocationContext() {\n    contextMgr.remove();\n  }\n\n  /**\n   *\n   * @param future must be InvocationContextCompletableFuture, that is returned from consumer api\n   * @return\n   */\n  public static InvocationContext getFromCompletableFuture(CompletableFuture<?> future) {\n    if (future instanceof InvocationContextCompletableFuture) {\n      return ((InvocationContextCompletableFuture<?>) future).getContext();\n    }\n\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/HttpStatus.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.context;\n\npublic class HttpStatus extends org.apache.servicecomb.foundation.common.http.HttpStatus {\n  public HttpStatus(int statusCode, String reasonPhrase) {\n    super(statusCode, reasonPhrase);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/HttpStatusManager.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.context;\n\npublic class HttpStatusManager extends org.apache.servicecomb.foundation.common.http.HttpStatusManager {\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/InvocationContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.context;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\n/**\n *  InvocationContext is used to pass data between microservices or in microservice different layer.\n */\npublic class InvocationContext {\n  private static final HttpStatusManager statusMgr = new HttpStatusManager();\n\n  protected StatusType httpStatus;\n\n  protected final Map<String, String> context = new HashMap<>();\n\n  protected final Map<String, Object> localContext = new HashMap<>();\n\n  protected TransportContext transportContext;\n\n  public InvocationContext() {\n    httpStatus = Status.OK;\n  }\n\n  public Map<String, String> getContext() {\n    return context;\n  }\n\n  public void setContext(Map<String, String> context) {\n    this.context.clear();\n    this.addContext(context);\n  }\n\n  public void addContext(String key, String value) {\n    context.put(key, value);\n  }\n\n  public String getContext(String key) {\n    return context.get(key);\n  }\n\n  public void addContext(InvocationContext otherContext) {\n    addContext(otherContext.getContext());\n  }\n\n  public void addContext(Map<String, String> otherContext) {\n    if (otherContext == null) {\n      return;\n    }\n\n    context.putAll(otherContext);\n  }\n\n  public void mergeContext(InvocationContext otherContext) {\n    mergeContext(otherContext.getContext());\n  }\n\n  public void mergeContext(Map<String, String> otherContext) {\n    if (otherContext == null) {\n      return;\n    }\n    context.putAll(otherContext);\n  }\n\n  public Map<String, Object> getLocalContext() {\n    return localContext;\n  }\n\n  public void setLocalContext(Map<String, Object> localContext) {\n    this.localContext.clear();\n    this.addLocalContext(localContext);\n  }\n\n  public void addLocalContext(String key, Object value) {\n    localContext.put(key, value);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getLocalContext(String key) {\n    return (T) localContext.get(key);\n  }\n\n  public void addLocalContext(Map<String, Object> otherContext) {\n    if (otherContext == null) {\n      return;\n    }\n\n    localContext.putAll(otherContext);\n  }\n\n  public StatusType getStatus() {\n    return httpStatus;\n  }\n\n  public void setStatus(StatusType status) {\n    this.httpStatus = status;\n  }\n\n  public void setStatus(int statusCode, String reason) {\n    httpStatus = new HttpStatus(statusCode, reason);\n  }\n\n  public void setStatus(int statusCode) {\n    this.httpStatus = statusMgr.getOrCreateByStatusCode(statusCode);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T extends TransportContext> T getTransportContext() {\n    return (T) transportContext;\n  }\n\n  public void setTransportContext(TransportContext transportContext) {\n    this.transportContext = transportContext;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/InvocationContextCompletableFuture.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.context;\n\nimport java.util.concurrent.CompletableFuture;\n\npublic class InvocationContextCompletableFuture<T> extends CompletableFuture<T> {\n  private final InvocationContext context;\n\n  public InvocationContextCompletableFuture(InvocationContext context) {\n    this.context = context;\n  }\n\n  public InvocationContext getContext() {\n    return context;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/TransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.context;\n\n/**\n * currently, only for server side\n */\npublic interface TransportContext {\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/context/VertxTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.context;\n\nimport io.vertx.core.Context;\n\npublic interface VertxTransportContext extends TransportContext {\n  Context getVertxContext();\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/Converter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter;\n\nimport java.lang.reflect.Type;\n\npublic interface Converter {\n  Type getSrcType();\n\n  Type getTargetType();\n\n  Object convert(Object value);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/BytesToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.io.ByteArrayInputStream;\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.InputStreamPart;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\n\npublic class BytesToPartConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return byte[].class;\n  }\n\n  @Override\n  public Type getTargetType() {\n    return Part.class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    // not set name, because not easy to get parameter name in this place\n    // org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl not depend on the name\n    return new InputStreamPart(null, new ByteArrayInputStream((byte[]) value));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.io.File;\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\n\npublic class FileToPartConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return File.class;\n  }\n\n  @Override\n  public Type getTargetType() {\n    return Part.class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    // not set name, because not easy to get parameter name in this place\n    // org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl not depend on the name\n    return new FilePart(null, (File) value);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/InputStreamToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.io.InputStream;\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.InputStreamPart;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\n\npublic class InputStreamToPartConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return InputStream.class;\n  }\n\n  @Override\n  public Type getTargetType() {\n    return Part.class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    // not set name, because not easy to get parameter name in this place\n    // org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl not depend on the name\n    return new InputStreamPart(null, (InputStream) value);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\n\nimport jakarta.servlet.http.Part;\n\npublic class PartListToPartArrayConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return ParameterizedTypeUtil.make(List.class, Part.class);\n  }\n\n  @Override\n  public Type getTargetType() {\n    return Part[].class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    if (value == null) {\n      return null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    List<Part> partList = (List<Part>) value;\n    return partList.toArray(new Part[0]);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\n\nimport jakarta.servlet.http.Part;\n\npublic class PartListToPartListConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return ParameterizedTypeUtil.make(List.class, Part.class);\n  }\n\n  @Override\n  public Type getTargetType() {\n    return ParameterizedTypeUtil.make(List.class, Part.class);\n  }\n\n  @Override\n  public Object convert(Object value) {\n    return value;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\n\npublic class PartToPartConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return Part.class;\n  }\n\n  @Override\n  public Type getTargetType() {\n    return Part.class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    return value;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/ResourceToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.ResourcePart;\nimport org.apache.servicecomb.swagger.invocation.converter.Converter;\nimport org.springframework.core.io.Resource;\n\npublic class ResourceToPartConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return Resource.class;\n  }\n\n  @Override\n  public Type getTargetType() {\n    return Part.class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    // not set name, because not easy to get parameter name in this place\n    // org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl not depend on the name\n    return new ResourcePart(null, (Resource) value);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/CommonExceptionData.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.exception;\n\nimport org.apache.servicecomb.foundation.common.DynamicObject;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jackson.annotation.JsonInclude.Include;\n\n/**\n * 将普通异常转换为InvocationException时，保存message信息\n */\npublic class CommonExceptionData extends DynamicObject {\n  @JsonInclude(Include.NON_NULL)\n  private String code;\n\n  private String message;\n\n  public CommonExceptionData() {\n  }\n\n  public CommonExceptionData(String message) {\n    this.message = message;\n  }\n\n  public CommonExceptionData(String code, String message) {\n    this.code = code;\n    this.message = message;\n  }\n\n  public String getCode() {\n    return code;\n  }\n\n  public CommonExceptionData setCode(String code) {\n    this.code = code;\n    return this;\n  }\n\n  public String getMessage() {\n    return message;\n  }\n\n  public CommonExceptionData setMessage(String message) {\n    this.message = message;\n    return this;\n  }\n\n  @Override\n  public String toString() {\n    if (code == null) {\n      return \"CommonExceptionData [message=\" + message + \"]\";\n    }\n\n    return \"CommonExceptionData{\" +\n        \"code='\" + code + '\\'' +\n        \", message='\" + message + '\\'' +\n        \", dynamic=\" + dynamic +\n        '}';\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.exception;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.concurrent.CompletionException;\nimport java.util.concurrent.ExecutionException;\n\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic final class ExceptionFactory {\n  // cse内置的错误\n  // 考虑到springmvc不支持自定义http错误码，所以只能使用“标准”错误码\n  // 510是ws.rs中未定义，在springmvc中定义为not extended\n  // 在我们的流程中不可能用到这个错误定义，所以将之转义为cse的provider内部错误\n  //    private static final int PROVIDER_INNER_STATUS_CODE = 510;\n  public static final int PRODUCER_INNER_STATUS_CODE = 590;\n\n  public static final String PRODUCER_INNER_REASON_PHRASE = \"Unexpected producer error, please check logs for details\";\n\n  public static final StatusType PRODUCER_INNER_STATUS =\n      new HttpStatus(PRODUCER_INNER_STATUS_CODE, PRODUCER_INNER_REASON_PHRASE);\n\n  // 420是ws.rs中未定义，在springmvc中定义为Method Failure\n  // 在我们的流程中不可能用到这个错误定义，所以将之转义为cse的consumer内部错误\n  //    private static final int CONSUMER_INNER_STATUS_CODE = 420;\n  public static final int CONSUMER_INNER_STATUS_CODE = 490;\n\n  public static final String CONSUMER_INNER_REASON_PHRASE = \"Unexpected consumer error, please check logs for details\";\n\n  public static final StatusType CONSUMER_INNER_STATUS =\n      new HttpStatus(CONSUMER_INNER_STATUS_CODE, CONSUMER_INNER_REASON_PHRASE);\n\n  private ExceptionFactory() {\n  }\n\n  public static InvocationException create(StatusType status,\n      Object exceptionOrErrorData) {\n    if (exceptionOrErrorData instanceof InvocationException) {\n      return (InvocationException) exceptionOrErrorData;\n    }\n\n    return doCreate(status, exceptionOrErrorData);\n  }\n\n  public static InvocationException createConsumerException(Object errorData) {\n    return create(CONSUMER_INNER_STATUS, errorData);\n  }\n\n  public static InvocationException createProducerException(Object errorData) {\n    return create(PRODUCER_INNER_STATUS, errorData);\n  }\n\n  private static InvocationException doCreate(StatusType status,\n      Object errorData) {\n    return new InvocationException(status, errorData);\n  }\n\n  private static InvocationException doCreate(int statusCode, String reasonPhrase, CommonExceptionData data,\n      Throwable e) {\n    return new InvocationException(statusCode, reasonPhrase, data, e);\n  }\n\n  public static InvocationException convertConsumerException(Throwable e) {\n    return convertException(CONSUMER_INNER_STATUS_CODE,\n        CONSUMER_INNER_REASON_PHRASE,\n        e,\n        CONSUMER_INNER_REASON_PHRASE);\n  }\n\n  public static InvocationException convertConsumerException(Throwable e, String errorMsg) {\n    return convertException(CONSUMER_INNER_STATUS_CODE,\n        CONSUMER_INNER_REASON_PHRASE,\n        e,\n        errorMsg);\n  }\n\n  public static InvocationException convertProducerException(Throwable e) {\n    return convertException(PRODUCER_INNER_STATUS_CODE,\n        PRODUCER_INNER_REASON_PHRASE,\n        e,\n        PRODUCER_INNER_REASON_PHRASE);\n  }\n\n  public static InvocationException convertProducerException(Throwable e, String errorMsg) {\n    return convertException(PRODUCER_INNER_STATUS_CODE,\n        PRODUCER_INNER_REASON_PHRASE,\n        e,\n        errorMsg);\n  }\n\n  // 如果e中取不出可以直接返回的InvocationException\n  // 则需要创建新的InvocationException实例，此时不允许使用e.getMessage，因为可能会涉及关键信息被传给远端\n  // 新创建的InvocationException，会使用errorMsg来构建CommonExceptionData\n  private static InvocationException convertException(int statusCode, String reasonPhrase, Throwable e,\n      String errorMsg) {\n    e = unwrap(e);\n\n    if (e instanceof InvocationException) {\n      return (InvocationException) e;\n    }\n\n    CommonExceptionData data = new CommonExceptionData(errorMsg);\n    return doCreate(statusCode, reasonPhrase, data, e);\n  }\n\n  public static Throwable unwrapIncludeInvocationException(Throwable throwable) {\n    throwable = unwrap(throwable);\n    if (throwable instanceof InvocationException) {\n      throwable = throwable.getCause();\n    }\n    return throwable;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T extends Throwable> T unwrap(Throwable throwable) {\n    if (throwable instanceof InvocationTargetException) {\n      throwable = ((InvocationTargetException) throwable).getTargetException();\n    }\n    if (throwable instanceof CompletionException) {\n      throwable = throwable.getCause();\n    }\n    if (throwable instanceof ExecutionException) {\n      throwable = throwable.getCause();\n    }\n    return (T) throwable;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/InvocationException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.exception;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\n\n/**\n * 业务在provider端，想返回在swagger中定义好的错误\n * 通过抛出本类型的异常来实现\n * 如果不是本类型的异常，则强制认为是PRODUCER_INNER_STATUS_CODE错误\n */\npublic class InvocationException extends RuntimeException {\n  private static final long serialVersionUID = 8027482777502649656L;\n\n  /**\n   * http header中的statusCode\n   * 不直接使用Status类型，是为了支持业务自定义code\n   */\n  private final StatusType status;\n\n  private final Object errorData;\n\n  public InvocationException(StatusType status, Object errorData) {\n    this.status = status;\n    this.errorData = errorData;\n  }\n\n  public InvocationException(StatusType status, String msg) {\n    this(status, new CommonExceptionData(msg));\n  }\n\n  public InvocationException(int statusCode, String reasonPhrase, Object errorData, Throwable cause) {\n    this(new HttpStatus(statusCode, reasonPhrase), errorData, cause);\n  }\n\n  public InvocationException(int statusCode, String reasonPhrase, Object errorData) {\n    this(new HttpStatus(statusCode, reasonPhrase), errorData);\n  }\n\n  public InvocationException(StatusType status, Object errorData, Throwable cause) {\n    super(cause);\n    this.status = status;\n    this.errorData = errorData;\n  }\n\n  public InvocationException(StatusType status, String code, String msg) {\n    this(status, new CommonExceptionData(code, msg));\n  }\n\n  public InvocationException(StatusType status, String code, String msg, Throwable cause) {\n    this(status, new CommonExceptionData(code, msg), cause);\n  }\n\n  public StatusType getStatus() {\n    return status;\n  }\n\n  public int getStatusCode() {\n    return status.getStatusCode();\n  }\n\n  public String getReasonPhrase() {\n    return status.getReasonPhrase();\n  }\n\n  public Object getErrorData() {\n    return errorData;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getError() {\n    return (T) errorData;\n  }\n\n  @Override\n  public String getMessage() {\n    return this.toString();\n  }\n\n  @Override\n  public String toString() {\n    return \"InvocationException: code=\" + getStatusCode()\n        + \";msg=\" + getErrorData();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/generator/InvocationContextProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.generator;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerContextRegister;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic class InvocationContextProcessor implements SwaggerContextRegister {\n  @Override\n  public Type getContextType() {\n    return InvocationContext.class;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/generator/ScbResponseProcessor.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.generator;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.generator.OperationGenerator;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.generator.core.processor.response.DefaultResponseTypeProcessor;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class ScbResponseProcessor extends DefaultResponseTypeProcessor {\n  @Override\n  public Class<?> getProcessType() {\n    return Response.class;\n  }\n\n  @Override\n  public Type extractResponseType(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,\n      Type genericResponseType) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMapperFactories.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\n\npublic class ResponseMapperFactories<MAPPER> {\n  private final List<ResponseMapperFactory<MAPPER>> factories;\n\n  @SuppressWarnings(\"unchecked\")\n  public ResponseMapperFactories(Class<? extends ResponseMapperFactory<MAPPER>> factoryCls) {\n    factories = (List<ResponseMapperFactory<MAPPER>>) SPIServiceUtils.getSortedService(factoryCls);\n  }\n\n  public MAPPER createResponseMapper(Type providerType) {\n    for (ResponseMapperFactory<MAPPER> factory : factories) {\n      if (!factory.isMatch(providerType)) {\n        continue;\n      }\n\n      return factory.createResponseMapper(this, providerType);\n    }\n\n    throw new IllegalStateException(\n        String.format(\"can not find response mapper for %s, this should never happened.\",\n            providerType.getTypeName()));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response;\n\nimport java.lang.reflect.Type;\n\npublic interface ResponseMapperFactory<MAPPER> {\n  default int getOrder() {\n    return 0;\n  }\n\n  boolean isMatch(Type providerType);\n\n  MAPPER createResponseMapper(ResponseMapperFactories<MAPPER> factories, Type providerType);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.response;\n\nimport java.util.Map;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\npublic interface ResponseMetaMapper {\n  default int getOrder() {\n    return 0;\n  }\n\n  Map<Integer, JavaType> getMapper();\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.swagger.SwaggerUtils;\nimport org.apache.servicecomb.swagger.converter.ConverterMgr;\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.fasterxml.jackson.databind.type.SimpleType;\n\nimport io.swagger.v3.core.util.ReflectionUtils;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\nimport io.swagger.v3.oas.models.responses.ApiResponse;\nimport jakarta.ws.rs.core.Response.Status;\n\n/**\n * <pre>\n * two Scenes:\n * 1.consumer interface + swagger\n *   interface declare success response type\n *   and can declare exceptions response type by annotations\n *   consumer interface meta never changed and has high priority\n *\n *   so, merge them to be one ResponsesMeta\n *\n * 2.restTemplate + swagger\n *   can only declare success response type\n *   and not stable\n *\n *   so, will wrap swagger meta\n *\n *   note:\n *   old version support: List&lt;User&gt; users = restTemplate.postForObject(...., List.class)\n *     in fact, in this time, type is determined by swagger meta\n *   new version:\n *     1) if request response type is List/Set/Map, and there is element type defined, then use swagger type,\n *     2) other times use request response type\n *     3) compare to old version, add support of ParameterizedTypeReference\n * </pre>\n */\npublic class ResponsesMeta {\n  private static final JavaType COMMON_EXCEPTION_JAVA_TYPE = SimpleType.constructUnsafe(CommonExceptionData.class);\n\n  private static final JavaType OBJECT_JAVA_TYPE = SimpleType.constructUnsafe(Object.class);\n\n  private static final ResponseMetaMapper GLOBAL_DEFAULT_MAPPER = SPIServiceUtils\n      .getPriorityHighestService(ResponseMetaMapper.class);\n\n  private final Map<Integer, JavaType> responseMap = new HashMap<>();\n\n  private JavaType defaultResponse;\n\n  public void init(OpenAPI swagger, Operation operation) {\n    if (responseMap.isEmpty()) {\n      responseMap.put(Status.OK.getStatusCode(), OBJECT_JAVA_TYPE);\n      initGlobalDefaultMapper();\n    }\n\n    for (Entry<String, ApiResponse> entry : operation.getResponses().entrySet()) {\n      if (entry.getValue().getContent() == null || entry.getValue().getContent().size() == 0) {\n        continue;\n      }\n\n      String mediaType = entry.getValue().getContent().keySet().iterator().next();\n\n      JavaType javaType = ConverterMgr.findJavaType(swagger,\n          SwaggerUtils.getSchema(swagger,\n              entry.getValue().getContent().get(mediaType).getSchema()));\n\n      if (\"default\".equals(entry.getKey())) {\n        defaultResponse = javaType;\n        continue;\n      }\n\n      Integer statusCode = Integer.parseInt(entry.getKey());\n      JavaType existing = responseMap.get(statusCode);\n      if (existing == null || !ReflectionUtils.isVoid(javaType)) {\n        responseMap.put(statusCode, javaType);\n      }\n    }\n\n    responseMap.putIfAbsent(ExceptionFactory.CONSUMER_INNER_STATUS_CODE, COMMON_EXCEPTION_JAVA_TYPE);\n    responseMap.putIfAbsent(ExceptionFactory.PRODUCER_INNER_STATUS_CODE, COMMON_EXCEPTION_JAVA_TYPE);\n    responseMap.putIfAbsent(Status.TOO_MANY_REQUESTS.getStatusCode(), COMMON_EXCEPTION_JAVA_TYPE);\n    responseMap.putIfAbsent(Status.REQUEST_TIMEOUT.getStatusCode(), COMMON_EXCEPTION_JAVA_TYPE);\n    responseMap.putIfAbsent(Status.SERVICE_UNAVAILABLE.getStatusCode(), COMMON_EXCEPTION_JAVA_TYPE);\n\n    if (defaultResponse == null) {\n      // swagger中没有定义default，加上default专用于处理exception\n      defaultResponse = OBJECT_JAVA_TYPE;\n    }\n  }\n\n  public void cloneTo(ResponsesMeta target) {\n    target.defaultResponse = defaultResponse;\n    target.responseMap.putAll(responseMap);\n  }\n\n  protected void initGlobalDefaultMapper() {\n    if (GLOBAL_DEFAULT_MAPPER != null) {\n      Map<Integer, JavaType> mappers = GLOBAL_DEFAULT_MAPPER.getMapper();\n      if (mappers != null) {\n        responseMap.putAll(mappers);\n      }\n    }\n  }\n\n  public JavaType findResponseType(int statusCode) {\n    JavaType responseType = responseMap.get(statusCode);\n    if (responseType == null) {\n      if (HttpStatus.isSuccess(statusCode)) {\n        return responseMap.get(Status.OK.getStatusCode());\n      }\n\n      return defaultResponse;\n    }\n\n    return responseType;\n  }\n\n  public void setResponseType(int statusCode, JavaType javaType) {\n    this.responseMap.put(statusCode, javaType);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/CompletableFutureConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class CompletableFutureConsumerResponseMapperFactory implements ConsumerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type consumerType) {\n    if (!ParameterizedType.class.isAssignableFrom(consumerType.getClass())) {\n      return false;\n    }\n\n    return ((ParameterizedType) consumerType).getRawType().equals(CompletableFuture.class);\n  }\n\n  @Override\n  public ConsumerResponseMapper createResponseMapper(ResponseMapperFactories<ConsumerResponseMapper> factories,\n      Type consumerType) {\n    Type realConsumerType = ((ParameterizedType) consumerType).getActualTypeArguments()[0];\n    return factories.createResponseMapper(realConsumerType);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/ConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic interface ConsumerResponseMapper {\n  Object mapResponse(Response response);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/ConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactory;\n\npublic interface ConsumerResponseMapperFactory extends ResponseMapperFactory<ConsumerResponseMapper> {\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/CseResponseConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class CseResponseConsumerResponseMapperFactory implements ConsumerResponseMapperFactory {\n  private static final ConsumerResponseMapper SAME = response -> response;\n\n  @Override\n  public boolean isMatch(Type consumerType) {\n    return Response.class.equals(consumerType);\n  }\n\n  @Override\n  public ConsumerResponseMapper createResponseMapper(ResponseMapperFactories<ConsumerResponseMapper> factories,\n      Type consumerType) {\n    return SAME;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/DefaultConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class DefaultConsumerResponseMapper implements ConsumerResponseMapper {\n  @Override\n  public Object mapResponse(Response response) {\n    return response.getResult();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/DefaultConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class DefaultConsumerResponseMapperFactory implements ConsumerResponseMapperFactory {\n  @Override\n  public int getOrder() {\n    return Integer.MAX_VALUE;\n  }\n\n  @Override\n  public boolean isMatch(Type consumerType) {\n    return true;\n  }\n\n  @Override\n  public ConsumerResponseMapper createResponseMapper(ResponseMapperFactories<ConsumerResponseMapper> factories,\n      Type consumerType) {\n    return new DefaultConsumerResponseMapper();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/OptionalConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport java.util.Optional;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class OptionalConsumerResponseMapper implements ConsumerResponseMapper {\n  private final ConsumerResponseMapper realMapper;\n\n  public OptionalConsumerResponseMapper(ConsumerResponseMapper realMapper) {\n    this.realMapper = realMapper;\n  }\n\n  @Override\n  public Object mapResponse(Response response) {\n    Object realResult = realMapper.mapResponse(response);\n    return Optional.ofNullable(realResult);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/OptionalConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.Optional;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class OptionalConsumerResponseMapperFactory implements ConsumerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type consumerType) {\n    if (!ParameterizedType.class.isAssignableFrom(consumerType.getClass())) {\n      return false;\n    }\n\n    return ((ParameterizedType) consumerType).getRawType().equals(Optional.class);\n  }\n\n  @Override\n  public ConsumerResponseMapper createResponseMapper(ResponseMapperFactories<ConsumerResponseMapper> factories,\n      Type consumerType) {\n    Type realConsumerType = ((ParameterizedType) consumerType).getActualTypeArguments()[0];\n    ConsumerResponseMapper realMapper = factories.createResponseMapper(realConsumerType);\n    return new OptionalConsumerResponseMapper(realMapper);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/CompletableFutureProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class CompletableFutureProducerResponseMapperFactory implements ProducerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type producerType) {\n    if (!ParameterizedType.class.isAssignableFrom(producerType.getClass())) {\n      return false;\n    }\n\n    return ((ParameterizedType) producerType).getRawType().equals(CompletableFuture.class);\n  }\n\n  @Override\n  public ProducerResponseMapper createResponseMapper(ResponseMapperFactories<ProducerResponseMapper> factories,\n      Type producerType) {\n    Type realProducerType = ((ParameterizedType) producerType).getActualTypeArguments()[0];\n    return factories.createResponseMapper(realProducerType);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/CseResponseProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class CseResponseProducerResponseMapperFactory implements ProducerResponseMapperFactory {\n  private static final ProducerResponseMapper SAME = (status, response) -> (Response) response;\n\n  @Override\n  public boolean isMatch(Type producerType) {\n    return producerType.equals(Response.class);\n  }\n\n  @Override\n  public ProducerResponseMapper createResponseMapper(ResponseMapperFactories<ProducerResponseMapper> factories,\n      Type producerType) {\n    return SAME;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/DefaultProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class DefaultProducerResponseMapper implements ProducerResponseMapper {\n  @Override\n  public Response mapResponse(StatusType status, Object response) {\n    return Response.create(status, response);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/DefaultProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class DefaultProducerResponseMapperFactory implements ProducerResponseMapperFactory {\n  @Override\n  public int getOrder() {\n    return Integer.MAX_VALUE;\n  }\n\n  @Override\n  public boolean isMatch(Type producerType) {\n    return true;\n  }\n\n  @Override\n  public ProducerResponseMapper createResponseMapper(ResponseMapperFactories<ProducerResponseMapper> factories,\n      Type producerType) {\n    return new DefaultProducerResponseMapper();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/OptionalProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport java.util.Optional;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class OptionalProducerResponseMapper implements ProducerResponseMapper {\n  private final ProducerResponseMapper realMapper;\n\n  public OptionalProducerResponseMapper(ProducerResponseMapper realMapper) {\n    this.realMapper = realMapper;\n  }\n\n  @Override\n  public Response mapResponse(StatusType status, Object response) {\n    @SuppressWarnings(\"unchecked\")\n    Optional<Object> optional = (Optional<Object>) response;\n    return realMapper.mapResponse(status, optional.orElse(null));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/OptionalProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\nimport java.util.Optional;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\n\npublic class OptionalProducerResponseMapperFactory implements ProducerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type producerType) {\n    if (!ParameterizedType.class.isAssignableFrom(producerType.getClass())) {\n      return false;\n    }\n\n    return ((ParameterizedType) producerType).getRawType().equals(Optional.class);\n  }\n\n  @Override\n  public ProducerResponseMapper createResponseMapper(ResponseMapperFactories<ProducerResponseMapper> factories,\n      Type producerType) {\n    Type realProducerType = ((ParameterizedType) producerType).getActualTypeArguments()[0];\n    ProducerResponseMapper realMapper = factories.createResponseMapper(realProducerType);\n    return new OptionalProducerResponseMapper(realMapper);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/ProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic interface ProducerResponseMapper {\n  Response mapResponse(StatusType status, Object response);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/producer/ProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactory;\n\npublic interface ProducerResponseMapperFactory extends ResponseMapperFactory<ProducerResponseMapper> {\n\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ResponseTypeProcessor",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.generator.ScbResponseProcessor\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.SwaggerContextRegister",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.generator.InvocationContextProcessor\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerContextArgumentMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerInvocationContextMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.arguments.producer.ProducerInvocationContextMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.converter.Converter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.converter.impl.part.InputStreamToPartConverter\norg.apache.servicecomb.swagger.invocation.converter.impl.part.BytesToPartConverter\norg.apache.servicecomb.swagger.invocation.converter.impl.part.FileToPartConverter\norg.apache.servicecomb.swagger.invocation.converter.impl.part.PartToPartConverter\norg.apache.servicecomb.swagger.invocation.converter.impl.part.PartListToPartArrayConverter\norg.apache.servicecomb.swagger.invocation.converter.impl.part.PartListToPartListConverter\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.response.consumer.CseResponseConsumerResponseMapperFactory\norg.apache.servicecomb.swagger.invocation.response.consumer.CompletableFutureConsumerResponseMapperFactory\norg.apache.servicecomb.swagger.invocation.response.consumer.DefaultConsumerResponseMapperFactory\norg.apache.servicecomb.swagger.invocation.response.consumer.OptionalConsumerResponseMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.response.producer.CseResponseProducerResponseMapperFactory\norg.apache.servicecomb.swagger.invocation.response.producer.CompletableFutureProducerResponseMapperFactory\norg.apache.servicecomb.swagger.invocation.response.producer.DefaultProducerResponseMapperFactory\norg.apache.servicecomb.swagger.invocation.response.producer.OptionalProducerResponseMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/core/TestException.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport java.lang.reflect.InvocationTargetException;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestException {\n  @Test\n  public void testCommonExceptionData() {\n    CommonExceptionData oData = new CommonExceptionData();\n    oData.setMessage(\"this is Common exception message\");\n    Assertions.assertEquals(\"this is Common exception message\", oData.getMessage());\n\n    oData = new CommonExceptionData(\"this is a test\");\n    Assertions.assertEquals(\"this is a test\", oData.getMessage());\n    Assertions.assertEquals(\"CommonExceptionData [message=this is a test]\", oData.toString());\n  }\n\n  @Test\n  public void testInvocationException() {\n    InvocationException oExceptionIn = new InvocationException(Status.OK, \"I am gone now\");\n    oExceptionIn = ExceptionFactory.convertConsumerException(new Throwable());\n    Assertions.assertEquals(490, oExceptionIn.getStatusCode());\n\n    oExceptionIn = ExceptionFactory.convertConsumerException(new Throwable(), \"abc\");\n    Assertions.assertEquals(490, oExceptionIn.getStatusCode());\n    Assertions.assertEquals(\"abc\", ((CommonExceptionData) oExceptionIn.getErrorData()).getMessage());\n\n    oExceptionIn = ExceptionFactory.convertProducerException(new Throwable());\n    Assertions.assertEquals(590, oExceptionIn.getStatusCode());\n\n    oExceptionIn = ExceptionFactory.convertProducerException(new Throwable(), \"abcd\");\n    Assertions.assertEquals(590, oExceptionIn.getStatusCode());\n    Assertions.assertEquals(\"abcd\", ((CommonExceptionData) oExceptionIn.getErrorData()).getMessage());\n\n    oExceptionIn =\n        ExceptionFactory.convertConsumerException(new InvocationException(Status.OK, new String(\"fake-object\")));\n    Assertions.assertEquals(200, oExceptionIn.getStatusCode());\n\n    oExceptionIn = ExceptionFactory.convertConsumerException(new InvocationTargetException(new Throwable()));\n    Assertions.assertNotEquals(\"java.lang.Throwable\", oExceptionIn.getMessage());\n\n    InvocationException oTemp = new InvocationException(Status.OK, new CommonExceptionData(\"testObject\"));\n    Assertions.assertEquals(\"OK\", oTemp.getReasonPhrase());\n    Assertions.assertEquals(\"CommonExceptionData [message=testObject]\", (oTemp.getErrorData().toString()));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/core/TestResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.core;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.swagger.invocation.AsyncResponse;\nimport org.apache.servicecomb.swagger.invocation.InvocationType;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestResponse {\n  Response response;\n\n  AsyncResponse ar = new AsyncResponse() {\n    @Override\n    public void handle(Response resp) {\n      response = resp;\n    }\n  };\n\n  @Test\n  public void testAr() {\n    ar.success(Status.ACCEPTED, 1);\n    Assertions.assertTrue(response.isSucceed());\n    Assertions.assertFalse(response.isFailed());\n    Assertions.assertEquals(1, (int) response.getResult());\n    Assertions.assertEquals(Status.ACCEPTED.getStatusCode(), response.getStatusCode());\n    Assertions.assertEquals(Status.ACCEPTED.getReasonPhrase(), response.getReasonPhrase());\n    Assertions.assertEquals(Status.ACCEPTED, response.getStatus());\n\n    ar.success(2);\n    Assertions.assertEquals(2, (int) response.getResult());\n    Assertions.assertEquals(Status.OK.getStatusCode(), response.getStatusCode());\n\n    Response r = Response.succResp(3);\n    ar.complete(r);\n    Assertions.assertEquals(r, response);\n\n    ar.consumerFail(new RuntimeExceptionWithoutStackTrace(\"abc\"));\n    CommonExceptionData data = (CommonExceptionData) ((InvocationException) response.getResult()).getErrorData();\n    Assertions.assertEquals(\"Unexpected consumer error, please check logs for details\", data.getMessage());\n    Assertions.assertEquals(ExceptionFactory.CONSUMER_INNER_STATUS_CODE, response.getStatusCode());\n\n    ar.fail(InvocationType.CONSUMER, new RuntimeExceptionWithoutStackTrace(\"abc\"));\n    data = (CommonExceptionData) ((InvocationException) response.getResult()).getErrorData();\n    Assertions.assertEquals(\"Unexpected consumer error, please check logs for details\", data.getMessage());\n    Assertions.assertEquals(ExceptionFactory.CONSUMER_INNER_STATUS_CODE, response.getStatusCode());\n\n    InvocationException consumerException = new InvocationException(300, \"abc\", \"def\");\n    ar.consumerFail(consumerException);\n    Assertions.assertEquals(\"def\", ((InvocationException) response.getResult()).getErrorData());\n    Assertions.assertEquals(300, response.getStatusCode());\n\n    ar.fail(InvocationType.CONSUMER, consumerException);\n    Assertions.assertEquals(\"def\", ((InvocationException) response.getResult()).getErrorData());\n    Assertions.assertEquals(300, response.getStatusCode());\n\n    ar.producerFail(new RuntimeExceptionWithoutStackTrace(\"abc\"));\n    data = (CommonExceptionData) ((InvocationException) response.getResult()).getErrorData();\n    Assertions.assertEquals(\"Unexpected producer error, please check logs for details\", data.getMessage());\n    Assertions.assertEquals(ExceptionFactory.PRODUCER_INNER_STATUS_CODE, response.getStatusCode());\n\n    ar.fail(InvocationType.PROVIDER, new RuntimeExceptionWithoutStackTrace(\"abc\"));\n    data = (CommonExceptionData) ((InvocationException) response.getResult()).getErrorData();\n    Assertions.assertEquals(\"Unexpected producer error, please check logs for details\", data.getMessage());\n    Assertions.assertEquals(ExceptionFactory.PRODUCER_INNER_STATUS_CODE, response.getStatusCode());\n\n    InvocationException producerException = new InvocationException(500, \"abc\", \"def\");\n    ar.producerFail(producerException);\n    Assertions.assertEquals(\"def\", ((InvocationException) response.getResult()).getErrorData());\n    Assertions.assertEquals(500, response.getStatusCode());\n\n    ar.fail(InvocationType.PROVIDER, producerException);\n    Assertions.assertEquals(\"def\", ((InvocationException) response.getResult()).getErrorData());\n    Assertions.assertEquals(500, response.getStatusCode());\n  }\n\n  @Test\n  public void test() {\n    Response r = Response.create(200, \"200\", 2);\n    Assertions.assertEquals(200, r.getStatusCode());\n    Assertions.assertEquals(2, (int) r.getResult());\n    Response r1 = r.build();\n    Assertions.assertEquals(r, r1);\n\n    r = Response.create(300, \"300\", 3);\n    Assertions.assertEquals(300, r.getStatusCode());\n    Assertions.assertEquals(\"300\", r.getReasonPhrase());\n    Assertions.assertEquals(3, ((InvocationException) r.getResult()).getErrorData());\n\n    r = Response.createSuccess(Status.OK, 2);\n    Assertions.assertEquals(200, r.getStatusCode());\n    Assertions.assertEquals(2, (int) r.getResult());\n\n    r = Response.success(2, Status.OK);\n    Assertions.assertEquals(200, r.getStatusCode());\n    Assertions.assertEquals(2, (int) r.getResult());\n\n    r = Response.createFail(InvocationType.CONSUMER, \"abc\");\n    Assertions.assertEquals(\"CommonExceptionData [message=abc]\",\n        ((InvocationException) r.getResult()).getErrorData().toString());\n    Assertions.assertEquals(490, r.getStatusCode());\n\n    r = Response.createFail(InvocationType.PROVIDER, \"def\");\n    Assertions.assertEquals(\"CommonExceptionData [message=def]\",\n        ((InvocationException) r.getResult()).getErrorData().toString());\n    Assertions.assertEquals(590, r.getStatusCode());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/engine/TestSwaggerEnvironment.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.engine;\n\nimport static org.hamcrest.core.Is.is;\nimport static org.hamcrest.core.IsNull.notNullValue;\nimport static org.hamcrest.core.IsNull.nullValue;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.models.ProducerImpl;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestSwaggerEnvironment {\n  private static final SwaggerEnvironment env = new SwaggerEnvironment();\n\n  private static SwaggerProducer producer;\n\n  @BeforeClass\n  public static void init() {\n    producer = env.createProducer(new ProducerImpl(), null);\n  }\n\n  @Test\n  public void ableToFindVisibleMethod() {\n    MatcherAssert.assertThat(producer.findOperation(\"visibleMethod\"), is(notNullValue()));\n  }\n\n  @Test\n  public void unableToFindHiddenMethod() {\n    MatcherAssert.assertThat(producer.findOperation(\"hiddenMethod\"), is(nullValue()));\n  }\n\n  interface ConsumerIntf {\n    void exist();\n\n    void notExist();\n  }\n\n  interface ContractIntf {\n    void exist();\n  }\n\n  @Test\n  public void createConsumer_consumerMethodSetBigger() {\n    OpenAPI swagger = SwaggerGenerator.generate(ContractIntf.class);\n    SwaggerConsumer swaggerConsumer = env.createConsumer(ConsumerIntf.class, swagger);\n\n    Assertions.assertNotNull(swaggerConsumer.findOperation(\"exist\"));\n    Assertions.assertNull(swaggerConsumer.findOperation(\"notExist\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/engine/TestSwaggerProducerOperation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.engine;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.invocation.models.PojoImpl;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestSwaggerProducerOperation {\n  private static final SwaggerEnvironment env = new SwaggerEnvironment();\n\n  private static SwaggerProducer producer;\n\n  @Test\n  public void testGetParameterType() {\n    PojoImpl pojo = new PojoImpl();\n    producer = env.createProducer(pojo, null);\n\n    SwaggerProducerOperation swaggerProducerOperation = producer.findOperation(\"testBytes\");\n    Assertions.assertEquals(true,\n        swaggerProducerOperation.getSwaggerOperation().getOperation().getRequestBody() != null);\n    Assertions.assertEquals(null, swaggerProducerOperation.getSwaggerParameterType(\"bytes\"));\n\n    swaggerProducerOperation = producer.findOperation(\"testSimple\");\n    Assertions.assertEquals(true,\n        swaggerProducerOperation.getSwaggerOperation().getOperation().getRequestBody() != null);\n    Assertions.assertEquals(Object.class, swaggerProducerOperation.getSwaggerParameterType(\n        (String) swaggerProducerOperation.getSwaggerOperation().getOperation().getRequestBody().getExtensions()\n            .get(SwaggerConst.EXT_BODY_NAME)));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/TestSwaggerInvocation.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation;\n\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestSwaggerInvocation {\n  @Test\n  public void construct_withContext() {\n    InvocationContext parentContext = new InvocationContext();\n    parentContext.addContext(\"k\", \"v\");\n    parentContext.addLocalContext(\"k\", 1);\n    ContextUtils.setInvocationContext(parentContext);\n\n    try {\n      SwaggerInvocation invocation = new SwaggerInvocation();\n      Assertions.assertSame(parentContext, invocation.getParentContext());\n      Assertions.assertEquals(\"v\", invocation.getContext(\"k\"));\n      Assertions.assertEquals(1, (int) invocation.getLocalContext(\"k\"));\n    } finally {\n      ContextUtils.removeInvocationContext();\n    }\n  }\n\n  @Test\n  public void construct_noContext() {\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Assertions.assertNull(invocation.getParentContext());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestJaxrsV1V1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBeanParamV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestJaxrsV1V1 {\n  @Test\n  public void should_mapper_consumer_multi_args_to_swagger_multi_args() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  interface ConsumerAddV1_diff_order {\n    int add(int y, int x);\n  }\n\n  @Test\n  public void should_mapper_consumer_multi_args_to_swagger_multi_args_with_diff_order() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1_diff_order.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_multi_args_to_swagger_multi_args_gen_by_BeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_multi_args_to_swagger_body() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_wrapped_body_to_swagger_multi_args() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_wrapped_body_to_swagger_multi_args_gen_by_BeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_body_to_swagger_body() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV1.class);\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestJaxrsV1V2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBeanParamV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestJaxrsV1V2 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addBeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV2.class);\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestJaxrsV2V1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBeanParamV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestJaxrsV2V1 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_addBeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV1.class);\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestJaxrsV2V2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBeanParamV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestJaxrsV2V2 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addBeanParam() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBeanParamV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(JaxrsAddBodyV2.class);\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestPojoOneArg.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerOneArg;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoOneArg;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestPojoOneArg {\n  @Test\n  public void should_mapper_consumer_simple_to_swagger_body() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoOneArg.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerOneArg.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"simple\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"name\", \"name\");\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"simpleBody\");\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertEquals(\"name\", result.get(\"name\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_bean_to_swagger_body() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoOneArg.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerOneArg.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"bean\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"user\", new User());\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertSame(arguments.get(\"user\"), result.get(\"user\"));\n  }\n\n  @Test\n  public void should_mapper_consumer_enum_to_swagger_body_field() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoOneArg.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerOneArg.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"enumBody\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"color\", Color.BLUE);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"enumBodyBody\");\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertEquals(Color.BLUE, result.get(\"color\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestPojoV1V1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddWithContext;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestPojoV1V1 {\n  @Test\n  public void add_add_class() {\n    add_add(PojoAddV1.class);\n  }\n\n  @Test\n  public void add_add_interface() {\n    add_add(ConsumerAddV1.class);\n  }\n\n  public void add_add(Class<?> clazz) {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(clazz);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV1.class);\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    AddWrapperV1 wrapperV1 = (AddWrapperV1) result.get(\"addBody\");\n    Assertions.assertEquals(1, wrapperV1.getX());\n    Assertions.assertEquals(2, wrapperV1.y);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n\n  @Test\n  public void addWithContext_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddWithContext.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    InvocationContext invocationContext = new InvocationContext();\n    invocationContext.addContext(\"k1\", \"v1\");\n    invocationContext.addContext(\"k2\", \"v2\");\n    invocationContext.addLocalContext(\"k3\", \"v3\");\n    invocationContext.addLocalContext(\"k4\", \"v4\");\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"context\", invocationContext);\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, result.get(\"x\"));\n    Assertions.assertEquals(2, result.get(\"y\"));\n\n    Assertions.assertEquals(2, invocation.getContext().size());\n    Assertions.assertEquals(\"v1\", invocation.getContext().get(\"k1\"));\n    Assertions.assertEquals(\"v2\", invocation.getContext().get(\"k2\"));\n\n    Assertions.assertEquals(2, invocation.getLocalContext().size());\n    Assertions.assertEquals(\"v3\", invocation.getLocalContext().get(\"k3\"));\n    Assertions.assertEquals(\"v4\", invocation.getLocalContext().get(\"k4\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestPojoV1V2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestPojoV1V2 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestPojoV2V1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestPojoV2V1 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestPojoV2V2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestPojoV2V2 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(PojoAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(arguments.get(\"addBody\"), result.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestSpringmvcV1V1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddWrapperV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport org.junit.jupiter.api.Assertions;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestSpringmvcV1V1 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestSpringmvcV1V2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddWrapperV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport org.junit.jupiter.api.Assertions;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestSpringmvcV1V2 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertNull(result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV1.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV1(1, 2));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestSpringmvcV2V1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddWrapperV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.junit.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\nimport org.junit.jupiter.api.Assertions;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestSpringmvcV2V1 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"x-z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV1.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/TestSpringmvcV2V2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.consumer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapper;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.ConsumerAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddBodyV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddWrapperV2;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\n@SuppressWarnings(\"unchecked\")\npublic class TestSpringmvcV2V2 {\n  @Test\n  public void add_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void add_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    arguments.put(\"z\", 3);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    result = (Map<String, Object>) result.get(\"addBody\");\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_add() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addWrapper() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddWrapperV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n    Assertions.assertEquals(3, (int) result.get(\"x-z\"));\n  }\n\n  @Test\n  public void addBody_addBody() {\n    SwaggerEnvironment environment = new SwaggerEnvironment();\n    OpenAPI swagger = SwaggerGenerator.generate(SpringmvcAddBodyV2.class);\n\n    SwaggerConsumer swaggerConsumer = environment.createConsumer(ConsumerAddBodyV2.class, swagger);\n    ArgumentsMapper mapper = swaggerConsumer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", new AddWrapperV2(1, 2, 3));\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.invocationArgumentToSwaggerArguments(invocation, arguments);\n\n    Assertions.assertSame(result.get(\"addBody\"), arguments.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/producer/TestJaxrs.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBeanParamV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.JaxrsAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddBeanParamV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestJaxrs {\n  @Test\n  public void add() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new JaxrsAddV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBeanParam() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new JaxrsAddBeanParamV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    AddBeanParamV1 paramV1 = (AddBeanParamV1) result.get(\"wrapper\");\n    Assertions.assertEquals(1, paramV1.getX());\n    Assertions.assertEquals(2, paramV1.y);\n  }\n\n  @Test\n  public void addBody() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new JaxrsAddBodyV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    AddWrapperV1 addBody = new AddWrapperV1();\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", addBody);\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertSame(addBody, result.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/producer/TestPojo.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoAddWithContextV1;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestPojo {\n  static Map<String, Object> addBody = new HashMap<>();\n\n  static {\n    addBody.put(\"x\", 1);\n    addBody.put(\"y\", 2);\n  }\n\n  @Test\n  public void add() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new PojoAddV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", addBody);\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addBody() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new PojoAddBodyV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", addBody);\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertSame(addBody, result.get(\"addBody\"));\n  }\n\n  @Test\n  public void addWithContext_add() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new PojoAddWithContextV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", addBody);\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(3, result.size());\n    Assertions.assertSame(invocation, result.get(\"context\"));\n    Assertions.assertEquals(1, result.get(\"x\"));\n    Assertions.assertEquals(2, result.get(\"y\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/producer/TestPojoOneArg.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.schemas.PojoOneArg;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestPojoOneArg {\n  @Test\n  public void should_mapper_swagger_wrapped_body_field_to_producer_enum() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new PojoOneArg(), null);\n    SwaggerProducerOperation swaggerProducerOperation = swaggerProducer.findOperation(\"enumBody\");\n    Assertions.assertEquals(\"enumBodyBody\",\n        swaggerProducerOperation.getSwaggerOperation().getOperation().getRequestBody().getExtensions().get(SwaggerConst.EXT_BODY_NAME));\n\n    ProducerArgumentsMapper mapper = swaggerProducerOperation.getArgumentsMapper();\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Map<String, Object> swaggerArguments = new HashMap<>();\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"color\", \"BLUE\");\n    swaggerArguments.put(\"enumBodyBody\", arguments);\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, swaggerArguments);\n\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertSame(Color.BLUE, result.get(\"color\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/arguments/producer/TestSpringmvc.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.arguments.producer;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.invocation.SwaggerInvocation;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddBodyV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.SpringmvcAddWrapperV1;\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestSpringmvc {\n  @Test\n  public void add() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new SpringmvcAddV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(2, result.size());\n    Assertions.assertEquals(1, (int) result.get(\"x\"));\n    Assertions.assertEquals(2, (int) result.get(\"y\"));\n  }\n\n  @Test\n  public void addWrapper() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new SpringmvcAddWrapperV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"x\", 1);\n    arguments.put(\"y\", 2);\n    SwaggerInvocation invocation = new SwaggerInvocation();\n\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    AddWrapperV1 paramV1 = (AddWrapperV1) result.get(\"wrapper\");\n    Assertions.assertEquals(1, paramV1.getX());\n    Assertions.assertEquals(2, paramV1.y);\n  }\n\n  @Test\n  public void addBody() {\n    SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new SpringmvcAddBodyV1(), null);\n    ProducerArgumentsMapper mapper = swaggerProducer.findOperation(\"add\").getArgumentsMapper();\n\n    AddWrapperV1 addBody = new AddWrapperV1();\n    Map<String, Object> arguments = new HashMap<>();\n    arguments.put(\"addBody\", addBody);\n\n    SwaggerInvocation invocation = new SwaggerInvocation();\n    Map<String, Object> result = mapper.swaggerArgumentToInvocationArguments(invocation, arguments);\n\n    Assertions.assertEquals(1, result.size());\n    Assertions.assertSame(addBody, result.get(\"addBody\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/context/TestContextUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.context;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestContextUtils {\n  @Test\n  public void getFromCompletableFuture() {\n    Assertions.assertNull(ContextUtils.getFromCompletableFuture(new CompletableFuture<>()));\n\n    InvocationContext context = new InvocationContext();\n    Assertions\n            .assertSame(context, ContextUtils.getFromCompletableFuture(new InvocationContextCompletableFuture<>(context)));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/context/TestInvocationContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.context;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport jakarta.ws.rs.core.Response.Status.Family;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestInvocationContext {\n  @Test\n  public void addContext() {\n    InvocationContext invocationContext = new InvocationContext();\n    invocationContext.addContext(\"key1\", \"value1\");\n    Assertions.assertEquals(1, invocationContext.getContext().size());\n    Assertions.assertEquals(\"value1\", invocationContext.getContext(\"key1\"));\n\n    Map<String, String> otherContext = new HashMap<>();\n    otherContext.put(\"key2\", \"value2\");\n    invocationContext.addContext(otherContext);\n    Assertions.assertEquals(2, invocationContext.getContext().size());\n    Assertions.assertEquals(\"value2\", invocationContext.getContext(\"key2\"));\n\n    InvocationContext invocationContext2 = new InvocationContext();\n    Map<String, String> otherContext2 = new HashMap<>();\n    otherContext2.put(\"key3\", \"value3\");\n    invocationContext2.setContext(otherContext2);\n    invocationContext.addContext(invocationContext2);\n    Assertions.assertEquals(3, invocationContext.getContext().size());\n  }\n\n  @Test\n  public void mergeMapContext() {\n    InvocationContext invocationContext = new InvocationContext();\n    Map<String, String> otherContext = new HashMap<>();\n    otherContext.put(\"key1\", \"value1\");\n    //otherContext's size is large than old.\n    invocationContext.mergeContext(otherContext);\n    Assertions.assertEquals(1, invocationContext.getContext().size());\n    Assertions.assertEquals(\"value1\", invocationContext.getContext(\"key1\"));\n\n    otherContext.put(\"key1\", \"value2\");\n    //otherContext's size is not large than old.\n    invocationContext.mergeContext(otherContext);\n    Assertions.assertEquals(1, invocationContext.getContext().size());\n    Assertions.assertEquals(\"value2\", invocationContext.getContext(\"key1\"));\n  }\n\n  @Test\n  public void mergeInvocationContext() {\n    InvocationContext invocationContext = new InvocationContext();\n    Map<String, String> otherContext = new HashMap<>();\n    otherContext.put(\"key1\", \"value1\");\n    InvocationContext context2 = new InvocationContext();\n    context2.setContext(otherContext);\n    invocationContext.mergeContext(context2);\n    Assertions.assertEquals(1, invocationContext.getContext().size());\n    Assertions.assertEquals(\"value1\", invocationContext.getContext(\"key1\"));\n  }\n\n  @Test\n  public void addLocalContext() {\n    InvocationContext invocationContext = new InvocationContext();\n    invocationContext.addLocalContext(\"key1\", \"value1\");\n    Assertions.assertEquals(1, invocationContext.getLocalContext().size());\n    Assertions.assertEquals(\"value1\", invocationContext.getLocalContext(\"key1\"));\n\n    Map<String, Object> otherContext = new HashMap<>();\n    otherContext.put(\"key2\", \"value2\");\n    invocationContext.addLocalContext(otherContext);\n    Assertions.assertEquals(2, invocationContext.getLocalContext().size());\n    Assertions.assertEquals(\"value2\", invocationContext.getLocalContext(\"key2\"));\n  }\n\n  @Test\n  public void setStatus() {\n    InvocationContext invocationContext = new InvocationContext();\n    invocationContext.setStatus(200);\n    System.out.println(invocationContext.getStatus().getFamily());\n    Assertions.assertEquals(200, invocationContext.getStatus().getStatusCode());\n    Assertions.assertEquals(\"OK\", invocationContext.getStatus().getReasonPhrase());\n    Assertions.assertEquals(Family.SUCCESSFUL, invocationContext.getStatus().getFamily());\n\n    invocationContext.setStatus(200, \"TEST\");\n    Assertions.assertEquals(200, invocationContext.getStatus().getStatusCode());\n    Assertions.assertEquals(\"TEST\", invocationContext.getStatus().getReasonPhrase());\n    Assertions.assertEquals(Family.SUCCESSFUL, invocationContext.getStatus().getFamily());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.util.Arrays;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class PartListToPartArrayConverterTest {\n  PartListToPartArrayConverter converter = new PartListToPartArrayConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertEquals(\"java.util.List<jakarta.servlet.http.Part>\", converter.getSrcType().getTypeName());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(Part[].class.getCanonicalName(), converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    Object parts = converter.convert(Arrays.asList(new FilePart(\"name\", \"file\")));\n    MatcherAssert.assertThat(parts, Matchers.instanceOf(Part[].class));\n  }\n\n  @Test\n  public void should_got_null_when_convert_null() {\n    Assertions.assertNull(converter.convert(null));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class PartListToPartListConverterTest {\n  PartListToPartListConverter converter = new PartListToPartListConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertEquals(\"java.util.List<jakarta.servlet.http.Part>\", converter.getSrcType().getTypeName());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(\"java.util.List<jakarta.servlet.http.Part>\", converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    List<Part> parts = Arrays.asList(new FilePart(\"name\", \"file\"));\n    Assertions.assertSame(parts, converter.convert(parts));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.part.FilePart;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class PartToPartConverterTest {\n  PartToPartConverter converter = new PartToPartConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertEquals(Part.class.getName(), converter.getSrcType().getTypeName());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(Part.class.getName(), converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    Part part = new FilePart(\"name\", \"file\");\n    Assertions.assertSame(part, converter.convert(part));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/TestBytesToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport jakarta.servlet.http.Part;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestBytesToPartConverter {\n  BytesToPartConverter converter = new BytesToPartConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertSame(byte[].class, converter.getSrcType());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(Part.class.getName(), converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    Object part = converter.convert(new byte[] {});\n    MatcherAssert.assertThat(part, Matchers.instanceOf(Part.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/TestFileToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.io.File;\n\nimport jakarta.servlet.http.Part;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestFileToPartConverter {\n  FileToPartConverter converter = new FileToPartConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertEquals(File.class.getName(), converter.getSrcType().getTypeName());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(Part.class.getName(), converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    File file = new File(\"abc\");\n    Object part = converter.convert(file);\n    MatcherAssert.assertThat(part, Matchers.instanceOf(Part.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/TestInputStreamToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\n\nimport jakarta.servlet.http.Part;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestInputStreamToPartConverter {\n  InputStreamToPartConverter converter = new InputStreamToPartConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertEquals(InputStream.class.getName(), converter.getSrcType().getTypeName());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(Part.class.getName(), converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    Object part = converter.convert(new ByteArrayInputStream(new byte[] {}));\n    MatcherAssert.assertThat(part, Matchers.instanceOf(Part.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/TestResourceToPartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter.impl.part;\n\nimport java.io.ByteArrayInputStream;\n\nimport jakarta.servlet.http.Part;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.core.io.InputStreamResource;\nimport org.springframework.core.io.Resource;\n\npublic class TestResourceToPartConverter {\n  ResourceToPartConverter converter = new ResourceToPartConverter();\n\n  @Test\n  public void getSrcType() {\n    Assertions.assertEquals(Resource.class.getName(), converter.getSrcType().getTypeName());\n  }\n\n  @Test\n  public void getTargetType() {\n    Assertions.assertEquals(Part.class.getName(), converter.getTargetType().getTypeName());\n  }\n\n  @Test\n  public void convert() {\n    Object part = converter.convert(new InputStreamResource(new ByteArrayInputStream(new byte[] {})));\n    MatcherAssert.assertThat(part, Matchers.instanceOf(Part.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/CommonExceptionDataTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.exception;\n\nimport static com.google.common.collect.ImmutableMap.of;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.Map;\n\nimport org.junit.jupiter.api.Test;\n\nimport io.vertx.core.json.Json;\n\nclass CommonExceptionDataTest {\n  @Test\n  void should_not_include_code_in_json_when_code_is_null() {\n    CommonExceptionData data = new CommonExceptionData(\"msg\");\n\n    assertThat(Json.encode(data)).isEqualTo(\"{\\\"message\\\":\\\"msg\\\"}\");\n  }\n\n  @Test\n  void should_include_code_in_json_when_code_is_not_null() {\n    CommonExceptionData data = new CommonExceptionData(\"code\", \"msg\");\n\n    String json = Json.encode(data);\n    @SuppressWarnings(\"unchecked\")\n    Map<String, Object> obj = Json.decodeValue(json, Map.class);\n\n    assertThat(obj).containsEntry(\"code\", \"code\").containsEntry(\"message\", \"msg\").hasSize(2);\n  }\n\n  @Test\n  void should_include_dynamic_field_in_json() {\n    CommonExceptionData data = new CommonExceptionData(\"msg\");\n    data.putDynamic(\"k\", \"v\");\n\n    assertThat(Json.encode(data)).isEqualTo(\"{\\\"message\\\":\\\"msg\\\",\\\"k\\\":\\\"v\\\"}\");\n  }\n\n  @Test\n  void should_decode_dynamic_field_from_json() {\n    String json = \"{\\\"message\\\":\\\"msg\\\",\\\"k\\\":\\\"v\\\"}\";\n    CommonExceptionData data = Json.decodeValue(json, CommonExceptionData.class);\n\n    assertThat(data.getMessage()).isEqualTo(\"msg\");\n    assertThat(data.getDynamic()).isEqualTo(of(\"k\", \"v\"));\n    assertThat(Json.encode(data)).isEqualTo(json);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/models/JaxrsImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.models;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport jakarta.ws.rs.CookieParam;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.PathParam;\nimport jakarta.ws.rs.Produces;\nimport jakarta.ws.rs.QueryParam;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\n@Path(\"/JaxrsImpl\")\n@Produces(MediaType.APPLICATION_JSON)\npublic class JaxrsImpl {\n  @Path(\"/testTwoSimple\")\n  @GET\n  public int testSimple(@PathParam(\"a\") int a, @QueryParam(\"b\") int b, @HeaderParam(\"c\") int c) {\n    return a - b - c;\n  }\n\n  @Path(\"/testObject\")\n  @POST\n  public Person testObject(Person user) {\n    user.setName(\"hello \" + user.getName());\n    return user;\n  }\n\n  @Path(\"/testSimpleAndObject\")\n  @POST\n  public String testSimpleAndObject(@CookieParam(\"prefix\") String prefix, Person user) {\n    return prefix + \" \" + user.getName();\n  }\n\n  @Path(\"/testContext\")\n  @POST\n  public String testContext(InvocationContext context, @FormParam(\"form\") String name) {\n    context.addContext(\"name\", name);\n    return name + \" sayhi\";\n  }\n\n  @Path(\"/bytes\")\n  @POST\n  public byte[] testBytes(byte[] input) {\n    return input;\n  }\n\n  @Path(\"/listBytes\")\n  @POST\n  public List<byte[]> testListBytes(List<byte[]> bytes) {\n    return bytes;\n  }\n\n  @Path(\"/testArrayArray\")\n  @POST\n  public String[] testArrayArray(String[] s) {\n    return s;\n  }\n\n  @Path(\"/testArrayList\")\n  @POST\n  public List<String> testArrayList(String[] s) {\n    return Arrays.asList(s);\n  }\n\n  @Path(\"/testListArray\")\n  @POST\n  public String[] testListArray(List<String> s) {\n    return s.toArray(new String[0]);\n  }\n\n  @Path(\"/testListList\")\n  @POST\n  public List<String> testListList(List<String> s) {\n    return s;\n  }\n\n  @Path(\"/testObjectArrayArray\")\n  @POST\n  public Person[] testObjectArrayArray(Person[] s) {\n    return s;\n  }\n\n  @Path(\"/testObjectArrayList\")\n  @POST\n  public List<Person> testObjectArrayList(Person[] s) {\n    return Arrays.asList(s);\n  }\n\n  @Path(\"/testObjectListArray\")\n  @POST\n  public Person[] testObjectListArray(List<Person> s) {\n    return s.toArray(new Person[0]);\n  }\n\n  @Path(\"/testObjectListList\")\n  @POST\n  public List<Person> testObjectListList(List<Person> s) {\n    return s;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/models/Person.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.models;\n\npublic class Person {\n  private String name;\n\n  public Person() {\n  }\n\n  public Person(String name) {\n    this.name = name;\n  }\n\n  public void setName(String name) {\n    this.name = name;\n  }\n\n  public String getName() {\n    return this.name;\n  }\n\n  @Override\n  public String toString() {\n    return name;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/models/PojoConsumerIntf.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.models;\n\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\npublic interface PojoConsumerIntf {\n  int testSimple(int a, int b, int c);\n\n  Person testObject(Person user);\n\n  @Operation(operationId = \"testObject\", summary = \"\")\n  CompletableFuture<Person> testObjectAsync(Person user);\n\n  String testSimpleAndObject(String prefix, Person user);\n\n  String testContext(InvocationContext context, String name);\n\n  List<byte[]> testListBytes(List<byte[]> bytes);\n\n  byte[] testBytes(byte[] bytes);\n\n  String[] testArrayArray(String[] s);\n\n  List<String> testArrayList(String[] s);\n\n  String[] testListArray(List<String> s);\n\n  List<String> testListList(List<String> s);\n\n  Person[] testObjectArrayArray(Person[] s);\n\n  List<Person> testObjectArrayList(Person[] s);\n\n  Person[] testObjectListArray(List<Person> s);\n\n  List<Person> testObjectListList(List<Person> s);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/models/PojoImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.models;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\nimport io.swagger.v3.oas.annotations.Operation;\n\npublic class PojoImpl {\n  public int testSimple(int a, int b, int c) {\n    return a - b - c;\n  }\n\n  public Person testObject(Person user) {\n    user.setName(\"hello \" + user.getName());\n    return user;\n  }\n\n  @Operation(operationId = \"testSimpleAndObject\", summary = \"\")\n  public CompletableFuture<String> testSimpleAndObjectAsync(String prefix, Person user) {\n    CompletableFuture<String> future = new CompletableFuture<>();\n    future.complete(prefix + \" \" + user.getName());\n    return future;\n  }\n\n  public String testContext(InvocationContext context, String name) {\n    context.addContext(\"name\", name);\n    return name + \" sayhi\";\n  }\n\n  public List<byte[]> testListBytes(List<byte[]> bytes) {\n    return bytes;\n  }\n\n  public byte[] testBytes(byte[] bytes) {\n    return bytes;\n  }\n\n  public String[] testArrayArray(String[] s) {\n    return s;\n  }\n\n  public List<String> testArrayList(String[] s) {\n    return Arrays.asList(s);\n  }\n\n  public String[] testListArray(List<String> s) {\n    return s.toArray(new String[0]);\n  }\n\n  public List<String> testListList(List<String> s) {\n    return s;\n  }\n\n  public Person[] testObjectArrayArray(Person[] s) {\n    return s;\n  }\n\n  public List<Person> testObjectArrayList(Person[] s) {\n    return Arrays.asList(s);\n  }\n\n  public Person[] testObjectListArray(List<Person> s) {\n    return s.toArray(new Person[0]);\n  }\n\n  public List<Person> testObjectListList(List<Person> s) {\n    return s;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/models/ProducerImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.models;\n\n\nimport io.swagger.v3.oas.annotations.Operation;\n\npublic class ProducerImpl {\n  @Operation(summary = \"\", hidden = true)\n  public int hiddenMethod(int a) {\n    return a;\n  }\n\n  @Operation(summary = \"\")\n  public int visibleMethod(int a) {\n    return a;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/models/SpringmvcImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.models;\n\npublic class SpringmvcImpl {\n\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response;\n\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.swagger.v3.oas.annotations.headers.Header;\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.annotations.responses.ApiResponses;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport io.swagger.v3.oas.models.Operation;\n\npublic class TestResponsesMeta {\n  static class ResponseMetaImpl {\n    @ApiResponses({@ApiResponse(responseCode = \"400\", description = \"\",\n        content = {@Content(schema = @Schema(implementation = String.class))}),\n        @ApiResponse(responseCode = \"401\", description = \"\",\n            content = {@Content(schema = @Schema(implementation = String.class))},\n            headers = {@Header(name = \"h1\", schema = @Schema(implementation = String.class))})\n    })\n    public int add(int x, int y) {\n      return x + y;\n    }\n  }\n\n  @Test\n  public void test() {\n    OpenAPI swagger = SwaggerGenerator.generate(ResponseMetaImpl.class);\n    Operation operation = swagger.getPaths().get(\"/add\").getPost();\n\n    ResponsesMeta meta = new ResponsesMeta();\n    meta.init(swagger, operation);\n\n    JavaType resp = meta.findResponseType(200);\n    Assertions.assertEquals(Integer.class, resp.getRawClass());\n\n    resp = meta.findResponseType(201);\n    Assertions.assertEquals(Integer.class, resp.getRawClass());\n\n    resp = meta.findResponseType(400);\n    Assertions.assertEquals(String.class, resp.getRawClass());\n\n    resp = meta.findResponseType(401);\n    Assertions.assertEquals(String.class, resp.getRawClass());\n\n    resp = meta.findResponseType(500);\n    // changed to Object for new version to keep user defined error data not lose and can be parsed.\n    Assertions.assertEquals(Object.class, resp.getRawClass());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/consumer/TestConsumerResponseMapperFactories.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.consumer;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.Optional;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class TestConsumerResponseMapperFactories {\n  interface ConsumerResponseForTest {\n    String normal();\n\n    CompletableFuture<String> async();\n\n    @ApiResponse(responseCode = \"200\", description = \"\", content =\n        {@Content(schema = @Schema(implementation = String.class))})\n    Response scbResponse();\n\n    @ApiResponse(responseCode = \"200\", description = \"\", content =\n        {@Content(schema = @Schema(implementation = String.class))})\n    jakarta.ws.rs.core.Response jaxrsResponse();\n\n    Optional<String> optional();\n  }\n\n  SwaggerEnvironment environment = new SwaggerEnvironment();\n\n  SwaggerConsumer swaggerConsumer;\n\n  String result = \"abc\";\n\n  Response response = Response.ok(result);\n\n  @Before\n  public void setup() {\n    OpenAPI swagger = SwaggerGenerator.generate(ConsumerResponseForTest.class);\n    swaggerConsumer = environment.createConsumer(ConsumerResponseForTest.class, swagger);\n  }\n\n  @Test\n  public void should_mapper_to_normal_string() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"normal\");\n    assertThat(operation.getResponseMapper()).isInstanceOf(DefaultConsumerResponseMapper.class);\n    Assertions.assertEquals(result, operation.getResponseMapper().mapResponse(response));\n  }\n\n  @Test\n  public void should_mapper_to_completableFuture_element_string() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"async\");\n    assertThat(operation.getResponseMapper()).isInstanceOf(DefaultConsumerResponseMapper.class);\n    Assertions.assertEquals(result, operation.getResponseMapper().mapResponse(response));\n  }\n\n  @Test\n  public void should_mapper_to_scbResponse_string() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"scbResponse\");\n    assertThat(operation.getResponseMapper().getClass().getName())\n        .startsWith(CseResponseConsumerResponseMapperFactory.class.getName());\n    Response scbResponse = (Response) operation.getResponseMapper().mapResponse(response);\n    Assertions.assertEquals(result, scbResponse.getResult());\n  }\n\n  @Test\n  public void should_mapper_to_optional_string() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"optional\");\n    assertThat(operation.getResponseMapper()).isInstanceOf(OptionalConsumerResponseMapper.class);\n    @SuppressWarnings(\"unchecked\")\n    Optional<String> optional = (Optional<String>) operation.getResponseMapper().mapResponse(response);\n    Assertions.assertEquals(result, optional.get());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/producer/TestProducerResponseMapperFactories.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.response.producer;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.Optional;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducer;\nimport org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class TestProducerResponseMapperFactories {\n  static class ResponseForTest {\n    public String normal() {\n      return \"normal\";\n    }\n\n    public CompletableFuture<String> async() {\n      return CompletableFuture.completedFuture(\"async\");\n    }\n\n    @ApiResponse(responseCode = \"200\", description = \"\",\n        content = {@Content(schema = @Schema(implementation = String.class))})\n    public Response scbResponse() {\n      return Response.ok(\"scb\");\n    }\n\n    @ApiResponse(responseCode = \"200\", description = \"\",\n        content = {@Content(schema = @Schema(implementation = String.class))})\n    public jakarta.ws.rs.core.Response jaxrsResponse() {\n      return jakarta.ws.rs.core.Response.ok(\"jaxrs\").build();\n    }\n\n    public Optional<String> optional() {\n      return Optional.of(\"optional\");\n    }\n  }\n\n  static SwaggerEnvironment environment = new SwaggerEnvironment();\n\n  static SwaggerProducer swaggerProducer;\n\n  static ResponseForTest instance = new ResponseForTest();\n\n  static String result = \"abc\";\n\n  static Response response = Response.ok(result);\n\n  @BeforeClass\n  public static void setup() {\n    swaggerProducer = environment.createProducer(instance);\n  }\n\n  @Test\n  public void should_mapper_to_normal_string() {\n    SwaggerProducerOperation operation = swaggerProducer.findOperation(\"normal\");\n    assertThat(operation.getResponseMapper()).isInstanceOf(DefaultProducerResponseMapper.class);\n    assertThat((String) operation.getResponseMapper().mapResponse(Status.OK, instance.normal()).getResult())\n        .isEqualTo(\"normal\");\n  }\n\n  @Test\n  public void should_mapper_to_completableFuture_element_string() throws ExecutionException, InterruptedException {\n    SwaggerProducerOperation operation = swaggerProducer.findOperation(\"async\");\n    assertThat(operation.getResponseMapper()).isInstanceOf(DefaultProducerResponseMapper.class);\n    assertThat((String) operation.getResponseMapper().mapResponse(Status.OK, instance.async().get()).getResult())\n        .isEqualTo(\"async\");\n  }\n\n  @Test\n  public void should_mapper_to_scbResponse_string() {\n    SwaggerProducerOperation operation = swaggerProducer.findOperation(\"scbResponse\");\n    assertThat(operation.getResponseMapper().getClass().getName())\n        .startsWith(CseResponseProducerResponseMapperFactory.class.getName());\n    assertThat((String) operation.getResponseMapper().mapResponse(Status.OK, instance.scbResponse()).getResult())\n        .isEqualTo(\"scb\");\n  }\n\n  @Test\n  public void should_mapper_to_optional_string() {\n    SwaggerProducerOperation operation = swaggerProducer.findOperation(\"optional\");\n    assertThat(operation.getResponseMapper()).isInstanceOf(OptionalProducerResponseMapper.class);\n    assertThat((String) operation.getResponseMapper().mapResponse(Status.OK, instance.optional()).getResult())\n        .isEqualTo(\"optional\");\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/ConsumerAddBodyV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\n\npublic interface ConsumerAddBodyV1 {\n  int add(AddWrapperV1 addBody);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/ConsumerAddBodyV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\n\npublic interface ConsumerAddBodyV2 {\n  int add(AddWrapperV2 addBody);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/ConsumerAddV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\npublic interface ConsumerAddV1 {\n  int add(int x, int y);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/ConsumerAddV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\n\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic interface ConsumerAddV2 {\n  int add(int x, int y, @Parameter(name = \"x-z\") int z);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/ConsumerAddWithContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic interface ConsumerAddWithContext {\n  int add(InvocationContext context, int x, int y);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/ConsumerOneArg.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\npublic interface ConsumerOneArg {\n  void simple(String name);\n\n  void bean(User user);\n\n  void enumBody(Color color);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/JaxrsAddBeanParamV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport jakarta.ws.rs.BeanParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddBeanParamV1;\n\n@Path(\"/\")\npublic class JaxrsAddBeanParamV1 {\n  @Path(\"/add\")\n  @GET\n  public int add(@BeanParam AddBeanParamV1 wrapper) {\n    return wrapper.getX() + wrapper.y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/JaxrsAddBeanParamV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport jakarta.ws.rs.BeanParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddBeanParamV2;\n\n@Path(\"/\")\npublic interface JaxrsAddBeanParamV2 {\n  @Path(\"/add\")\n  @GET\n  int add(@BeanParam AddBeanParamV2 wrapper);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/JaxrsAddBodyV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\n\n@Path(\"/\")\npublic class JaxrsAddBodyV1 {\n  @Path(\"/add\")\n  @POST\n  public int add(AddWrapperV1 addBody) {\n    return addBody.getX() + addBody.y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/JaxrsAddBodyV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\n\n@Path(\"/\")\npublic interface JaxrsAddBodyV2 {\n  @Path(\"/add\")\n  @POST\n  int add(AddWrapperV2 addBody);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/JaxrsAddV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\n@Path(\"/\")\npublic class JaxrsAddV1 {\n  @Path(\"/add\")\n  @GET\n  public int add(@QueryParam(\"x\") int x, @QueryParam(\"y\") int y) {\n    return x + y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/JaxrsAddV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\n@Path(\"/\")\npublic interface JaxrsAddV2 {\n  @Path(\"/add\")\n  @GET\n  int add(@QueryParam(\"x\") int x, @QueryParam(\"y\") int y, @HeaderParam(\"x-z\") int z);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/PojoAddBodyV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\n\npublic class PojoAddBodyV1 {\n  public int add(AddWrapperV1 addBody) {\n    return addBody.getX() + addBody.y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/PojoAddBodyV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\n\npublic interface PojoAddBodyV2 {\n  int add(AddWrapperV2 addBody);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/PojoAddV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\npublic class PojoAddV1 {\n  public int add(int x, int y) {\n    return x + y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/PojoAddV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport io.swagger.v3.oas.annotations.Parameter;\n\npublic interface PojoAddV2 {\n  int add(int x, int y, @Parameter(name = \"x-z\") int z);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/PojoAddWithContextV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\npublic class PojoAddWithContextV1 {\n  public int add(InvocationContext context, int x, int y) {\n    return x + y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/PojoOneArg.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.foundation.test.scaffolding.model.Color;\nimport org.apache.servicecomb.foundation.test.scaffolding.model.User;\n\npublic class PojoOneArg {\n  public void simple(String name) {\n\n  }\n\n  public void bean(User user) {\n\n  }\n\n  public void enumBody(Color color) {\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/SpringmvcAddBodyV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping\npublic class SpringmvcAddBodyV1 {\n  @PostMapping(path = \"/add\")\n  public int add(@RequestBody AddWrapperV1 addBody) {\n    return addBody.getX() + addBody.y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/SpringmvcAddBodyV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping\npublic interface SpringmvcAddBodyV2 {\n  @PostMapping(path = \"/add\")\n  int add(@RequestBody AddWrapperV2 addBody);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/SpringmvcAddV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping\npublic class SpringmvcAddV1 {\n  @GetMapping(path = \"/add\")\n  public int add(int x, int y) {\n    return x + y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/SpringmvcAddV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestHeader;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping\npublic interface SpringmvcAddV2 {\n  @GetMapping(path = \"/add\")\n  int add(int x, int y, @RequestHeader(name = \"x-z\") int z);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/SpringmvcAddWrapperV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV1;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping\npublic class SpringmvcAddWrapperV1 {\n  @GetMapping(path = \"/add\")\n  public int add(AddWrapperV1 wrapper) {\n    return wrapper.getX() + wrapper.y;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/SpringmvcAddWrapperV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas;\n\nimport org.apache.servicecomb.swagger.invocation.schemas.models.AddWrapperV2;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@RequestMapping\npublic interface SpringmvcAddWrapperV2 {\n  @GetMapping(path = \"/add\")\n  int add(AddWrapperV2 wrapper);\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/models/AddBeanParamV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas.models;\n\nimport jakarta.ws.rs.QueryParam;\n\npublic class AddBeanParamV1 {\n  @QueryParam(\"x\")\n  private int x;\n\n  @QueryParam(\"y\")\n  public int y;\n\n  public AddBeanParamV1() {\n  }\n\n  public AddBeanParamV1(int x, int y) {\n    this.x = x;\n    this.y = y;\n  }\n\n  public int getX() {\n    return x;\n  }\n\n  public void setX(int x) {\n    this.x = x;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/models/AddBeanParamV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas.models;\n\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.QueryParam;\n\npublic class AddBeanParamV2 {\n  @QueryParam(\"x\")\n  private int x;\n\n  @QueryParam(\"y\")\n  public int y;\n\n  @HeaderParam(\"x-z\")\n  public int z;\n\n  public AddBeanParamV2(int x, int y, int z) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n  }\n\n  public int getX() {\n    return x;\n  }\n\n  public void setX(int x) {\n    this.x = x;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/models/AddWrapperV1.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas.models;\n\npublic class AddWrapperV1 {\n  private int x;\n\n  public int y;\n\n  public AddWrapperV1() {\n  }\n\n  public AddWrapperV1(int x, int y) {\n    this.x = x;\n    this.y = y;\n  }\n\n  public int getX() {\n    return x;\n  }\n\n  public void setX(int x) {\n    this.x = x;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/schemas/models/AddWrapperV2.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.schemas.models;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\n\npublic class AddWrapperV2 {\n  private int x;\n\n  public int y;\n\n  @JsonProperty(value = \"x-z\")\n  public int z;\n\n  public AddWrapperV2(int x, int y, int z) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n  }\n\n  public int getX() {\n    return x;\n  }\n\n  public void setX(int x) {\n    this.x = x;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-invocation</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-invocation-jaxrs</artifactId>\n  <name>Java Chassis::Swagger::Invocation::JAXRS</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.glassfish.jersey.core</groupId>\n      <artifactId>jersey-client</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/main/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/JaxrsConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport java.util.Map.Entry;\n\nimport jakarta.ws.rs.core.Response.ResponseBuilder;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;\n\nimport io.vertx.core.MultiMap;\n\npublic class JaxrsConsumerResponseMapper implements ConsumerResponseMapper {\n  @Override\n  public Object mapResponse(Response response) {\n    ResponseBuilder responseBuilder =\n        jakarta.ws.rs.core.Response.status(response.getStatus()).entity(response.getResult());\n\n    MultiMap headers = response.getHeaders();\n    if (headers == null) {\n      return responseBuilder.build();\n    }\n\n    for (Entry<String, String> entry : headers.entries()) {\n      responseBuilder.header(entry.getKey(), entry.getValue());\n    }\n\n    return responseBuilder.build();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/main/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/JaxrsConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.core.Response;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory;\n\npublic class JaxrsConsumerResponseMapperFactory implements ConsumerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type consumerType) {\n    return Response.class.equals(consumerType);\n  }\n\n  @Override\n  public ConsumerResponseMapper createResponseMapper(ResponseMapperFactories<ConsumerResponseMapper> factories,\n      Type consumerType) {\n    return new JaxrsConsumerResponseMapper();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/main/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/JaxrsProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport java.util.List;\nimport java.util.Map.Entry;\n\nimport jakarta.ws.rs.core.MultivaluedMap;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\n\npublic class JaxrsProducerResponseMapper implements ProducerResponseMapper {\n  @Override\n  public Response mapResponse(StatusType status, Object response) {\n    jakarta.ws.rs.core.Response jaxrsResponse = (jakarta.ws.rs.core.Response) response;\n\n    Response cseResponse = Response.status(jaxrsResponse.getStatusInfo()).entity(jaxrsResponse.getEntity());\n    MultivaluedMap<String, Object> headers = jaxrsResponse.getHeaders();\n    for (Entry<String, List<Object>> entry : headers.entrySet()) {\n      if (entry.getValue() == null) {\n        continue;\n      }\n\n      for (Object value : entry.getValue()) {\n        if (value == null) {\n          continue;\n        }\n        cseResponse.addHeader(entry.getKey(), value.toString());\n      }\n    }\n    return cseResponse;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/main/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/JaxrsProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.ws.rs.core.Response;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory;\n\npublic class JaxrsProducerResponseMapperFactory implements ProducerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type producerType) {\n    return Response.class.equals(producerType);\n  }\n\n  @Override\n  public ProducerResponseMapper createResponseMapper(ResponseMapperFactories<ProducerResponseMapper> factories,\n      Type producerType) {\n    return new JaxrsProducerResponseMapper();\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.jaxrs.response.JaxrsConsumerResponseMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.jaxrs.response.JaxrsProducerResponseMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/test/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/TestJaxrsConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\nimport io.swagger.v3.oas.annotations.media.Content;\nimport io.swagger.v3.oas.annotations.media.Schema;\nimport io.swagger.v3.oas.annotations.responses.ApiResponse;\nimport io.swagger.v3.oas.models.OpenAPI;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.core.Response;\n\npublic class TestJaxrsConsumerResponseMapper {\n  @Path(\"/\")\n  interface ConsumerResponseForTest {\n    @ApiResponse(responseCode = \"200\", description = \"\", content = @Content(schema =\n    @Schema(implementation = String.class)))\n    @Path(\"/jaxrsResponse\")\n    @GET\n    jakarta.ws.rs.core.Response jaxrsResponse();\n  }\n\n  SwaggerEnvironment environment = new SwaggerEnvironment();\n\n  SwaggerConsumer swaggerConsumer;\n\n  String result = \"abc\";\n\n  org.apache.servicecomb.swagger.invocation.Response response = org.apache.servicecomb.swagger.invocation.Response\n      .ok(result);\n\n  @BeforeEach\n  public void setup() {\n    OpenAPI swagger = SwaggerGenerator.generate(ConsumerResponseForTest.class);\n    swaggerConsumer = environment.createConsumer(ConsumerResponseForTest.class, swagger);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void jaxrsResponse() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"jaxrsResponse\");\n\n    Response jaxrsResponse = (Response) operation.getResponseMapper().mapResponse(response);\n    Assertions.assertEquals(result, jaxrsResponse.getEntity());\n    Assertions.assertTrue(jaxrsResponse.getHeaders().isEmpty());\n  }\n\n  @Test\n  public void jaxrsResponseWithHeaders() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"jaxrsResponse\");\n    response.addHeader(\"h\", \"v1\").addHeader(\"h\", \"v2\").addHeader(\"h\", null);\n    response.addHeader(\"h1\", null);\n\n    Response jaxrsResponse = (Response) operation.getResponseMapper().mapResponse(response);\n    Assertions.assertEquals(result, jaxrsResponse.getEntity());\n    Assertions.assertEquals(1, jaxrsResponse.getHeaders().size());\n    MatcherAssert.assertThat(jaxrsResponse.getHeaders().get(\"h\"), Matchers.contains(\"v1\", \"v2\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/test/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/TestJaxrsProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport jakarta.ws.rs.core.MultivaluedHashMap;\nimport jakarta.ws.rs.core.MultivaluedMap;\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\npublic class TestJaxrsProducerResponseMapper {\n  JaxrsProducerResponseMapper mapper = new JaxrsProducerResponseMapper();\n\n  @Test\n  public void mapResponse_withoutHeaders() {\n    jakarta.ws.rs.core.Response jaxrsResponse = Mockito.mock(jakarta.ws.rs.core.Response.class);\n    Mockito.when(jaxrsResponse.getStatusInfo()).thenReturn(Status.OK);\n    Mockito.when(jaxrsResponse.getEntity()).thenReturn(\"result\");\n    Mockito.when(jaxrsResponse.getHeaders()).thenReturn(new MultivaluedHashMap<>());\n\n    Response response = mapper.mapResponse(null, jaxrsResponse);\n    Assertions.assertEquals(Status.OK, response.getStatus());\n    Assertions.assertEquals(\"result\", response.getResult());\n    Assertions.assertNull(response.getHeaders());\n  }\n\n  @Test\n  public void mapResponse_withHeaders() {\n    jakarta.ws.rs.core.Response jaxrsResponse = Mockito.mock(jakarta.ws.rs.core.Response.class);\n    Mockito.when(jaxrsResponse.getStatusInfo()).thenReturn(Status.OK);\n    Mockito.when(jaxrsResponse.getEntity()).thenReturn(\"result\");\n\n    MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();\n    headers.add(\"h\", \"v\");\n    Mockito.when(jaxrsResponse.getHeaders()).thenReturn(headers);\n\n    Response response = mapper.mapResponse(null, jaxrsResponse);\n    Assertions.assertEquals(Status.OK, response.getStatus());\n    Assertions.assertEquals(\"result\", response.getResult());\n    Assertions.assertEquals(1, response.getHeaders().size());\n    MatcherAssert.assertThat(response.getHeaders(\"h\"), Matchers.contains(\"v\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/test/java/org/apache/servicecomb/swagger/invocation/jaxrs/response/TestJaxrsProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.jaxrs.response;\n\nimport jakarta.ws.rs.core.Response;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestJaxrsProducerResponseMapperFactory {\n  JaxrsProducerResponseMapperFactory factory = new JaxrsProducerResponseMapperFactory();\n\n  @Test\n  public void isMatch_true() {\n    Assertions.assertTrue(factory.isMatch(Response.class));\n  }\n\n  @Test\n  public void isMatch_false() {\n    Assertions.assertFalse(factory.isMatch(String.class));\n  }\n\n  @Test\n  public void createResponseMapper() {\n    MatcherAssert.assertThat(factory.createResponseMapper(null, null),\n        Matchers.instanceOf(JaxrsProducerResponseMapper.class));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-jaxrs/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-invocation</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-invocation-springmvc</artifactId>\n  <name>Java Chassis::Swagger::Invocation::Spring MVC</name>\n\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-webmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/converter/PartListToMultipartArrayConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport jakarta.servlet.http.Part;\n\npublic class PartListToMultipartArrayConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return ParameterizedTypeUtil.make(List.class, Part.class);\n  }\n\n  @Override\n  public Type getTargetType() {\n    return MultipartFile[].class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    if (value == null) {\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    List<Part> partList = (List<Part>) value;\n    PartToMultipartFile[] partArray = new PartToMultipartFile[partList.size()];\n    for (int i = 0; i < partArray.length; i++) {\n      partArray[i] = new PartToMultipartFile(partList.get(i));\n    }\n    return partArray;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/converter/PartListToMultipartListConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.converter;\n\nimport java.lang.reflect.Type;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.ParameterizedTypeUtil;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport jakarta.servlet.http.Part;\n\npublic class PartListToMultipartListConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return ParameterizedTypeUtil.make(List.class, Part.class);\n  }\n\n  @Override\n  public Type getTargetType() {\n    return ParameterizedTypeUtil.make(List.class, MultipartFile.class);\n  }\n\n  @Override\n  public Object convert(Object value) {\n    if (value == null) {\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    List<Part> partList = (List<Part>) value;\n    List<PartToMultipartFile> fileList = new ArrayList<>();\n    partList.forEach(part -> fileList.add(new PartToMultipartFile(part)));\n    return fileList;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/converter/PartToMultipartConverter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter;\n\nimport java.lang.reflect.Type;\n\nimport jakarta.servlet.http.Part;\n\nimport org.springframework.web.multipart.MultipartFile;\n\npublic class PartToMultipartConverter implements Converter {\n  @Override\n  public Type getSrcType() {\n    return Part.class;\n  }\n\n  @Override\n  public Type getTargetType() {\n    return MultipartFile.class;\n  }\n\n  @Override\n  public Object convert(Object value) {\n    if (value == null) {\n      return null;\n    }\n\n    return new PartToMultipartFile((Part) value);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/converter/PartToMultipartFile.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.InputStream;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.commons.io.IOUtils;\nimport org.springframework.web.multipart.MultipartFile;\n\npublic class PartToMultipartFile implements MultipartFile {\n  private final Part part;\n\n  public PartToMultipartFile(Part part) {\n    this.part = part;\n  }\n\n  @Override\n  public String getName() {\n    return part.getName();\n  }\n\n  @Override\n  public String getOriginalFilename() {\n    return part.getSubmittedFileName();\n  }\n\n  @Override\n  public String getContentType() {\n    return part.getContentType();\n  }\n\n  @Override\n  public boolean isEmpty() {\n    return part.getSize() == 0;\n  }\n\n  @Override\n  public long getSize() {\n    return part.getSize();\n  }\n\n  @Override\n  public byte[] getBytes() throws IOException {\n    try (InputStream is = getInputStream()) {\n      return IOUtils.toByteArray(is);\n    }\n  }\n\n  @Override\n  public InputStream getInputStream() throws IOException {\n    return part.getInputStream();\n  }\n\n  @Override\n  public void transferTo(File dest) throws IOException, IllegalStateException {\n    part.write(dest.getPath());\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/springmvc/response/SpringmvcConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\n\nimport io.vertx.core.MultiMap;\n\npublic class SpringmvcConsumerResponseMapper implements ConsumerResponseMapper {\n  private final ConsumerResponseMapper realMapper;\n\n  public SpringmvcConsumerResponseMapper(ConsumerResponseMapper realMapper) {\n    this.realMapper = realMapper;\n  }\n\n  @Override\n  public Object mapResponse(Response response) {\n    HttpStatus status = HttpStatus.valueOf(response.getStatusCode());\n\n    MultiMap headers = response.getHeaders();\n    if (headers == null) {\n      Object realResult = realMapper.mapResponse(response);\n      return new ResponseEntity<>(realResult, null, status);\n    }\n\n    HttpHeaders httpHeaders = new HttpHeaders();\n    for (Entry<String, String> entry : headers.entries()) {\n      httpHeaders.add(entry.getKey(), entry.getValue());\n    }\n\n    Object realResult = realMapper.mapResponse(response);\n    return new ResponseEntity<>(realResult, httpHeaders, status);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/springmvc/response/SpringmvcConsumerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory;\nimport org.springframework.http.ResponseEntity;\n\npublic class SpringmvcConsumerResponseMapperFactory implements ConsumerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type consumerType) {\n    if (!ParameterizedType.class.isAssignableFrom(consumerType.getClass())) {\n      return false;\n    }\n\n    return ((ParameterizedType) consumerType).getRawType().equals(ResponseEntity.class);\n  }\n\n  @Override\n  public ConsumerResponseMapper createResponseMapper(ResponseMapperFactories<ConsumerResponseMapper> factories,\n      Type consumerType) {\n    Type realConsumerType = ((ParameterizedType) consumerType).getActualTypeArguments()[0];\n    ConsumerResponseMapper realMapper = factories.createResponseMapper(realConsumerType);\n    return new SpringmvcConsumerResponseMapper(realMapper);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/springmvc/response/SpringmvcProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.util.List;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.context.HttpStatus;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.ResponseEntity;\n\nimport jakarta.ws.rs.core.Response.StatusType;\n\npublic class SpringmvcProducerResponseMapper implements ProducerResponseMapper {\n  private final ProducerResponseMapper realMapper;\n\n  public SpringmvcProducerResponseMapper(ProducerResponseMapper realMapper) {\n    this.realMapper = realMapper;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public Response mapResponse(StatusType status, Object response) {\n    ResponseEntity<Object> springmvcResponse = (ResponseEntity<Object>) response;\n\n    // TODO: maybe can use swagger HttpStatus instead of customized one\n    StatusType responseStatus = new HttpStatus(springmvcResponse.getStatusCode().value(), \"\");\n\n    Response cseResponse = null;\n    if (HttpStatus.isSuccess(responseStatus)) {\n      cseResponse = realMapper.mapResponse(responseStatus, springmvcResponse.getBody());\n    } else {\n      // not support fail response mapper now\n      cseResponse = Response.status(responseStatus).entity(springmvcResponse.getBody());\n    }\n\n    HttpHeaders headers = springmvcResponse.getHeaders();\n    for (Entry<String, List<String>> entry : headers.entrySet()) {\n      if (entry.getValue() == null) {\n        continue;\n      }\n\n      for (String value : entry.getValue()) {\n        cseResponse.addHeader(entry.getKey(), value);\n      }\n    }\n    return cseResponse;\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/java/org/apache/servicecomb/swagger/invocation/springmvc/response/SpringmvcProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.lang.reflect.ParameterizedType;\nimport java.lang.reflect.Type;\n\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory;\nimport org.springframework.http.ResponseEntity;\n\npublic class SpringmvcProducerResponseMapperFactory implements ProducerResponseMapperFactory {\n  @Override\n  public boolean isMatch(Type producerType) {\n    if (!ParameterizedType.class.isAssignableFrom(producerType.getClass())) {\n      return false;\n    }\n\n    return ((ParameterizedType) producerType).getRawType().equals(ResponseEntity.class);\n  }\n\n  @Override\n  public ProducerResponseMapper createResponseMapper(ResponseMapperFactories<ProducerResponseMapper> factories,\n      Type producerType) {\n    Type realProducerType = ((ParameterizedType) producerType).getActualTypeArguments()[0];\n    ProducerResponseMapper realMapper = factories.createResponseMapper(realProducerType);\n    return new SpringmvcProducerResponseMapper(realMapper);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.converter.Converter",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.converter.PartListToMultipartArrayConverter\norg.apache.servicecomb.swagger.invocation.converter.PartToMultipartConverter\norg.apache.servicecomb.swagger.invocation.converter.PartListToMultipartListConverter\norg.apache.servicecomb.swagger.invocation.converter.impl.part.ResourceToPartConverter\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.springmvc.response.SpringmvcConsumerResponseMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.swagger.invocation.springmvc.response.SpringmvcProducerResponseMapperFactory\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/test/java/org/apache/servicecomb/swagger/invocation/converter/TestPartToMultipartFile.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.swagger.invocation.converter;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.IOException;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestPartToMultipartFile {\n  @Mocked\n  Part part;\n\n  PartToMultipartFile multipartFile;\n\n  @Before\n  public void setup() {\n    multipartFile = new PartToMultipartFile(part);\n  }\n\n  @Test\n  public void getName() {\n    String name = \"paramName\";\n    new Expectations() {\n      {\n        part.getName();\n        result = name;\n      }\n    };\n\n    Assertions.assertEquals(name, multipartFile.getName());\n  }\n\n  @Test\n  public void getOriginalFilename() {\n    String submittedFileName = \"fileName\";\n    new Expectations() {\n      {\n        part.getSubmittedFileName();\n        result = submittedFileName;\n      }\n    };\n\n    Assertions.assertEquals(submittedFileName, multipartFile.getOriginalFilename());\n  }\n\n  @Test\n  public void getContentType() {\n    String contentType = \"json\";\n    new Expectations() {\n      {\n        part.getContentType();\n        result = contentType;\n      }\n    };\n\n    Assertions.assertEquals(contentType, multipartFile.getContentType());\n  }\n\n  @Test\n  public void isEmptyTrue() {\n    new Expectations() {\n      {\n        part.getSize();\n        result = 0;\n      }\n    };\n\n    Assertions.assertTrue(multipartFile.isEmpty());\n  }\n\n  @Test\n  public void isEmptyFalse() {\n    new Expectations() {\n      {\n        part.getSize();\n        result = 1;\n      }\n    };\n\n    Assertions.assertFalse(multipartFile.isEmpty());\n  }\n\n  @Test\n  public void getSize() {\n    long size = 10;\n    new Expectations() {\n      {\n        part.getSize();\n        result = size;\n      }\n    };\n\n    Assertions.assertEquals(size, multipartFile.getSize());\n  }\n\n  static class ByteArrayInputStreamForTest extends ByteArrayInputStream {\n    boolean closed;\n\n    public ByteArrayInputStreamForTest(byte[] buf) {\n      super(buf);\n    }\n\n    @Override\n    public void close() throws IOException {\n      closed = true;\n    }\n  }\n\n  @Test\n  public void getBytes_normal() throws IOException {\n    byte[] bytes = new byte[] {1, 2, 3};\n    ByteArrayInputStreamForTest is = new ByteArrayInputStreamForTest(bytes);\n    new Expectations() {\n      {\n        part.getInputStream();\n        result = is;\n      }\n    };\n\n    Assertions.assertArrayEquals(bytes, multipartFile.getBytes());\n    Assertions.assertTrue(is.closed);\n  }\n\n  @Test\n  public void getBytes_exception() throws IOException {\n    new Expectations() {\n      {\n        part.getInputStream();\n        result = new IOException(\"open stream failed\");\n      }\n    };\n\n    IOException exception = Assertions.assertThrows(IOException.class,\n            () -> multipartFile.getBytes());\n    Assertions.assertEquals(\"open stream failed\", exception.getMessage());\n  }\n\n  @Test\n  public void transferTo() throws IllegalStateException, IOException {\n    File dest = new File(\"/dest\");\n    Holder<String> destName = new Holder<>();\n    new MockUp<Part>(part) {\n      @Mock\n      void write(String fileName) throws IOException {\n        destName.value = fileName;\n      }\n    };\n\n    multipartFile.transferTo(dest);\n    Assertions.assertEquals(dest.getPath(), destName.value);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/test/java/org/apache/servicecomb/swagger/invocation/springmvc/response/TestSpringmvcConsumerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumer;\nimport org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;\nimport org.apache.servicecomb.swagger.engine.SwaggerEnvironment;\nimport org.apache.servicecomb.swagger.generator.SwaggerGenerator;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.springframework.http.ResponseEntity;\n\nimport io.swagger.v3.oas.models.OpenAPI;\n\npublic class TestSpringmvcConsumerResponseMapper {\n  interface ConsumerResponseForTest {\n    ResponseEntity<String> responseEntity();\n\n    CompletableFuture<ResponseEntity<String>> asyncResponseEntity();\n  }\n\n  SwaggerEnvironment environment = new SwaggerEnvironment();\n\n  SwaggerConsumer swaggerConsumer;\n\n  String result = \"abc\";\n\n  Response response = Response.ok(result);\n\n  @Before\n  public void setup() {\n    OpenAPI swagger = SwaggerGenerator.generate(ConsumerResponseForTest.class);\n    swaggerConsumer = environment.createConsumer(ConsumerResponseForTest.class, swagger);\n  }\n\n  @Test\n  public void responseEntity() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"responseEntity\");\n\n    @SuppressWarnings(\"unchecked\")\n    ResponseEntity<String> responseEntity = (ResponseEntity<String>) operation.getResponseMapper()\n        .mapResponse(response);\n    Assertions.assertEquals(result, responseEntity.getBody());\n    Assertions.assertTrue(responseEntity.getHeaders().isEmpty());\n  }\n\n  @Test\n  public void responseEntityWithHeader() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"responseEntity\");\n    response.addHeader(\"h\", \"v\");\n\n    @SuppressWarnings(\"unchecked\")\n    ResponseEntity<String> responseEntity = (ResponseEntity<String>) operation.getResponseMapper()\n        .mapResponse(response);\n    Assertions.assertEquals(result, responseEntity.getBody());\n    Assertions.assertEquals(1, responseEntity.getHeaders().size());\n    MatcherAssert.assertThat(responseEntity.getHeaders().get(\"h\"), Matchers.contains(\"v\"));\n  }\n\n  @Test\n  public void asyncResponseEntity() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"asyncResponseEntity\");\n\n    @SuppressWarnings(\"unchecked\")\n    ResponseEntity<String> responseEntity = (ResponseEntity<String>) operation.getResponseMapper()\n        .mapResponse(response);\n    Assertions.assertEquals(result, responseEntity.getBody());\n    Assertions.assertTrue(responseEntity.getHeaders().isEmpty());\n  }\n\n  @Test\n  public void asyncResponseEntityWithHeader() {\n    SwaggerConsumerOperation operation = swaggerConsumer.findOperation(\"asyncResponseEntity\");\n    response.addHeader(\"h\", \"v1\").addHeader(\"h\", \"v2\");\n    response.addHeader(\"h1\", null);\n\n    @SuppressWarnings(\"unchecked\")\n    ResponseEntity<String> responseEntity = (ResponseEntity<String>) operation.getResponseMapper()\n        .mapResponse(response);\n    Assertions.assertEquals(result, responseEntity.getBody());\n    Assertions.assertEquals(1, responseEntity.getHeaders().size());\n    MatcherAssert.assertThat(responseEntity.getHeaders().get(\"h\"), Matchers.contains(\"v1\", \"v2\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/test/java/org/apache/servicecomb/swagger/invocation/springmvc/response/TestSpringmvcProducerResponseMapper.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.StatusType;\n\nimport org.apache.servicecomb.foundation.common.http.HttpStatus;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.springframework.http.HttpHeaders;\nimport org.springframework.http.ResponseEntity;\n\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestSpringmvcProducerResponseMapper {\n  @Mocked\n  ProducerResponseMapper realMapper;\n\n  SpringmvcProducerResponseMapper mapper;\n\n  String[] arrResult = new String[] {\"a\", \"b\"};\n\n  @Before\n  public void setup() {\n    mapper = new SpringmvcProducerResponseMapper(realMapper);\n\n    new MockUp<ProducerResponseMapper>(realMapper) {\n      @Mock\n      Response mapResponse(StatusType status, Object response) {\n        if (HttpStatus.isSuccess(status.getStatusCode())) {\n          return Response.ok(Arrays.asList(arrResult));\n        }\n\n        return null;\n      }\n    };\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Test\n  public void mapResponse_withoutHeader_success() {\n    ResponseEntity<String[]> responseEntity =\n        new ResponseEntity<>(arrResult, org.springframework.http.HttpStatus.OK);\n    Response response = mapper.mapResponse(null, responseEntity);\n    MatcherAssert.assertThat((List<String>) response.getResult(), Matchers.contains(\"a\", \"b\"));\n    Assertions.assertEquals(Status.OK, response.getStatus());\n  }\n\n  @Test\n  public void mapResponse_withoutHeader_fail() {\n    ResponseEntity<String[]> responseEntity =\n        new ResponseEntity<>(arrResult, org.springframework.http.HttpStatus.BAD_REQUEST);\n    Response response = mapper.mapResponse(null, responseEntity);\n    Assertions.assertSame(arrResult, response.getResult());\n    Assertions.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus().getStatusCode());\n  }\n\n  @Test\n  public void mapResponse_withHeader() {\n    HttpHeaders headers = new HttpHeaders();\n    headers.add(\"h\", \"v\");\n\n    ResponseEntity<String[]> responseEntity =\n        new ResponseEntity<>(arrResult, headers, org.springframework.http.HttpStatus.OK);\n    Response response = mapper.mapResponse(null, responseEntity);\n\n    List<String> hv = response.getHeaders(\"h\");\n    MatcherAssert.assertThat(hv, Matchers.contains(\"v\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/test/java/org/apache/servicecomb/swagger/invocation/springmvc/response/TestSpringmvcProducerResponseMapperFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.springmvc.response;\n\nimport java.lang.reflect.Method;\nimport java.util.List;\n\nimport org.apache.servicecomb.foundation.common.utils.ReflectUtils;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactories;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;\nimport org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapperFactory;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.ResponseEntity;\n\npublic class TestSpringmvcProducerResponseMapperFactory {\n  SpringmvcProducerResponseMapperFactory factory = new SpringmvcProducerResponseMapperFactory();\n\n  ResponseMapperFactories<ProducerResponseMapper> factories = new ResponseMapperFactories<>(\n      ProducerResponseMapperFactory.class);\n\n  public ResponseEntity<String[]> responseEntity() {\n    return null;\n  }\n\n  public List<String> list() {\n    return null;\n  }\n\n  @Test\n  public void isMatch_true() {\n    Method method = ReflectUtils.findMethod(this.getClass(), \"responseEntity\");\n    Assertions.assertTrue(factory.isMatch(method.getGenericReturnType()));\n  }\n\n  @Test\n  public void isMatch_Parameterized_false() {\n    Method method = ReflectUtils.findMethod(this.getClass(), \"list\");\n    Assertions.assertFalse(factory.isMatch(method.getGenericReturnType()));\n  }\n\n  @Test\n  public void isMatch_false() {\n    Assertions.assertFalse(factory.isMatch(String.class));\n  }\n\n  @Test\n  public void createResponseMapper() {\n    Method responseEntityMethod = ReflectUtils.findMethod(this.getClass(), \"responseEntity\");\n\n    ProducerResponseMapper mapper = factory\n        .createResponseMapper(factories, responseEntityMethod.getGenericReturnType());\n    MatcherAssert.assertThat(mapper, Matchers.instanceOf(SpringmvcProducerResponseMapper.class));\n\n    ResponseEntity<String[]> responseEntity = new ResponseEntity<>(new String[] {\"a\", \"b\"}, HttpStatus.OK);\n    Response response = mapper.mapResponse(null, responseEntity);\n    MatcherAssert.assertThat(response.getResult(), Matchers.arrayContaining(\"a\", \"b\"));\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-springmvc/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-validator/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger-invocation</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-invocation-validator</artifactId>\n  <name>Java Chassis::Swagger::Invocation::Validator</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-invocation-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.hibernate.validator</groupId>\n      <artifactId>hibernate-validator</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/DefaultParameterNameProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.validator;\n\nimport java.lang.reflect.AccessibleObject;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Executable;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Parameter;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport jakarta.validation.ParameterNameProvider;\n\nimport org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;\n\npublic class DefaultParameterNameProvider implements ParameterNameProvider {\n  private final Map<AccessibleObject, List<String>> methodCache = new ConcurrentHashMapEx<>();\n\n  @Override\n  public List<String> getParameterNames(Constructor<?> constructor) {\n    return methodCache.computeIfAbsent(constructor, k -> getParameterNamesEx(constructor));\n  }\n\n  @Override\n  public List<String> getParameterNames(Method method) {\n    return methodCache.computeIfAbsent(method, k -> getParameterNamesEx(method));\n  }\n\n  private List<String> getParameterNamesEx(Executable methodOrConstructor) {\n    Parameter[] parameters = methodOrConstructor.getParameters();\n    List<String> parameterNames = new ArrayList<>(parameters.length);\n    for (int idx = 0; idx < parameters.length; idx++) {\n      Parameter parameter = parameters[idx];\n      String parameterName = parameter.isNamePresent() ? parameter.getName() : \"arg\" + idx;\n      parameterNames.add(parameterName);\n    }\n    return Collections.unmodifiableList(parameterNames);\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/invocation-validator/src/test/java/org/apache/servicecomb/swagger/invocation/validator/TestDefaultParameterNameProvider.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.swagger.invocation.validator;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Method;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestDefaultParameterNameProvider {\n  static class ValidatorForTest {\n    static class Student {\n      private String name;\n\n      int age;\n\n      public String getName() {\n        return name;\n      }\n\n      public void setName(String name) {\n        this.name = name;\n      }\n\n      public int getAge() {\n        return age;\n      }\n\n      public void setAge(int age) {\n        this.age = age;\n      }\n    }\n\n    private String grade;\n\n    private int number;\n\n    public ValidatorForTest() {\n    }\n\n    public ValidatorForTest(String grade, int number) {\n      this.grade = grade;\n      this.number = number;\n    }\n\n    public int add(int a, int b) {\n      return a + b;\n    }\n\n    public String sayHi(String hi) {\n      return hi + \" sayhi\";\n    }\n\n    public Student sayHello(Student student) {\n      return student;\n    }\n\n    public String setTest(String grade) {\n      this.grade = grade;\n      return this.grade;\n    }\n\n    public int getNumber() {\n      return number;\n    }\n\n    public void setNumber(int number) {\n      this.number = number;\n    }\n  }\n\n  Class<ValidatorForTest> validatorForTest = ValidatorForTest.class;\n\n  DefaultParameterNameProvider parameterNameProvider = new DefaultParameterNameProvider();\n\n  @Test\n  public void testMethod() throws NoSuchMethodException {\n    Method method = validatorForTest.getMethod(\"add\", int.class, int.class);\n    MatcherAssert.assertThat(parameterNameProvider.getParameterNames(method), Matchers.contains(\"a\", \"b\"));\n    method = validatorForTest.getMethod(\"sayHi\", String.class);\n    MatcherAssert.assertThat(parameterNameProvider.getParameterNames(method), Matchers.contains(\"hi\"));\n    method = validatorForTest.getMethod(\"sayHello\", ValidatorForTest.Student.class);\n    MatcherAssert.assertThat(parameterNameProvider.getParameterNames(method), Matchers.contains(\"student\"));\n    method = validatorForTest.getMethod(\"setTest\", String.class);\n    MatcherAssert.assertThat(parameterNameProvider.getParameterNames(method), Matchers.contains(\"grade\"));\n    method = validatorForTest.getMethod(\"getNumber\");\n    Assertions.assertTrue(parameterNameProvider.getParameterNames(method).isEmpty());\n    method = validatorForTest.getMethod(\"setNumber\", int.class);\n    MatcherAssert.assertThat(parameterNameProvider.getParameterNames(method), Matchers.contains(\"number\"));\n  }\n\n  @Test\n  public void testConstructor() throws NoSuchMethodException {\n    Constructor<ValidatorForTest> constructor = validatorForTest.getConstructor(String.class, int.class);\n    MatcherAssert.assertThat(parameterNameProvider.getParameterNames(constructor), Matchers.contains(\"grade\", \"number\"));\n    constructor = validatorForTest.getConstructor();\n    Assertions.assertTrue(parameterNameProvider.getParameterNames(constructor).isEmpty());\n\n  }\n}\n"
  },
  {
    "path": "swagger/swagger-invocation/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>swagger</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>swagger-invocation</artifactId>\n  <name>Java Chassis::Swagger::Invocation</name>\n\n  <packaging>pom</packaging>\n  <modules>\n    <module>invocation-core</module>\n    <module>invocation-jaxrs</module>\n    <module>invocation-springmvc</module>\n    <module>invocation-validator</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "tracing/README.md",
    "content": "# Customized Tracing\nCustomized tracing with [Zipkin](http://zipkin.io/) is supported to allow users to add tracing spans at points of\ninterest.\n\n## Set Up Customized Tracing\n1. Include the following dependency\n```\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>tracing-zipkin</artifactId>\n    </dependency>\n```\n2. Enable tracing with annotation `@EnableZipkinTracing` on your application entry or configuration\n\nImport `tracing.zipkin.EnableZipkinTracing` package\n\n```\nimport org.apache.servicecomb.tracing.zipkin.EnableZipkinTracing;\n```\nAdd annotation `@EnableZipkinTracing`\n\n```\n@SpringBootApplication\n@EnableZipkinTracing\npublic class ZipkinSpanTestApplication {\n  public static void main(String[] args) {\n    SpringApplication.run(ZipkinSpanTestApplication.class);\n  }\n}\n```\n3. Add new span to the point of interest with annotation `@Span`\n\nImport `tracing.Span` package\n\n```\nimport org.apache.servicecomb.tracing.Span;\n```\nAdd annotation `@Span`\n\n```\n@Component\npublic class SlowRepoImpl implements SlowRepo {\n  private static final Logger logger = LoggerFactory.getLogger(SlowRepoImpl.class);\n\n  private final Random random = new Random();\n\n  @Span\n  @Override\n  public String crawl() throws InterruptedException {\n    logger.info(\"in /crawl\");\n    Thread.sleep(random.nextInt(200));\n    return \"crawled\";\n  }\n}\n```\n\nThat's it!\n\n## Reported Span Data\nCustomized tracing span includes two pieces of data:\n* span name - annotated method name\n* call.path - annotated method signature\n\ne.g. the example `SlowRepoImpl` in the previous section reports the following span\n\n| key | value |\n| --- | --- |\n| span name | crawl |\n| call.path\t| public abstract java.lang.String org.apache.servicecomb.tests.tracing.SlowRepo.crawl() throws java.lang.InterruptedException |\n\n## Constraints\n* Customized tracing with annotation only supports method calls in the request thread.\n* Classes with `@Span` must be a spring managed bean. If you want to do load-time weaving for non spring beans,\nyou have to do it manually according to this [answer](https://stackoverflow.com/questions/41383941/load-time-weaving-for-non-spring-beans-in-a-spring-application).\n"
  },
  {
    "path": "tracing/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>tracing</artifactId>\n  <name>Java Chassis::Tracing</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>tracing-common</module>\n    <module>tracing-zipkin</module>\n  </modules>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.springframework.boot</groupId>\n      <artifactId>spring-boot-starter-aop</artifactId>\n      <exclusions>\n        <exclusion>\n          <groupId>org.springframework.boot</groupId>\n          <artifactId>spring-boot-starter-logging</artifactId>\n        </exclusion>\n      </exclusions>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "tracing/tracing-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>tracing</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>tracing-common</artifactId>\n  <name>Java Chassis::Tracing::Common</name>\n\n\n</project>\n"
  },
  {
    "path": "tracing/tracing-common/src/main/java/org/apache/servicecomb/tracing/Span.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Span {\n  String spanName() default \"\";\n\n  String callPath() default \"\";\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>tracing</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>tracing-zipkin</artifactId>\n  <name>Java Chassis::Tracing::Zipkin</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>handler-tracing-zipkin</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>tracing-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave-spring-beans</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.brave</groupId>\n      <artifactId>brave-context-slf4j</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.reporter2</groupId>\n      <artifactId>zipkin-sender-okhttp3</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.zipkin.reporter2</groupId>\n      <artifactId>zipkin-reporter-brave</artifactId>\n    </dependency>\n  </dependencies>\n\n</project>\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/EnableZipkinTracing.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\nimport org.springframework.context.annotation.Import;\n\n/**\n * This annotation enables auto-configuration of Zipkin for auto span generation using annotation {@link org.apache.servicecomb.tracing.Span}.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\n@Import(ZipkinSpanAspectConfig.class)\npublic @interface EnableZipkinTracing {\n\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinSpanAspect.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport java.lang.invoke.MethodHandles;\nimport java.lang.reflect.Method;\n\nimport org.apache.servicecomb.tracing.Span;\nimport org.aspectj.lang.ProceedingJoinPoint;\nimport org.aspectj.lang.annotation.Around;\nimport org.aspectj.lang.annotation.Aspect;\nimport org.aspectj.lang.reflect.MethodSignature;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport brave.Tracing;\n\n@Aspect\nclass ZipkinSpanAspect {\n  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\n\n  private final ZipkinTracingAdviser adviser;\n\n  ZipkinSpanAspect(Tracing tracing) {\n    this.adviser = new ZipkinTracingAdviser(tracing.tracer());\n  }\n\n  @Around(\"execution(@org.apache.servicecomb.tracing.Span * *(..)) && @annotation(spanAnnotation)\")\n  public Object advise(ProceedingJoinPoint joinPoint, Span spanAnnotation) throws Throwable {\n    String spanName = spanAnnotation.spanName();\n    String callPath = spanAnnotation.callPath();\n    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();\n    LOG.debug(\"Generating zipkin span for method {}\", method.toString());\n    if (\"\".equals(spanName)) {\n      spanName = method.getName();\n    }\n    if (\"\".equals(callPath)) {\n      callPath = method.toString();\n    }\n\n    return adviser.invoke(spanName, callPath, joinPoint::proceed);\n  }\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinSpanAspectConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.EnableAspectJAutoProxy;\n\nimport brave.Tracing;\n\n@Configuration\n@EnableAspectJAutoProxy\nclass ZipkinSpanAspectConfig {\n  @Bean\n  ZipkinSpanAspect zipkinSpanAspect(Tracing tracing) {\n    return new ZipkinSpanAspect(tracing);\n  }\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingAdviser.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport org.apache.servicecomb.swagger.invocation.context.ContextUtils;\nimport org.apache.servicecomb.swagger.invocation.context.InvocationContext;\n\nimport brave.Span;\nimport brave.Tracer;\nimport brave.Tracer.SpanInScope;\n\nclass ZipkinTracingAdviser {\n\n  static final String CALL_PATH = \"call.path\";\n\n  private final Tracer tracer;\n\n  ZipkinTracingAdviser(Tracer tracer) {\n    this.tracer = tracer;\n  }\n\n  @SuppressWarnings({\"unused\", \"try\"})\n  <T> T invoke(String spanName, String path, ThrowableSupplier<T> supplier) throws Throwable {\n    Span span = createSpan(spanName, path);\n    try (SpanInScope spanInScope = tracer.withSpanInScope(span)) {\n      return supplier.get();\n    } catch (Throwable throwable) {\n      span.tag(\"error\", throwable.getClass().getSimpleName() + \": \" + throwable.getMessage());\n      throw throwable;\n    } finally {\n      span.finish();\n    }\n  }\n\n  private Span createSpan(String spanName, String path) {\n    InvocationContext context = ContextUtils.getInvocationContext();\n    Span currentSpan = null;\n    if (context != null) {\n      currentSpan = context.getLocalContext(ZipkinTracingFilter.CONTEXT_TRACE_SPAN);\n    }\n    if (currentSpan == null) {\n      currentSpan = tracer.currentSpan();\n    }\n    if (currentSpan != null) {\n      return tracer.newChild(currentSpan.context()).name(spanName).tag(CALL_PATH, path).start();\n    }\n\n    return tracer.newTrace().name(spanName).tag(CALL_PATH, path).start();\n  }\n\n  interface ThrowableSupplier<T> {\n    T get() throws Throwable;\n  }\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/ZipkinSpanAspectTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport static java.util.concurrent.TimeUnit.SECONDS;\nimport static org.apache.servicecomb.tracing.zipkin.ZipkinTracingAdviser.CALL_PATH;\nimport static org.awaitility.Awaitility.await;\nimport static org.hamcrest.CoreMatchers.is;\nimport static org.hamcrest.collection.IsIterableContainingInOrder.contains;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentLinkedDeque;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.tracing.zipkin.ZipkinSpanAspectTest.TracingConfig;\nimport org.apache.servicecomb.tracing.zipkin.app.ZipkinSpanTestApplication;\nimport org.apache.servicecomb.tracing.zipkin.app.ZipkinSpanTestApplication.CustomSpanTask;\nimport org.apache.servicecomb.tracing.zipkin.app.ZipkinSpanTestApplication.SomeSlowTask;\nimport org.hamcrest.MatcherAssert;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Test;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.Primary;\n\nimport brave.Tracing;\nimport brave.propagation.StrictScopeDecorator;\nimport brave.propagation.ThreadLocalCurrentTraceContext;\nimport zipkin2.Span;\nimport zipkin2.reporter.brave.ZipkinSpanHandler;\n\n@SpringBootTest(classes = {ZipkinSpanTestApplication.class, TracingConfig.class})\npublic class ZipkinSpanAspectTest {\n  private Queue<Span> spans;\n\n  private SomeSlowTask someSlowTask;\n\n  private CustomSpanTask customSpanTask;\n\n  private Tracing tracing;\n\n  @Autowired\n  public void setSpans(Queue<Span> spans) {\n    this.spans = spans;\n  }\n\n  @Autowired\n  public void setSomeSlowTask(SomeSlowTask someSlowTask) {\n    this.someSlowTask = someSlowTask;\n  }\n\n  @Autowired\n  public void setCustomSpanTask(CustomSpanTask customSpanTask) {\n    this.customSpanTask = customSpanTask;\n  }\n\n  @Autowired\n  public void setTracing(Tracing tracing) {\n    this.tracing = tracing;\n  }\n\n  public ZipkinSpanAspectTest() {\n  }\n\n  @AfterEach\n  public void tearDown() throws Exception {\n    tracing.close();\n  }\n\n  @Test\n  public void reportedSpanContainsAnnotatedMethodInfo() throws Exception {\n    someSlowTask.crawl();\n\n    await().atMost(2, SECONDS).until(() -> !spans.isEmpty());\n\n    zipkin2.Span span = spans.poll();\n    MatcherAssert.assertThat(span.name(), is(\"crawl\"));\n    MatcherAssert.assertThat(tracedValues(span), contains(SomeSlowTask.class.getMethod(\"crawl\").toString()));\n  }\n\n  @Test\n  public void reportCustomSpanInformation() {\n    customSpanTask.invoke();\n    await().atMost(2, SECONDS).until(() -> !spans.isEmpty());\n\n    zipkin2.Span span = spans.poll();\n    MatcherAssert.assertThat(span.name(), is(\"transaction1\"));\n    MatcherAssert.assertThat(tracedValues(span), contains(\"startA\"));\n  }\n\n  private List<String> tracedValues(zipkin2.Span spans) {\n    return spans.tags().entrySet().stream()\n        .filter(span -> CALL_PATH.equals(span.getKey()) || \"error\".equals(span.getKey()))\n        .filter(span -> span.getValue() != null)\n        .map(Map.Entry::getValue)\n        .distinct()\n        .collect(Collectors.toList());\n  }\n\n  @Configuration\n  static class TracingConfig {\n    @Bean\n    Queue<Span> spans() {\n      return new ConcurrentLinkedDeque<>();\n    }\n\n    @Bean\n    @Primary\n    Tracing zipkinTracing(Queue<Span> spans) {\n      return Tracing.newBuilder()\n          .currentTraceContext(\n              ThreadLocalCurrentTraceContext.newBuilder().addScopeDecorator(StrictScopeDecorator.create()).build())\n          .addSpanHandler(ZipkinSpanHandler.create(spans::add))\n          .build();\n    }\n  }\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingAdviserTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin;\n\nimport static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;\nimport static java.util.concurrent.TimeUnit.SECONDS;\nimport static org.apache.servicecomb.tracing.zipkin.ZipkinTracingAdviser.CALL_PATH;\nimport static org.awaitility.Awaitility.await;\nimport static org.hamcrest.CoreMatchers.is;\nimport static org.hamcrest.Matchers.containsInAnyOrder;\nimport static org.hamcrest.collection.IsIterableContainingInOrder.contains;\n\nimport java.lang.reflect.Array;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.concurrent.BrokenBarrierException;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentLinkedDeque;\nimport java.util.concurrent.CyclicBarrier;\nimport java.util.concurrent.Executors;\nimport java.util.stream.Collectors;\n\nimport org.apache.servicecomb.tracing.zipkin.ZipkinTracingAdviser.ThrowableSupplier;\nimport org.hamcrest.MatcherAssert;\n\nimport brave.Span;\nimport brave.Tracer.SpanInScope;\nimport brave.Tracing;\nimport brave.propagation.StrictScopeDecorator;\nimport brave.propagation.ThreadLocalCurrentTraceContext;\n\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\nimport zipkin2.reporter.brave.ZipkinSpanHandler;\n\npublic class ZipkinTracingAdviserTest {\n  private static final int nThreads = 10;\n\n  private final String spanName = \"some span\";\n\n  private final String path = this.getClass().getCanonicalName();\n\n  private final String expected = \"supplied\";\n\n  private final RuntimeException error = new RuntimeException(\"oops\");\n\n  private final ThrowableSupplier<String> supplier = () -> expected;\n\n  private final Map<String, Queue<zipkin2.Span>> traces = new ConcurrentHashMap<>();\n\n  private final Tracing tracing = Tracing.newBuilder()\n      .currentTraceContext(\n          ThreadLocalCurrentTraceContext.newBuilder().addScopeDecorator(StrictScopeDecorator.create()).build())\n      .addSpanHandler(ZipkinSpanHandler.create(\n          e -> traces.computeIfAbsent(e.traceId(), id -> new ConcurrentLinkedDeque<>()).add(e)))\n      .build();\n\n  private final ZipkinTracingAdviser tracingAdviser = new ZipkinTracingAdviser(tracing.tracer());\n\n  @AfterEach\n  public void tearDown() throws Exception {\n    tracing.close();\n  }\n\n  @Test\n  public void startsNewRootSpan() throws Throwable {\n    String result = tracingAdviser.invoke(spanName, path, supplier);\n\n    MatcherAssert.assertThat(result, is(expected));\n    await().atMost(2, SECONDS).until(() -> !traces.isEmpty());\n\n    zipkin2.Span span = traces.values().iterator().next().poll();\n    MatcherAssert.assertThat(span.name(), is(spanName));\n    MatcherAssert.assertThat(tracedValues(span), contains(this.getClass().getCanonicalName()));\n  }\n\n  @Test\n  public void includesExceptionInTags() throws Throwable {\n    try {\n      tracingAdviser.invoke(spanName, path, () -> {\n        throw error;\n      });\n\n      expectFailing(RuntimeException.class);\n    } catch (RuntimeException ignored) {\n    }\n\n    await().atMost(2, SECONDS).until(() -> !traces.isEmpty());\n\n    zipkin2.Span span = traces.values().iterator().next().poll();\n    Assertions.assertEquals(spanName, span.name());\n    MatcherAssert.assertThat(tracedValues(span),\n        containsInAnyOrder(this.getClass().getCanonicalName(), \"RuntimeException: oops\"));\n  }\n\n  @SuppressWarnings({\"unused\", \"try\"})\n  @Test\n  public void startsNewChildSpan() {\n    CyclicBarrier cyclicBarrier = new CyclicBarrier(nThreads);\n\n    CompletableFuture<?>[] futures = (CompletableFuture<?>[]) Array.newInstance(CompletableFuture.class, nThreads);\n    for (int i = 0; i < nThreads; i++) {\n      futures[i] = CompletableFuture.runAsync(() -> {\n        Span currentSpan = tracing.tracer().newTrace().start();\n\n        waitTillAllAreReady(cyclicBarrier);\n\n        try (SpanInScope spanInScope = tracing.tracer().withSpanInScope(currentSpan)) {\n          MatcherAssert.assertThat(tracingAdviser.invoke(spanName, path, supplier), is(expected));\n        } catch (Throwable throwable) {\n          Assertions.fail(throwable.getMessage());\n        } finally {\n          currentSpan.finish();\n        }\n      }, Executors.newFixedThreadPool(nThreads));\n    }\n\n    CompletableFuture.allOf(futures).join();\n\n    MatcherAssert.assertThat(traces.size(), is(nThreads));\n\n    for (Queue<zipkin2.Span> queue : traces.values()) {\n      zipkin2.Span child = queue.poll();\n      MatcherAssert.assertThat(child.name(), is(spanName));\n\n      zipkin2.Span parent = queue.poll();\n      MatcherAssert.assertThat(child.parentId(), is(parent.id()));\n      MatcherAssert.assertThat(child.traceId(), is(parent.traceId()));\n      MatcherAssert.assertThat(tracedValues(child), contains(this.getClass().getCanonicalName()));\n    }\n  }\n\n  private void waitTillAllAreReady(CyclicBarrier cyclicBarrier) {\n    try {\n      cyclicBarrier.await();\n    } catch (InterruptedException | BrokenBarrierException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  private List<String> tracedValues(zipkin2.Span spans) {\n    return spans.tags().entrySet().stream()\n        .filter(span -> CALL_PATH.equals(span.getKey()) || \"error\".equals(span.getKey()))\n        .filter(span -> span.getValue() != null)\n        .map(Map.Entry::getValue)\n        .distinct()\n        .collect(Collectors.toList());\n  }\n}\n"
  },
  {
    "path": "tracing/tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/app/ZipkinSpanTestApplication.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.tracing.zipkin.app;\n\nimport org.apache.servicecomb.tracing.Span;\nimport org.apache.servicecomb.tracing.zipkin.EnableZipkinTracing;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.annotation.Bean;\n\n@SpringBootApplication\n@EnableZipkinTracing\npublic class ZipkinSpanTestApplication {\n  public static void main(String[] args) {\n    SpringApplication.run(ZipkinSpanTestApplication.class);\n  }\n\n  @Bean\n  SomeSlowTask someSlowTask() {\n    return new SomeSlowTask();\n  }\n\n  @Bean\n  CustomSpanTask customSpanTask() {\n    return new CustomSpanTask();\n  }\n\n  public static class SomeSlowTask {\n    @Span\n    public String crawl() {\n      return \"crawling...\";\n    }\n  }\n\n  public static class CustomSpanTask {\n    @Span(spanName = \"transaction1\", callPath = \"startA\")\n    public String invoke() {\n      return \"invoke the method\";\n    }\n  }\n}\n"
  },
  {
    "path": "transports/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>java-chassis-parent</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n    <relativePath>../parents/default</relativePath>\n  </parent>\n  <artifactId>transports</artifactId>\n  <name>Java Chassis::Transports</name>\n  <packaging>pom</packaging>\n  <modules>\n    <module>transport-highway</module>\n    <module>transport-rest</module>\n    <module>transport-common</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "transports/transport-common/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <parent>\n    <artifactId>transports</artifactId>\n    <groupId>org.apache.servicecomb</groupId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <modelVersion>4.0.0</modelVersion>\n\n  <artifactId>transport-common</artifactId>\n  <name>Java Chassis::Transports::common</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-config</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "transports/transport-common/src/main/java/org/apache/servicecomb/transport/common/TransportConfigUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.common;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic final class TransportConfigUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TransportConfigUtils.class);\n\n  private TransportConfigUtils() {\n  }\n\n  // old verticle count key is ambiguous\n  // suggest to use new name\n  public static int readVerticleCount(String key, String deprecatedKey) {\n    int count = LegacyPropertyFactory.getIntProperty(key, -1);\n    if (count > 0) {\n      return count;\n    }\n\n    count = LegacyPropertyFactory.getIntProperty(deprecatedKey, -1);\n    if (count > 0) {\n      LOGGER.warn(\"{} is ambiguous, and deprecated, recommended to use {}.\", deprecatedKey, key);\n      return count;\n    }\n\n    // default value\n    count = Math.min(Runtime.getRuntime().availableProcessors(), 8);\n    LOGGER.info(\"{} not defined, set to {}.\", key, count);\n    return count;\n  }\n}\n"
  },
  {
    "path": "transports/transport-common/src/test/java/org/apache/servicecomb/transport/common/TestTransportConfigUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.common;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;\nimport org.junit.jupiter.api.AfterAll;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class TestTransportConfigUtils {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeEach\n  public void setup() {\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @AfterAll\n  public static void teardown() {\n  }\n\n  static String key = \"verticle-count\";\n\n  static String deprecatedKey = \"thread-count\";\n\n  @Test\n  public void readVerticleCount_new_exist() {\n    Mockito.when(environment.getProperty(\"verticle-count\", int.class, -1)).thenReturn(10);\n    Assertions.assertEquals(10, TransportConfigUtils.readVerticleCount(key, deprecatedKey));\n  }\n\n  @Test\n  public void readVerticleCount_old_exist() {\n    Mockito.when(environment.getProperty(\"verticle-count\", int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\"thread-count\", int.class, -1)).thenReturn(10);\n    LogCollector collector = new LogCollector();\n    Assertions.assertEquals(10, TransportConfigUtils.readVerticleCount(key, deprecatedKey));\n    Assertions.assertEquals(\"thread-count is ambiguous, and deprecated, recommended to use verticle-count.\",\n        collector.getEvent(0).getMessage().getFormattedMessage());\n    collector.tearDown();\n  }\n\n  @Test\n  public void readVerticleCount_default_smallCpu() {\n    Mockito.when(environment.getProperty(\"verticle-count\", int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\"thread-count\", int.class, -1)).thenReturn(-1);\n\n    new MockUp<Runtime>() {\n      @Mock\n      int availableProcessors() {\n        return 7;\n      }\n    };\n\n    LogCollector collector = new LogCollector();\n    Assertions.assertEquals(7, TransportConfigUtils.readVerticleCount(key, deprecatedKey));\n    Assertions.assertEquals(\"verticle-count not defined, set to 7.\",\n        collector.getLastEvents().getMessage().getFormattedMessage());\n    collector.tearDown();\n  }\n\n  @Test\n  public void readVerticleCount_default_bigCpu() {\n    Mockito.when(environment.getProperty(\"verticle-count\", int.class, -1)).thenReturn(-1);\n    Mockito.when(environment.getProperty(\"thread-count\", int.class, -1)).thenReturn(-1);\n\n    AtomicInteger count = new AtomicInteger(8);\n    new MockUp<Runtime>() {\n      @Mock\n      int availableProcessors() {\n        return count.get();\n      }\n    };\n\n    LogCollector collector = new LogCollector();\n    Assertions.assertEquals(8, TransportConfigUtils.readVerticleCount(key, deprecatedKey));\n    Assertions.assertEquals(\"verticle-count not defined, set to 8.\",\n        collector.getLastEvents().getMessage().getFormattedMessage());\n\n    count.set(9);\n    collector.clear();\n    Assertions.assertEquals(8, TransportConfigUtils.readVerticleCount(key, deprecatedKey));\n    Assertions.assertEquals(\"verticle-count not defined, set to 8.\",\n        collector.getLastEvents().getMessage().getFormattedMessage());\n\n    collector.tearDown();\n  }\n}\n"
  },
  {
    "path": "transports/transport-common/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "transports/transport-highway/pom.xml",
    "content": "<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>transports</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>transport-highway</artifactId>\n  <name>Java Chassis::Transports::Hightway</name>\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>java-chassis-core</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-protobuf</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-metrics</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-common</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.ssl.SSLOptionFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;\nimport org.apache.servicecomb.foundation.vertx.client.ClientVerticle;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.Vertx;\n\npublic class HighwayClient {\n  private static final String SSL_KEY = \"highway.consumer\";\n\n  private ClientPoolManager<HighwayClientConnectionPool> clientMgr;\n\n  public void init(Vertx vertx) throws Exception {\n    TcpClientConfig normalConfig = createTcpClientConfig();\n    normalConfig.setSsl(false);\n\n    TcpClientConfig sslConfig = createTcpClientConfig();\n    sslConfig.setSsl(true);\n\n    clientMgr = new ClientPoolManager<>(vertx, new HighwayClientPoolFactory(normalConfig, sslConfig));\n\n    DeploymentOptions deployOptions = VertxUtils.createClientDeployOptions(clientMgr,\n        HighwayConfig.getClientThreadCount());\n    Map<String, Object> result = VertxUtils.blockDeploy(vertx, ClientVerticle.class, deployOptions);\n    if (!(boolean) result.get(\"code\")) {\n      throw new IllegalStateException((String) result.get(\"message\"));\n    }\n  }\n\n  @VisibleForTesting\n  TcpClientConfig createTcpClientConfig() {\n    TcpClientConfig tcpClientConfig = new TcpClientConfig();\n    // global request timeout to be login timeout\n    tcpClientConfig.setMsLoginTimeout(\n        LegacyPropertyFactory.getLongProperty(\"servicecomb.request.timeout\", TcpClientConfig.DEFAULT_LOGIN_TIMEOUT));\n\n    SSLOptionFactory factory =\n        SSLOptionFactory.createSSLOptionFactory(SSL_KEY, LegacyPropertyFactory.getEnvironment());\n    SSLOption sslOption;\n    if (factory == null) {\n      sslOption = SSLOption.build(SSL_KEY, LegacyPropertyFactory.getEnvironment());\n    } else {\n      sslOption = factory.createSSLOption();\n    }\n    SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass());\n    VertxTLSBuilder.buildClientOptionsBase(sslOption, sslCustom, tcpClientConfig);\n    if (!sslOption.isCheckCNHost()) {\n      tcpClientConfig.setHostnameVerificationAlgorithm(\"\");\n    } else {\n      tcpClientConfig.setHostnameVerificationAlgorithm(\"HTTPS\");\n    }\n\n    return tcpClientConfig;\n  }\n\n  public HighwayClientPackage createClientPackage(Invocation invocation, OperationProtobuf operationProtobuf) {\n    long msRequestTimeout = invocation.getOperationMeta().getConfig().getMsRequestTimeout();\n    return new HighwayClientPackage(invocation, operationProtobuf, msRequestTimeout);\n  }\n\n  public HighwayClientConnection findClientPool(Invocation invocation) {\n    return clientMgr.findClientPool(invocation.isSync())\n        .findOrCreateClient(invocation.getEndpoint().getEndpoint());\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.AbstractTcpClientPackage;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.NetClientWrapper;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConnection;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\nimport org.apache.servicecomb.transport.highway.message.LoginRequest;\nimport org.apache.servicecomb.transport.highway.message.LoginResponse;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.buffer.Buffer;\n\npublic class HighwayClientConnection extends TcpClientConnection {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HighwayClientConnection.class);\n\n  public HighwayClientConnection(Context context, NetClientWrapper netClientWrapper, String endpoint) {\n    super(context, netClientWrapper, endpoint);\n    setLocalSupportLogin(true);\n  }\n\n  @Override\n  protected TcpOutputStream createLogin() {\n    try {\n      RequestHeader header = new RequestHeader();\n      header.setMsgType(MsgType.LOGIN);\n\n      LoginRequest login = new LoginRequest();\n      login.setProtocol(CoreConst.HIGHWAY);\n\n      HighwayOutputStream os = new HighwayOutputStream(AbstractTcpClientPackage.getAndIncRequestId());\n      os.write(header, LoginRequest.getRootSerializer(), login);\n      return os;\n    } catch (Throwable e) {\n      throw new Error(\"impossible.\", e);\n    }\n  }\n\n  @Override\n  protected boolean onLoginResponse(Buffer bodyBuffer) {\n    try {\n      LoginResponse.readObject(bodyBuffer);\n      return true;\n    } catch (Throwable e) {\n      LOGGER.error(\"decode login response failed.\", e);\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientConnectionPool.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.foundation.vertx.client.tcp.AbstractTcpClientConnectionPool;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.NetClientWrapper;\n\nimport io.vertx.core.Context;\n\npublic class HighwayClientConnectionPool extends AbstractTcpClientConnectionPool<HighwayClientConnection> {\n  public HighwayClientConnectionPool(Context context, NetClientWrapper netClientWrapper) {\n    super(context, netClientWrapper);\n  }\n\n  @Override\n  protected HighwayClientConnection create(String endpoint) {\n    return new HighwayClientConnection(context, netClientWrapper, endpoint);\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpData;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class HighwayClientFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HighwayClientFilter.class);\n\n  public static final String NAME = \"highway-client\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.HIGHWAY.equals(transport);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 2000;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    LOGGER.debug(\"Sending request by highway, operation={}, endpoint={}.\",\n        invocation.getMicroserviceQualifiedName(),\n        invocation.getEndpoint().getEndpoint());\n\n    OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(invocation);\n    return send(invocation, operationProtobuf)\n        .thenApply(tcpData -> convertToResponse(invocation, operationProtobuf, tcpData))\n        .thenApply(this::convertFailedResponseToException);\n  }\n\n  protected CompletableFuture<TcpData> send(Invocation invocation, OperationProtobuf operationProtobuf) {\n    invocation.getInvocationStageTrace().startConsumerConnection();\n    HighwayClient highwayClient = ((HighwayTransport) invocation.getTransport()).getHighwayClient();\n    HighwayClientPackage clientPackage = highwayClient.createClientPackage(invocation, operationProtobuf);\n    HighwayClientConnection clientConnection = highwayClient.findClientPool(invocation);\n    invocation.getInvocationStageTrace().finishConsumerConnection();\n    invocation.onStartSendRequest();\n    invocation.getInvocationStageTrace().startConsumerSendRequest();\n    CompletableFuture<TcpData> sendFuture = clientConnection\n        .send(clientPackage).whenComplete((r, e) -> invocation.getInvocationStageTrace().finishWaitResponse());\n    invocation.getInvocationStageTrace().finishConsumerSendRequest();\n    invocation.getInvocationStageTrace().startWaitResponse();\n    return invocation.optimizeSyncConsumerThread(sendFuture);\n  }\n\n  protected Response convertToResponse(Invocation invocation, OperationProtobuf operationProtobuf, TcpData tcpData) {\n    try {\n      invocation.getInvocationStageTrace().startConsumerDecodeResponse();\n      Response result = HighwayCodec.decodeResponse(invocation, operationProtobuf, tcpData);\n      invocation.getInvocationStageTrace().finishConsumerDecodeResponse();\n      return result;\n    } catch (Exception e) {\n      throw AsyncUtils.rethrow(e);\n    }\n  }\n\n  protected Response convertFailedResponseToException(Response response) {\n    if (response.isFailed()) {\n      Object errorData = response.getResult();\n      if (errorData instanceof InvocationException) {\n        errorData = ((InvocationException) errorData).getErrorData();\n      }\n      throw Exceptions.create(response.getStatus(), errorData);\n    }\n\n    return response;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientPackage.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.AbstractTcpClientPackage;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class HighwayClientPackage extends AbstractTcpClientPackage {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HighwayClientPackage.class);\n\n  private final Invocation invocation;\n\n  private final OperationProtobuf operationProtobuf;\n\n  public HighwayClientPackage(Invocation invocation, OperationProtobuf operationProtobuf, long msRequestTimeout) {\n    this.invocation = invocation;\n    this.operationProtobuf = operationProtobuf;\n    this.setMsRequestTimeout(msRequestTimeout);\n  }\n\n  @Override\n  public TcpOutputStream createStream() {\n    try {\n      return HighwayCodec.encodeRequest(msgId, invocation, operationProtobuf);\n    } catch (Exception e) {\n      String msg = String.format(\"encode request failed. appid=%s, qualifiedName=%s\",\n          invocation.getAppId(),\n          invocation.getOperationMeta().getMicroserviceQualifiedName());\n      LOGGER.error(msg, e);\n      throw new Error(msg, e);\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientPoolFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.foundation.vertx.client.tcp.AbstractTcpClientPoolFactory;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.NetClientWrapper;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;\n\nimport io.vertx.core.Context;\n\npublic class HighwayClientPoolFactory extends AbstractTcpClientPoolFactory<HighwayClientConnectionPool> {\n  public HighwayClientPoolFactory(TcpClientConfig normalClientConfig, TcpClientConfig sslClientConfig) {\n    super(normalClientConfig, sslClientConfig);\n  }\n\n  @Override\n  protected HighwayClientConnectionPool doCreateClientPool(Context context, NetClientWrapper netClientWrapper) {\n    return new HighwayClientConnectionPool(context, netClientWrapper);\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpData;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\nimport org.apache.servicecomb.swagger.generator.SwaggerConst;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\nimport org.apache.servicecomb.transport.highway.message.ResponseHeader;\n\nimport com.fasterxml.jackson.databind.JavaType;\nimport com.google.common.base.Defaults;\n\nimport io.swagger.v3.oas.models.media.Schema;\nimport io.swagger.v3.oas.models.parameters.Parameter;\nimport io.swagger.v3.oas.models.parameters.RequestBody;\nimport io.vertx.core.buffer.Buffer;\n\n@SuppressWarnings(\"rawtypes\")\npublic final class HighwayCodec {\n  private HighwayCodec() {\n  }\n\n  public static TcpOutputStream encodeRequest(long msgId, Invocation invocation,\n      OperationProtobuf operationProtobuf) throws Exception {\n    // 写header\n    RequestHeader header = new RequestHeader();\n    header.setMsgType(MsgType.REQUEST);\n    header.setFlags(0);\n    header.setDestMicroservice(invocation.getMicroserviceName());\n    header.setSchemaId(invocation.getSchemaId());\n    header.setOperationName(invocation.getOperationName());\n    header.setContext(invocation.getContext());\n\n    HighwayOutputStream os = new HighwayOutputStream(msgId);\n    os.write(header, operationProtobuf.getRequestRootSerializer(), invocation.getSwaggerArguments());\n    return os;\n  }\n\n  // Proto buffer never serialize default values, put it back in provider.\n  // Or will get IllegalArgumentsException for primitive types.\n  private static Map<String, Object> addPrimitiveTypeDefaultValues(Invocation invocation,\n      Map<String, Object> swaggerArguments) {\n    if (invocation.getOperationMeta().getSwaggerProducerOperation() != null && !invocation.isEdge()) {\n      List<Parameter> swaggerParameters = invocation.getOperationMeta().getSwaggerOperation()\n          .getParameters();\n      if (swaggerParameters != null) {\n        for (Parameter parameter : swaggerParameters) {\n          if (swaggerArguments.get(parameter.getName()) == null) {\n            Type type = invocation.getOperationMeta().getSwaggerProducerOperation()\n                .getSwaggerParameterType(parameter.getName());\n            swaggerArguments.put(parameter.getName(), defaultPrimitiveValue(null, type));\n          }\n        }\n      }\n\n      RequestBody requestBody = invocation.getOperationMeta().getSwaggerOperation().getRequestBody();\n      if (requestBody != null && requestBody.getContent() != null\n          && requestBody.getContent().get(SwaggerConst.FORM_MEDIA_TYPE) != null\n          && requestBody.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema() != null\n          && requestBody.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties() != null) {\n        for (Object entry :\n            requestBody.getContent().get(SwaggerConst.FORM_MEDIA_TYPE).getSchema().getProperties().entrySet()) {\n          Entry<String, Schema> types = (Entry<String, Schema>) entry;\n          if (swaggerArguments.get(types.getKey()) == null) {\n            Type type = invocation.getOperationMeta().getSwaggerProducerOperation()\n                .getSwaggerParameterType(types.getKey());\n            swaggerArguments.put(types.getKey(), defaultPrimitiveValue(null, type));\n          }\n        }\n      }\n    }\n    return swaggerArguments;\n  }\n\n  public static void decodeRequest(Invocation invocation, RequestHeader header, OperationProtobuf operationProtobuf,\n      Buffer bodyBuffer) throws Exception {\n    RequestRootDeserializer<Object> requestDeserializer = operationProtobuf.getRequestRootDeserializer();\n    Map<String, Object> swaggerArguments = requestDeserializer.deserialize(bodyBuffer.getBytes());\n    addPrimitiveTypeDefaultValues(invocation, swaggerArguments);\n    invocation.setSwaggerArguments(swaggerArguments);\n  }\n\n  public static RequestHeader readRequestHeader(Buffer headerBuffer) throws Exception {\n    return RequestHeader.readObject(headerBuffer);\n  }\n\n  public static Buffer encodeResponse(long msgId, ResponseHeader header, ResponseRootSerializer bodySchema,\n      Object body) throws Exception {\n    try (HighwayOutputStream os = new HighwayOutputStream(msgId)) {\n      os.write(header, bodySchema, body);\n      return os.getBuffer();\n    }\n  }\n\n  public static Response decodeResponse(Invocation invocation, OperationProtobuf operationProtobuf, TcpData tcpData)\n      throws Exception {\n    ResponseHeader header = ResponseHeader.readObject(tcpData.getHeaderBuffer());\n    if (header.getContext() != null) {\n      invocation.getContext().putAll(header.getContext());\n    }\n\n    ResponseRootDeserializer<Object> bodySchema = operationProtobuf\n        .findResponseRootDeserializer(header.getStatusCode());\n    JavaType type = invocation.findResponseType(header.getStatusCode());\n    Object body = bodySchema\n        .deserialize(tcpData.getBodyBuffer().getBytes(), type);\n\n    Response response = Response.create(header.getStatusCode(), header.getReasonPhrase()\n        , defaultPrimitiveValue(body, type));\n    response.setHeaders(header.toMultiMap());\n\n    return response;\n  }\n\n  private static Object defaultPrimitiveValue(Object body, Type type) {\n    if (body == null) {\n      if (type instanceof Class<?> && ((Class<?>) type).isPrimitive()) {\n        return Defaults.defaultValue((Class<?>) type);\n      }\n      if (type instanceof JavaType && ((JavaType) type).isPrimitive()) {\n        return Defaults.defaultValue(((JavaType) type).getRawClass());\n      }\n    }\n    return body;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.transport.common.TransportConfigUtils;\n\npublic final class HighwayConfig {\n  private HighwayConfig() {\n  }\n\n  public static String getAddress() {\n    return LegacyPropertyFactory.getStringProperty(\"servicecomb.highway.address\", null);\n  }\n\n  public static int getServerThreadCount() {\n    return TransportConfigUtils.readVerticleCount(\n        \"servicecomb.highway.server.verticle-count\",\n        \"servicecomb.highway.server.thread-count\");\n  }\n\n  public static int getClientThreadCount() {\n    return TransportConfigUtils.readVerticleCount(\n        \"servicecomb.highway.client.verticle-count\",\n        \"servicecomb.highway.client.thread-count\");\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\nimport org.apache.servicecomb.transport.highway.message.ResponseHeader;\n\npublic class HighwayOutputStream extends TcpOutputStream {\n  public HighwayOutputStream(long msgId) {\n    super(msgId);\n  }\n\n  public void write(RequestHeader header, RequestRootSerializer requestRootSerializer, Object body) throws Exception {\n    write(RequestHeader.getRootSerializer().serialize(header), requestRootSerializer.serialize(body));\n  }\n\n  public void write(ResponseHeader header, ResponseRootSerializer responseRootSerializer, Object body)\n      throws Exception {\n    write(ResponseHeader.getRootSerializer().serialize(header), responseRootSerializer.serialize(body));\n  }\n\n  public void write(RequestHeader header, RootSerializer bodySerializer, Object body) throws Exception {\n    write(RequestHeader.getRootSerializer(), header, bodySerializer, body);\n  }\n\n  public void write(ResponseHeader header, RootSerializer bodySerializer, Object body) throws Exception {\n    write(ResponseHeader.getRootSerializer(), header, bodySerializer, body);\n  }\n\n  public void write(RootSerializer headerSerializer, Object header, RootSerializer bodySerializer, Object body)\n      throws Exception {\n    byte[] headerBytes = new byte[0];\n    byte[] bodyBytes = new byte[0];\n\n    if (headerSerializer != null) {\n      headerBytes = headerSerializer.serialize(header);\n    }\n\n    if (bodySerializer != null) {\n      bodyBytes = bodySerializer.serialize(body);\n    }\n\n    write(headerBytes, bodyBytes);\n  }\n\n  private void write(byte[] headerBytes, byte[] bodyBytes)\n      throws Exception {\n    int headerLength = 0;\n    int totalLength = 0;\n\n    if (headerBytes != null) {\n      headerLength = headerBytes.length;\n      totalLength = totalLength + headerLength;\n    }\n\n    if (bodyBytes != null) {\n      totalLength = totalLength + bodyBytes.length;\n    }\n\n    this.writeLength(totalLength, headerLength);\n    this.write(headerBytes);\n    this.write(bodyBytes);\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayProducerInvocationFlow.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.core.invocation.ProducerInvocationFlow;\nimport org.apache.servicecomb.foundation.common.utils.ExceptionUtils;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpConnection;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class HighwayProducerInvocationFlow extends ProducerInvocationFlow {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HighwayProducerInvocationFlow.class);\n\n  private final TcpConnection connection;\n\n  private final long msgId;\n\n  public HighwayProducerInvocationFlow(InvocationCreator invocationCreator, TcpConnection connection, long msgId) {\n    super(invocationCreator);\n    this.connection = connection;\n    this.msgId = msgId;\n  }\n\n  @Override\n  protected Invocation sendCreateInvocationException(Throwable throwable) {\n    logException(throwable);\n    return null;\n  }\n\n  private void logException(Throwable throwable) {\n    if (Exceptions.isPrintInvocationStackTrace()) {\n      LOGGER.error(\"Failed to prepare invocation, msgId={}.\", msgId, throwable);\n      return;\n    }\n\n    LOGGER.error(\"Failed to prepare invocation, msgId={}, message={}.\", msgId,\n        ExceptionUtils.getExceptionMessageWithoutTrace(throwable));\n  }\n\n  @Override\n  protected void endResponse(Invocation invocation, Response response) {\n    HighwayTransportContext transportContext = invocation.getTransportContext();\n    connection.write(transportContext.getResponseBuffer());\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServer.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.vertx.server.TcpServer;\nimport org.apache.servicecomb.foundation.vertx.server.TcpServerConnection;\n\npublic class HighwayServer extends TcpServer {\n  private final Endpoint endpoint;\n\n  public HighwayServer(Endpoint endpoint) {\n    super((URIEndpointObject) endpoint.getAddress());\n    this.endpoint = endpoint;\n  }\n\n  @Override\n  protected TcpServerConnection createTcpServerConnection() {\n    return new HighwayServerConnection(endpoint);\n  }\n\n  @Override\n  protected int getConnectionLimit() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.highway.server.connection-limit\", Integer.MAX_VALUE);\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport static org.apache.servicecomb.core.exception.Exceptions.toProducerResponse;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.filter.ProviderFilter;\nimport org.apache.servicecomb.foundation.common.utils.AsyncUtils;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.apache.servicecomb.transport.highway.message.ResponseHeader;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class HighwayServerCodecFilter extends AbstractFilter implements ProviderFilter {\n  public static final String NAME = \"highway-server-codec\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    // almost time, should be the first filter.\n    return Filter.PROVIDER_SCHEDULE_FILTER_ORDER - 2000;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.HIGHWAY.equals(transport);\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    return CompletableFuture.completedFuture(invocation)\n        .thenCompose(this::decodeRequest)\n        .thenCompose(nextNode::onFilter)\n        .exceptionally(exception -> toProducerResponse(invocation, exception))\n        .thenCompose(response -> encodeResponse(invocation, response));\n  }\n\n  protected CompletableFuture<Invocation> decodeRequest(Invocation invocation) {\n    HighwayTransportContext transportContext = invocation.getTransportContext();\n    try {\n      invocation.getInvocationStageTrace().startProviderDecodeRequest();\n      HighwayCodec.decodeRequest(invocation,\n          transportContext.getHeader(),\n          transportContext.getOperationProtobuf(),\n          transportContext.getBodyBuffer());\n      invocation.getInvocationStageTrace().finishProviderDecodeRequest();\n      return CompletableFuture.completedFuture(invocation);\n    } catch (Exception e) {\n      return AsyncUtils.completeExceptionally(e);\n    }\n  }\n\n  protected CompletableFuture<Response> encodeResponse(Invocation invocation, Response response) {\n    invocation.onEncodeResponseStart(response);\n\n    ResponseHeader header = new ResponseHeader();\n    header.setStatusCode(response.getStatusCode());\n    header.setReasonPhrase(response.getReasonPhrase());\n    header.setContext(invocation.getContext());\n    header.fromMultiMap(response.getHeaders());\n\n    HighwayTransportContext transportContext = invocation.getTransportContext();\n    long msgId = transportContext.getMsgId();\n    OperationProtobuf operationProtobuf = transportContext.getOperationProtobuf();\n    ResponseRootSerializer bodySchema = operationProtobuf.findResponseRootSerializer(response.getStatusCode());\n\n    try {\n      boolean failed = response.getResult() instanceof InvocationException;\n      Buffer respBuffer;\n      if (failed) {\n        respBuffer = HighwayCodec.encodeResponse(\n            msgId, header, bodySchema, ((InvocationException) response.getResult()).getErrorData());\n      } else {\n        respBuffer = HighwayCodec.encodeResponse(\n            msgId, header, bodySchema, response.getResult());\n      }\n      transportContext.setResponseBuffer(respBuffer);\n\n      invocation.onEncodeResponseFinish();\n      return CompletableFuture.completedFuture(response);\n    } catch (Exception e) {\n      // keep highway performance and simple, this encoding/decoding error not need handle by client\n      String msg = String.format(\"encode response failed, msgId=%d\", msgId);\n      return AsyncUtils.completeExceptionally(new IllegalStateException(msg, e));\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerConnection.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.definition.SchemaMeta;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.foundation.vertx.server.TcpBufferHandler;\nimport org.apache.servicecomb.foundation.vertx.server.TcpParser;\nimport org.apache.servicecomb.foundation.vertx.server.TcpServerConnection;\nimport org.apache.servicecomb.transport.highway.message.LoginRequest;\nimport org.apache.servicecomb.transport.highway.message.LoginResponse;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\nimport org.apache.servicecomb.transport.highway.message.ResponseHeader;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.net.NetSocket;\n\npublic class HighwayServerConnection extends TcpServerConnection implements TcpBufferHandler {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HighwayServerConnection.class);\n\n  private final Endpoint endpoint;\n\n  public HighwayServerConnection(Endpoint endpoint) {\n    this.endpoint = endpoint;\n  }\n\n  @Override\n  public void init(NetSocket netSocket) {\n    splitter = new TcpParser(this);\n    super.init(netSocket);\n  }\n\n  @Override\n  public void handle(long msgId, Buffer headerBuffer, Buffer bodyBuffer) {\n    RequestHeader requestHeader = decodeRequestHeader(msgId, headerBuffer);\n    if (requestHeader == null) {\n      return;\n    }\n\n    switch (requestHeader.getMsgType()) {\n      case MsgType.REQUEST:\n        onRequest(msgId, requestHeader, bodyBuffer);\n        break;\n      case MsgType.LOGIN:\n        onLogin(msgId, requestHeader, bodyBuffer);\n        break;\n\n      default:\n        throw new Error(\"Unknown tcp msgType \" + requestHeader.getMsgType());\n    }\n  }\n\n  protected RequestHeader decodeRequestHeader(long msgId, Buffer headerBuffer) {\n    try {\n      return HighwayCodec.readRequestHeader(headerBuffer);\n    } catch (Exception e) {\n      String msg = String.format(\"decode request header error, msgId=%d\",\n          msgId);\n      LOGGER.error(msg, e);\n\n      netSocket.close();\n      return null;\n    }\n  }\n\n  protected void onLogin(long msgId, RequestHeader header, Buffer bodyBuffer) {\n    LoginRequest request;\n    try {\n      request = LoginRequest.readObject(bodyBuffer);\n    } catch (Exception e) {\n      String msg = String.format(\"decode setParameter error, msgId=%d\",\n          msgId);\n      LOGGER.error(msg, e);\n      netSocket.close();\n      return;\n    }\n\n    if (request != null) {\n      this.setProtocol(request.getProtocol());\n      this.setZipName(request.getZipName());\n    }\n\n    try (HighwayOutputStream os = new HighwayOutputStream(msgId)) {\n      ResponseHeader responseHeader = new ResponseHeader();\n      responseHeader.setStatusCode(Status.OK.getStatusCode());\n\n      LoginResponse response = new LoginResponse();\n\n      os.write(ResponseHeader.getRootSerializer(),\n          responseHeader,\n          LoginResponse.getRootSerializer(),\n          response);\n      netSocket.write(os.getBuffer());\n    } catch (Exception e) {\n      throw new Error(\"impossible.\", e);\n    }\n  }\n\n  protected void onRequest(long msgId, RequestHeader header, Buffer bodyBuffer) {\n    InvocationCreator creator = () -> createInvocation(msgId, header, bodyBuffer);\n    new HighwayProducerInvocationFlow(creator, this, msgId)\n        .run();\n  }\n\n  public CompletableFuture<Invocation> createInvocation(long msgId, RequestHeader header, Buffer bodyBuffer) {\n    MicroserviceMeta microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();\n    SchemaMeta schemaMeta = microserviceMeta.ensureFindSchemaMeta(header.getSchemaId());\n    OperationMeta operationMeta = schemaMeta.ensureFindOperation(header.getOperationName());\n\n    Invocation invocation = InvocationFactory.forProvider(endpoint,\n        operationMeta,\n        null);\n    invocation.getHandlerContext().put(CoreConst.REMOTE_ADDRESS, netSocket.remoteAddress());\n\n    HighwayTransportContext transportContext = new HighwayTransportContext()\n        .setConnection(this)\n        .setMsgId(msgId)\n        .setHeader(header)\n        .setBodyBuffer(bodyBuffer)\n        .setOperationProtobuf(ProtobufManager.getOrCreateOperation(invocation));\n    invocation.setTransportContext(transportContext);\n\n    invocation.mergeContext(header.getContext());\n\n    return CompletableFuture.completedFuture(invocation);\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport java.net.InetSocketAddress;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.AbstractVerticle;\nimport io.vertx.core.Context;\nimport io.vertx.core.Promise;\nimport io.vertx.core.Vertx;\n\npublic class HighwayServerVerticle extends AbstractVerticle {\n  private static final Logger LOGGER = LoggerFactory.getLogger(HighwayServerVerticle.class);\n\n  public static final String SSL_KEY = \"highway.provider\";\n\n  private Endpoint endpoint;\n\n  private URIEndpointObject endpointObject;\n\n  @Override\n  public void init(Vertx vertx, Context context) {\n    super.init(vertx, context);\n    this.endpoint = (Endpoint) context.config().getValue(AbstractTransport.ENDPOINT_KEY);\n    this.endpointObject = (URIEndpointObject) this.endpoint.getAddress();\n  }\n\n  @Override\n  public void start(Promise<Void> startPromise) throws Exception {\n    try {\n      super.start();\n      startListen(startPromise);\n    } catch (Throwable e) {\n      // vert.x got some states that not print error and execute call back in VertexUtils.blockDeploy, we add a log our self.\n      LOGGER.error(\"\", e);\n      throw e;\n    }\n  }\n\n  protected void startListen(Promise<Void> startPromise) {\n    // if listen address is not provided, do not fail and maybe a consumer service.\n    if (endpointObject == null) {\n      LOGGER.warn(\"highway listen address is not configured, will not listen.\");\n      startPromise.complete();\n      return;\n    }\n\n    HighwayServer server = new HighwayServer(endpoint);\n    server.init(vertx, SSL_KEY, ar -> {\n      if (ar.succeeded()) {\n        InetSocketAddress socketAddress = ar.result();\n        LOGGER.info(\"highway listen success. address={}:{}\",\n            socketAddress.getHostString(),\n            socketAddress.getPort());\n        startPromise.complete();\n        return;\n      }\n\n      LOGGER.error(CoreConst.HIGHWAY, ar.cause());\n      startPromise.fail(ar.cause());\n    });\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport java.util.Collections;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.vertx.SimpleJsonObject;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpConst;\n\nimport io.vertx.core.DeploymentOptions;\n\npublic class HighwayTransport extends AbstractTransport {\n  private final HighwayClient highwayClient = new HighwayClient();\n\n  @Override\n  public String getName() {\n    return CoreConst.HIGHWAY;\n  }\n\n  @Override\n  public boolean init() throws Exception {\n    highwayClient.init(transportVertx);\n\n    DeploymentOptions deployOptions = new DeploymentOptions().setInstances(HighwayConfig.getServerThreadCount());\n    setListenAddressWithoutSchema(HighwayConfig.getAddress(), Collections.singletonMap(TcpConst.LOGIN, \"true\"));\n    SimpleJsonObject json = new SimpleJsonObject();\n    json.put(ENDPOINT_KEY, getEndpoint());\n    deployOptions.setConfig(json);\n    deployOptions.setWorkerPoolName(\"pool-worker-transport-highway\");\n    Map<String, Object> result = VertxUtils.blockDeploy(transportVertx, HighwayServerVerticle.class, deployOptions);\n    if ((boolean) result.get(\"code\")) {\n      return true;\n    } else {\n      throw new IllegalStateException((String) result.get(\"message\"));\n    }\n  }\n\n  public HighwayClient getHighwayClient() {\n    return highwayClient;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.foundation.vertx.tcp.TcpConnection;\nimport org.apache.servicecomb.swagger.invocation.context.VertxTransportContext;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.buffer.Buffer;\n\npublic class HighwayTransportContext implements VertxTransportContext {\n  private final Context vertxContext;\n\n  private TcpConnection connection;\n\n  private long msgId;\n\n  private RequestHeader header;\n\n  private Buffer bodyBuffer;\n\n  private OperationProtobuf operationProtobuf;\n\n  private Buffer responseBuffer;\n\n  public HighwayTransportContext() {\n    this.vertxContext = Vertx.currentContext();\n  }\n\n  @Override\n  public Context getVertxContext() {\n    return vertxContext;\n  }\n\n  public TcpConnection getConnection() {\n    return connection;\n  }\n\n  public HighwayTransportContext setConnection(TcpConnection connection) {\n    this.connection = connection;\n    return this;\n  }\n\n  public long getMsgId() {\n    return msgId;\n  }\n\n  public HighwayTransportContext setMsgId(long msgId) {\n    this.msgId = msgId;\n    return this;\n  }\n\n  public RequestHeader getHeader() {\n    return header;\n  }\n\n  public HighwayTransportContext setHeader(RequestHeader header) {\n    this.header = header;\n    return this;\n  }\n\n  public Buffer getBodyBuffer() {\n    return bodyBuffer;\n  }\n\n  public HighwayTransportContext setBodyBuffer(Buffer bodyBuffer) {\n    this.bodyBuffer = bodyBuffer;\n    return this;\n  }\n\n  public OperationProtobuf getOperationProtobuf() {\n    return operationProtobuf;\n  }\n\n  public HighwayTransportContext setOperationProtobuf(\n      OperationProtobuf operationProtobuf) {\n    this.operationProtobuf = operationProtobuf;\n    return this;\n  }\n\n  public Buffer getResponseBuffer() {\n    return responseBuffer;\n  }\n\n  public HighwayTransportContext setResponseBuffer(Buffer responseBuffer) {\n    this.responseBuffer = responseBuffer;\n    return this;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/MsgType.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\npublic final class MsgType {\n  public static final byte REQUEST = 0;\n\n  public static final byte LOGIN = 1;\n\n  private MsgType() {\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/TransportHighwayConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class TransportHighwayConfiguration {\n  @Bean\n  public HighwayServerCodecFilter highwayServerCodecFilter() {\n    return new HighwayServerCodecFilter();\n  }\n\n  @Bean\n  public HighwayClientFilter highwayClientFilter() {\n    return new HighwayClientFilter();\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/message/Headers.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway.message;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Headers {\n  private Map<String, List<Object>> headerMap;\n\n  public Map<String, List<Object>> getHeaderMap() {\n    return headerMap;\n  }\n\n  public void setHeaderMap(Map<String, List<Object>> headerMap) {\n    this.headerMap = headerMap;\n  }\n\n  public Object getFirst(String name) {\n    if (headerMap == null) {\n      return null;\n    }\n\n    List<Object> values = headerMap.get(name);\n    if (values == null || values.isEmpty()) {\n      return null;\n    }\n\n    return values.get(0);\n  }\n\n  public List<Object> getHeader(String name) {\n    if (headerMap == null) {\n      return null;\n    }\n\n    return headerMap.get(name);\n  }\n\n  public Headers addHeader(String name, Object value) {\n    if (headerMap == null) {\n      headerMap = new HashMap<>();\n    }\n\n    List<Object> values = headerMap.computeIfAbsent(name, k -> new ArrayList<>());\n    values.add(value);\n\n    return this;\n  }\n\n  public Headers addHeader(String name, List<Object> value) {\n    if (headerMap == null) {\n      headerMap = new HashMap<>();\n    }\n\n    List<Object> values = headerMap.computeIfAbsent(name, k -> new ArrayList<>());\n    values.addAll(value);\n\n    return this;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/message/LoginRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway.message;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class LoginRequest {\n  private static final ProtoMapperFactory protoMapperFactory = new ProtoMapperFactory();\n\n  private static final RootDeserializer<LoginRequest> rootDeserializer = protoMapperFactory\n      .createFromName(\"LoginRequest.proto\")\n      .createRootDeserializer(\"LoginRequest\", LoginRequest.class);\n\n  private static final RootSerializer rootSerializer = protoMapperFactory.createFromName(\"LoginRequest.proto\")\n      .createRootSerializer(\"LoginRequest\", LoginRequest.class);\n\n  public static RootSerializer getRootSerializer() {\n    return rootSerializer;\n  }\n\n  public static LoginRequest readObject(Buffer bodyBuffer) throws Exception {\n    return rootDeserializer.deserialize(bodyBuffer.getBytes());\n  }\n\n  private String protocol;\n\n  // 压缩算法名字\n  private String zipName;\n\n  public String getProtocol() {\n    return protocol;\n  }\n\n  public void setProtocol(String protocol) {\n    this.protocol = protocol;\n  }\n\n  public String getZipName() {\n    return zipName;\n  }\n\n  public void setZipName(String zipName) {\n    this.zipName = zipName;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/message/LoginResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway.message;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class LoginResponse {\n  private static final ProtoMapperFactory protoMapperFactory = new ProtoMapperFactory();\n\n  private static final RootDeserializer<LoginResponse> rootDeserializer = protoMapperFactory\n      .createFromName(\"LoginResponse.proto\")\n      .createRootDeserializer(\"LoginResponse\", LoginResponse.class);\n\n  private static final RootSerializer rootSerializer = protoMapperFactory.createFromName(\"LoginResponse.proto\")\n      .createRootSerializer(\"LoginResponse\", LoginResponse.class);\n\n  public static RootSerializer getRootSerializer() {\n    return rootSerializer;\n  }\n\n  public static LoginResponse readObject(Buffer bodyBuffer) throws Exception {\n    return rootDeserializer.deserialize(bodyBuffer.getBytes());\n  }\n\n  private String protocol;\n\n  // 压缩算法名字\n  private String zipName;\n\n  public String getProtocol() {\n    return protocol;\n  }\n\n  public void setProtocol(String protocol) {\n    this.protocol = protocol;\n  }\n\n  public String getZipName() {\n    return zipName;\n  }\n\n  public void setZipName(String zipName) {\n    this.zipName = zipName;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/message/RequestHeader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway.message;\n\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\nimport io.vertx.core.buffer.Buffer;\n\npublic class RequestHeader {\n  private static final ProtoMapperFactory protoMapperFactory = new ProtoMapperFactory();\n\n  private static final RootDeserializer<RequestHeader> rootDeserializer = protoMapperFactory\n      .createFromName(\"RequestHeader.proto\")\n      .createRootDeserializer(\"RequestHeader\", RequestHeader.class);\n\n  private static final RootSerializer rootSerializer = protoMapperFactory.createFromName(\"RequestHeader.proto\")\n      .createRootSerializer(\"RequestHeader\", RequestHeader.class);\n\n  public static RootSerializer getRootSerializer() {\n    return rootSerializer;\n  }\n\n  public static RequestHeader readObject(Buffer bodyBuffer) throws Exception {\n    return rootDeserializer.deserialize(bodyBuffer.getBytes());\n  }\n\n  private int msgType;\n\n  // 运行时必须的数据，比如body是否压缩\n  // 预留特性选项\n  private int flags;\n\n  private String destMicroservice;\n\n  private String schemaId;\n\n  private String operationName;\n\n  private Map<String, String> context;\n\n  public int getMsgType() {\n    return msgType;\n  }\n\n  public void setMsgType(int msgType) {\n    this.msgType = msgType;\n  }\n\n  public String getDestMicroservice() {\n    return destMicroservice;\n  }\n\n  public void setDestMicroservice(String destMicroservice) {\n    this.destMicroservice = destMicroservice;\n  }\n\n  public int getFlags() {\n    return flags;\n  }\n\n  public void setFlags(int flags) {\n    this.flags = flags;\n  }\n\n  public String getSchemaId() {\n    return schemaId;\n  }\n\n  public void setSchemaId(String schemaId) {\n    this.schemaId = schemaId;\n  }\n\n  public String getOperationName() {\n    return operationName;\n  }\n\n  public void setOperationName(String operationName) {\n    this.operationName = operationName;\n  }\n\n  public Map<String, String> getContext() {\n    return context;\n  }\n\n  public void setContext(Map<String, String> context) {\n    this.context = context;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/message/ResponseHeader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway.message;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;\nimport org.apache.servicecomb.foundation.protobuf.RootDeserializer;\nimport org.apache.servicecomb.foundation.protobuf.RootSerializer;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\n\npublic class ResponseHeader {\n  private static final ProtoMapperFactory protoMapperFactory = new ProtoMapperFactory();\n\n  private static final RootDeserializer<ResponseHeader> rootDeserializer = protoMapperFactory\n      .createFromName(\"ResponseHeader.proto\")\n      .createRootDeserializer(\"ResponseHeader\", ResponseHeader.class);\n\n  private static final RootSerializer rootSerializer = protoMapperFactory.createFromName(\"ResponseHeader.proto\")\n      .createRootSerializer(\"ResponseHeader\", ResponseHeader.class);\n\n  public static RootSerializer getRootSerializer() {\n    return rootSerializer;\n  }\n\n  public static ResponseHeader readObject(Buffer bodyBuffer) throws Exception {\n    return rootDeserializer.deserialize(bodyBuffer.getBytes());\n  }\n\n  // 运行时必须的数据，比如body是否压缩\n  // 预留特性选项\n  private int flags;\n\n  private int statusCode;\n\n  private String reasonPhrase;\n\n  private Map<String, String> context;\n\n  private Headers headers = new Headers();\n\n  public int getFlags() {\n    return flags;\n  }\n\n  public void setFlags(int flags) {\n    this.flags = flags;\n  }\n\n  public int getStatusCode() {\n    return statusCode;\n  }\n\n  public void setStatusCode(int statusCode) {\n    this.statusCode = statusCode;\n  }\n\n  public String getReasonPhrase() {\n    return reasonPhrase;\n  }\n\n  public void setReasonPhrase(String reason) {\n    this.reasonPhrase = reason;\n  }\n\n  public Map<String, String> getContext() {\n    return context;\n  }\n\n  public void setContext(Map<String, String> context) {\n    this.context = context;\n  }\n\n  public Headers getHeaders() {\n    return headers;\n  }\n\n  public void setHeaders(Headers headers) {\n    this.headers = headers;\n  }\n\n  public void fromMultiMap(MultiMap multiMap) {\n    if (multiMap == null) {\n      return;\n    }\n\n    for (Entry<String, String> entry : multiMap.entries()) {\n      headers.addHeader(entry.getKey(), entry.getValue());\n    }\n  }\n\n  public MultiMap toMultiMap() {\n    MultiMap multiMap = MultiMap.caseInsensitiveMultiMap();\n    Map<String, List<Object>> headerMap = headers.getHeaderMap();\n    if (headerMap == null) {\n      return multiMap;\n    }\n\n    for (Entry<String, List<Object>> entry : headerMap.entrySet()) {\n      String key = entry.getKey();\n      for (Object value : entry.getValue()) {\n        multiMap.add(key, value.toString());\n      }\n    }\n    return multiMap;\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/LoginRequest.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\npackage org.apache.servicecomb.transport.highway.message;\n\nmessage LoginRequest {\n  string protocol = 1;\n  string zipName = 2;\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/LoginResponse.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\npackage org.apache.servicecomb.transport.highway.message;\n\nmessage LoginResponse {\n  string protocol = 1;\n  string zipName = 2;\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.transport.highway.HighwayTransport\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.transport.highway.TransportHighwayConfiguration\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/RequestHeader.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\npackage org.apache.servicecomb.transport.highway.message;\n\nmessage RequestHeader {\n  string destMicroservice = 1;\n  int32 msgType = 2;\n  int32 flags = 3;\n  string schemaId = 4;\n  string operationName = 5;\n  map<string,string> context = 6;\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/ResponseHeader.proto",
    "content": "/*\n  Licensed to the Apache Software Foundation (ASF) under one or more\n  contributor license agreements.  See the NOTICE file distributed with\n  this work for additional information regarding copyright ownership.\n  The ASF licenses this file to You under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with\n  the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n */\n\nsyntax = \"proto3\";\nimport \"google/protobuf/any.proto\";\npackage org.apache.servicecomb.transport.highway.message;\n\nmessage ResponseHeader {\n  int32 flags = 1;\n  int32 statusCode = 2;\n  string reasonPhrase = 3;\n  map<string,string> context = 4;\n  Headers headers = 5;\n}\n\nmessage Headers {\n  map<string,ListGoogle_protobuf_Any> headerMap = 1;\n}\n\n//@WrapProperty\nmessage ListGoogle_protobuf_Any {\n  repeated google.protobuf.Any value = 1;\n}\n"
  },
  {
    "path": "transports/transport-highway/src/main/resources/microservice.yaml",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\nservicecomb-config-order: -500\nservicecomb:\n  filter-chains:\n    transport:\n      scb-consumer-transport:\n        highway: highway-client\n      scb-producer-transport:\n        highway: highway-server-codec\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/common/MockUtil.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.common;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.transport.highway.HighwayCodec;\nimport org.apache.servicecomb.transport.highway.HighwayConfig;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.buffer.Buffer;\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class MockUtil {\n\n  private static final MockUtil instance = new MockUtil();\n\n  private MockUtil() {\n\n  }\n\n  public static MockUtil getInstance() {\n    return instance;\n  }\n\n  public void mockHighwayConfig() {\n\n    new MockUp<HighwayConfig>() {\n      @Mock\n      String getAddress() {\n        return \"127.0.0.1\";\n      }\n    };\n  }\n\n  public RequestHeader requestHeader = new RequestHeader();\n\n  public boolean decodeRequestSucc = true;\n\n  public void mockHighwayCodec() {\n\n    new MockUp<HighwayCodec>() {\n      @Mock\n      RequestHeader readRequestHeader(Buffer headerBuffer) throws Exception {\n        return requestHeader;\n      }\n\n      @Mock\n      public Invocation decodeRequest(RequestHeader header, OperationProtobuf operationProtobuf, Buffer bodyBuffer)\n          throws Exception {\n        if (decodeRequestSucc) {\n          return Mockito.mock(Invocation.class);\n        }\n\n        throw new Error(\"decode failed\");\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilterTest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;\nimport static org.apache.servicecomb.core.SCBEngine.CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.apache.servicecomb.core.SCBEngine.DEFAULT_TURN_DOWN_STATUS_WAIT_SEC;\nimport static org.assertj.core.api.Assertions.assertThat;\n\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.SCBStatus;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.core.invocation.InvocationFactory;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.apache.servicecomb.transport.highway.message.RequestHeader;\nimport org.apache.servicecomb.transport.highway.message.ResponseHeader;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.mockito.Mockito;\nimport org.skyscreamer.jsonassert.JSONAssert;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.impl.SysProps;\nimport io.vertx.core.json.Json;\nimport mockit.Expectations;\nimport mockit.Mocked;\nimport mockit.Verifications;\n\npublic class HighwayServerCodecFilterTest {\n  HighwayServerCodecFilter codecFilter = new HighwayServerCodecFilter();\n\n  Invocation invocation;\n\n  @Mocked\n  Endpoint endpoint;\n\n  @Mocked\n  OperationMeta operationMeta;\n\n  @Mocked\n  HighwayTransportContext transportContext;\n\n  MultiMap headers = MultiMap.caseInsensitiveMultiMap();\n\n  FilterNode nextNode = new FilterNode(new AbstractFilter() {\n    @Override\n    public String getName() {\n      return \"test\";\n    }\n\n    @Override\n    public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n      Response response = Response.ok(\"ok\");\n      response.setHeaders(headers);\n      return CompletableFuture.completedFuture(response);\n    }\n  });\n\n  static SCBEngine engine;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(CFG_KEY_TURN_DOWN_STATUS_WAIT_SEC,\n        long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC);\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n\n    engine = SCBBootstrap.createSCBEngineForTest(environment);\n    engine.setStatus(SCBStatus.UP);\n    invocation = InvocationFactory.forProvider(endpoint, operationMeta, null);\n  }\n\n  @After\n  public void tearDown() {\n    engine.destroy();\n  }\n\n  private void mockDecodeRequestFail() throws Exception {\n    new Expectations(invocation) {\n      {\n        invocation.getTransportContext();\n        result = transportContext;\n      }\n    };\n    new Expectations(HighwayCodec.class) {\n      {\n        HighwayCodec.decodeRequest(invocation, (RequestHeader) any, (OperationProtobuf) any, (Buffer) any);\n        result = new RuntimeExceptionWithoutStackTrace(\"encode request failed\");\n      }\n    };\n  }\n\n  @Test\n  public void should_not_invoke_filter_when_decode_request_failed(@Mocked FilterNode nextNode) throws Exception {\n    mockDecodeRequestFail();\n\n    codecFilter.onFilter(invocation, nextNode);\n\n    new Verifications() {\n      {\n        nextNode.onFilter(invocation);\n        times = 0;\n      }\n    };\n  }\n\n  @Test\n  public void should_convert_exception_to_response_when_decode_request_failed()\n      throws Exception {\n    mockDecodeRequestFail();\n\n    Response response = codecFilter.onFilter(invocation, nextNode).get();\n\n    assertThat(response.getStatus()).isEqualTo(INTERNAL_SERVER_ERROR);\n\n    JSONAssert.assertEquals(Json.encode(((InvocationException) response.getResult()).getErrorData()),\n        \"{\\\"code\\\":\\\"SCB.50000000\\\",\\\"message\\\":\\\"Unexpected \"\n            + \"exception when processing null. encode request failed\\\"}\", false);\n  }\n\n  private void success_invocation() throws InterruptedException, ExecutionException {\n    new Expectations(invocation) {\n      {\n        invocation.getTransportContext();\n        result = transportContext;\n      }\n    };\n\n    codecFilter.onFilter(invocation, nextNode).get();\n  }\n\n  @Test\n  public void should_encode_response_header(@Mocked ResponseHeader responseHeader)\n      throws ExecutionException, InterruptedException {\n    success_invocation();\n\n    new Verifications() {\n      {\n        MultiMap captureHeaders;\n        responseHeader.fromMultiMap(captureHeaders = withCapture());\n        assertThat(captureHeaders).isSameAs(headers);\n      }\n    };\n  }\n\n  @Test\n  public void should_encode_response() throws ExecutionException, InterruptedException {\n    success_invocation();\n\n    new Verifications() {\n      {\n        Buffer captureBuffer;\n        transportContext.setResponseBuffer(captureBuffer = withCapture());\n        assertThat(captureBuffer).isNotNull();\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.AbstractVerticle;\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.Vertx;\nimport mockit.Deencapsulation;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestHighwayClient {\n  private static final String REQUEST_TIMEOUT_KEY = \"servicecomb.request.timeout\";\n\n  HighwayClient client = new HighwayClient();\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  static long nanoTime = 123;\n\n  @BeforeClass\n  public static void setup() {\n    new MockUp<System>() {\n      @Mock\n      long nanoTime() {\n        return nanoTime;\n      }\n    };\n  }\n\n  @AfterClass\n  public static void teardown() {\n\n  }\n\n  @Before\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(REQUEST_TIMEOUT_KEY, long.class, (long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT))\n        .thenReturn((long) 2000);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.client.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.client.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.server.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.server.thread-count\", int.class, -1))\n        .thenReturn(-1);\n  }\n\n  @Test\n  public void testLoginTimeout(@Mocked Vertx vertx) {\n    TcpClientConfig tcpClientConfig = client.createTcpClientConfig();\n    Assertions.assertEquals(2000, tcpClientConfig.getMsLoginTimeout());\n  }\n\n  @Test\n  public void testHighwayClientSSL(@Mocked Vertx vertx) throws Exception {\n    new MockUp<VertxUtils>() {\n      @Mock\n      <VERTICLE extends AbstractVerticle> Map<String, Object> blockDeploy(Vertx vertx,\n          Class<VERTICLE> cls,\n          DeploymentOptions options) {\n        Map<String, Object> result = new HashMap<>();\n        result.put(\"code\", true);\n        return result;\n      }\n    };\n\n    client.init(vertx);\n\n    ClientPoolManager<HighwayClientConnectionPool> clientMgr = Deencapsulation.getField(client, \"clientMgr\");\n    Assertions.assertSame(vertx, Deencapsulation.getField(clientMgr, \"vertx\"));\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;\nimport org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationMeta;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.impl.SysProps;\n\npublic class TestHighwayTransport {\n  private static final Logger LOGGER = LoggerFactory.getLogger(TestHighwayTransport.class);\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @BeforeClass\n  public static void setup() {\n    VertxUtils.blockCloseVertxByName(\"transport\");\n    Thread.getAllStackTraces().keySet().forEach(t -> LOGGER.info(\"before: {}\", t.getName()));\n  }\n\n  @AfterClass\n  public static void teardown() {\n    VertxUtils.blockCloseVertxByName(\"transport\");\n    Thread.getAllStackTraces().keySet().forEach(t -> LOGGER.info(\"after: {}\", t.getName()));\n  }\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.request.timeout\", long.class, (long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT))\n        .thenReturn((long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.client.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.client.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.server.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.highway.server.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testGetInstance() {\n    HighwayTransport transport = new HighwayTransport();\n    Assertions.assertNotNull(transport);\n  }\n\n  @Test\n  public void testInit() {\n    HighwayTransport transport = new HighwayTransport();\n    transport.setEnvironment(environment);\n    boolean status = true;\n    try {\n      transport.init();\n    } catch (Exception e) {\n      e.printStackTrace();\n      status = false;\n    }\n\n    Assertions.assertTrue(status);\n  }\n\n  @Test\n  public void testHighway() {\n    HighwayTransport transport = new HighwayTransport();\n    Invocation invocation = Mockito.mock(Invocation.class);\n    commonHighwayMock(invocation);\n    Assertions.assertEquals(\"highway\", transport.getName());\n  }\n\n  private void commonHighwayMock(Invocation invocation) {\n    OperationMeta operationMeta = Mockito.mock(OperationMeta.class);\n    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);\n    OperationProtobuf operationProtobuf = Mockito.mock(OperationProtobuf.class);\n    Mockito.when(operationMeta.getExtData(\"protobuf\")).thenReturn(operationProtobuf);\n    Endpoint lEndpoint = Mockito.mock(Endpoint.class);\n    Mockito.when(invocation.getEndpoint()).thenReturn(lEndpoint);\n    RequestRootSerializer lWrapSchema = Mockito.mock(RequestRootSerializer.class);\n    Mockito.when(operationProtobuf.getRequestRootSerializer()).thenReturn(lWrapSchema);\n    URIEndpointObject ep = Mockito.mock(URIEndpointObject.class);\n    Mockito.when(lEndpoint.getAddress()).thenReturn(ep);\n    Mockito.when(ep.getHostOrIp()).thenReturn(\"127.0.0.1\");\n    Mockito.when(ep.getPort()).thenReturn(80);\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway;\n\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.transport.common.MockUtil;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Promise;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.json.JsonObject;\nimport mockit.Expectations;\nimport mockit.Mocked;\n\npublic class TestHighwayVerticle {\n  @Test\n  public void testHighwayVehicle(@Mocked Transport transport, @Mocked Vertx vertx, @Mocked Context context,\n                                 @Mocked JsonObject json) {\n    HighwayServerVerticle highwayVehicle = new HighwayServerVerticle();\n    URIEndpointObject endpointObject = new URIEndpointObject(\"highway://127.0.0.1:9090\");\n    new Expectations() {\n      {\n        transport.parseAddress(anyString);\n        result = endpointObject;\n      }\n    };\n\n    Endpoint endpoint = new Endpoint(transport, \"highway://127.0.0.1:9090\");\n\n    new Expectations() {\n      {\n        context.config();\n        result = json;\n        json.getValue(anyString);\n        result = endpoint;\n      }\n    };\n\n    highwayVehicle.init(vertx, context);\n    @SuppressWarnings(\"unchecked\")\n    Promise<Void> startPromise = Mockito.mock(Promise.class);\n    highwayVehicle.startListen(startPromise);\n    MockUtil.getInstance().mockHighwayConfig();\n    try {\n      highwayVehicle.startListen(startPromise);\n      Assertions.assertTrue(true);\n    } catch (Exception e) {\n      Assertions.fail();\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/message/TestHeaders.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway.message;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestHeaders {\n  @Test\n  public void test1() {\n    Headers headers = new Headers();\n    Assertions.assertNull(headers.getFirst(\"h1\"));\n    Assertions.assertNull(headers.getHeader(\"h1\"));\n\n    Map<String, List<Object>> headerMap = new HashMap<>();\n    List<Object> h1Value = Arrays.asList(\"h1v1\", \"h1v2\");\n    headerMap.put(\"h1\", h1Value);\n    headerMap.put(\"h2\", null);\n    headerMap.put(\"h3\", Arrays.asList());\n    headers.setHeaderMap(headerMap);\n\n    Assertions.assertEquals(headerMap, headers.getHeaderMap());\n    Assertions.assertEquals(\"h1v1\", headers.getFirst(\"h1\"));\n    Assertions.assertNull(headers.getFirst(\"h2\"));\n    Assertions.assertNull(headers.getFirst(\"h3\"));\n    Assertions.assertEquals(h1Value, headers.getHeader(\"h1\"));\n  }\n\n  @Test\n  public void test2() {\n    Headers headers = new Headers();\n    headers.addHeader(\"h1\", \"h1v1\");\n    headers.addHeader(\"h1\", \"h1v2\");\n\n    Assertions.assertEquals(\"h1v1\", headers.getFirst(\"h1\"));\n  }\n\n  @Test\n  public void addHeader_list() {\n    Headers headers = new Headers();\n    headers.addHeader(\"h\", Arrays.asList(\"v1\", \"v2\"));\n    headers.addHeader(\"h\", Arrays.asList(\"v3\"));\n\n    MatcherAssert.assertThat(headers.getHeader(\"h\"), Matchers.contains(\"v1\", \"v2\", \"v3\"));\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/message/TestLoginRequest.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway.message;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestLoginRequest {\n  @Test\n  public void test() {\n    LoginRequest req = new LoginRequest();\n    req.setProtocol(\"p\");\n    req.setZipName(\"z\");\n\n    Assertions.assertEquals(\"p\", req.getProtocol());\n    Assertions.assertEquals(\"z\", req.getZipName());\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/message/TestLoginResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.highway.message;\n\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\n\npublic class TestLoginResponse {\n  @Test\n  public void test() {\n    LoginResponse resp = new LoginResponse();\n    resp.setProtocol(\"p\");\n    resp.setZipName(\"z\");\n\n    Assertions.assertEquals(\"p\", resp.getProtocol());\n    Assertions.assertEquals(\"z\", resp.getZipName());\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/message/TestRequestHeader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway.message;\n\nimport java.util.Map;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestRequestHeader {\n\n  private RequestHeader requestHeader = null;\n\n  @Before\n  public void setUp() throws Exception {\n    requestHeader = new RequestHeader();\n  }\n\n  @After\n  public void tearDown() throws Exception {\n    requestHeader = null;\n  }\n\n  @Test\n  public void testContext() {\n\n    Map<String, String> context = null;\n    requestHeader.setContext(context);\n    Assertions.assertNull(requestHeader.getContext());\n  }\n\n  @Test\n  public void testDestMicroservice() {\n    requestHeader.setDestMicroservice(\"test\");\n    Assertions.assertEquals(\"test\", requestHeader.getDestMicroservice());\n  }\n\n  @Test\n  public void testFlags() {\n\n    requestHeader.setFlags(1);\n    Assertions.assertEquals(1, requestHeader.getFlags());\n  }\n\n  @Test\n  public void testOperationName() {\n\n    requestHeader.setOperationName(\"cse\");\n    Assertions.assertEquals(\"cse\", requestHeader.getOperationName());\n  }\n\n  @Test\n  public void testSchemaId() {\n\n    requestHeader.setSchemaId(\"id\");\n    Assertions.assertEquals(\"id\", requestHeader.getSchemaId());\n  }\n}\n"
  },
  {
    "path": "transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/message/TestResponseHeader.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.highway.message;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestResponseHeader {\n\n  private ResponseHeader responseHeader = null;\n\n  Map<String, String> context = new HashMap<>();\n\n  @Before\n  public void setUp() throws Exception {\n    responseHeader = new ResponseHeader();\n  }\n\n  @After\n  public void tearDown() throws Exception {\n    responseHeader = null;\n  }\n\n  @Test\n  public void testSetContext() {\n    context.put(\"key1\", \"v1\");\n    responseHeader.setContext(context);\n    Assertions.assertNotNull(responseHeader.getContext());\n    Assertions.assertEquals(\"v1\", responseHeader.getContext().get(\"key1\"));\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>transports</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>transport-rest</artifactId>\n  <name>Java Chassis::Transports::Rest</name>\n  <packaging>pom</packaging>\n\n  <modules>\n    <module>transport-rest-vertx</module>\n    <module>transport-rest-servlet</module>\n    <module>transport-rest-client</module>\n  </modules>\n</project>\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>transport-rest</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>transport-rest-client</artifactId>\n  <name>Java Chassis::Transports::Rest::Client</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-rx-java3</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-vertx</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-common</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-rest</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-local</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>swagger-generator-jaxrs</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.commons</groupId>\n      <artifactId>commons-text</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/BoundaryFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.UUID;\nimport java.util.concurrent.atomic.AtomicLong;\n\npublic interface BoundaryFactory {\n  String BOUNDARY_PREFIX = \"boundary-\" + UUID.randomUUID() + \"-\";\n\n  AtomicLong BOUNDARY_INDEX = new AtomicLong();\n\n  BoundaryFactory DEFAULT = () -> BOUNDARY_PREFIX + BOUNDARY_INDEX.getAndIncrement();\n\n  String create();\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/Http2TransportHttpClientOptionsSPI.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.client;\n\nimport io.vertx.core.http.HttpVersion;\n\npublic class Http2TransportHttpClientOptionsSPI extends HttpTransportHttpClientOptionsSPI {\n  public static final String CLIENT_NAME = \"http2-transport-client\";\n\n  @Override\n  public String clientName() {\n    return CLIENT_NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    return super.getOrder() + 1;\n  }\n\n  @Override\n  public boolean enabled() {\n    return TransportClientConfig.isHttp2TransportClientEnabled();\n  }\n\n  @Override\n  public HttpVersion getHttpVersion() {\n    return HttpVersion.HTTP_2;\n  }\n\n  @Override\n  public String getWorkerPoolName() {\n    return \"pool-worker-transport-client-http2\";\n  }\n\n  @Override\n  public boolean isUseAlpn() {\n    return TransportClientConfig.getUseAlpn();\n  }\n\n  @Override\n  public int getHttp2MultiplexingLimit() {\n    return TransportClientConfig.getHttp2MultiplexingLimit();\n  }\n\n  @Override\n  public int getHttp2MaxPoolSize() {\n    return TransportClientConfig.getHttp2ConnectionMaxPoolSize();\n  }\n\n  @Override\n  public int getIdleTimeoutInSeconds() {\n    return TransportClientConfig.getHttp2ConnectionIdleTimeoutInSeconds();\n  }\n\n  @Override\n  public int getKeepAliveTimeout() {\n    return TransportClientConfig.getHttp2ConnectionKeepAliveTimeoutInSeconds();\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpClientRequestFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport org.apache.servicecomb.core.Invocation;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.http.HttpClient;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.RequestOptions;\n\n/**\n * some service has special domain name rule, eg: k8s<br>\n * assume k8s domain name is https://k8s.com:1234, and clusterId is my-id<br>\n * then must send request to https://my-id.k8s.com:1234<br>\n * <br>\n * this interface allowed to modify host by invocation argument, eg:<br>\n * <pre>\n * {@code\n *  Future<HttpClientRequest> create(Invocation invocation, HttpClient httpClient, HttpMethod method, RequestOptions options) {\n *    if (\"k8s\".equals(invocation.getMicroserviceName())) {\n *      options.setHost(invocation.getSwaggerArgument(\"clusterId\") + \".\" + options.getHost());\n *    }\n *\n *    return httpClient.request(options);\n *  }\n * }\n * </pre>\n */\npublic interface HttpClientRequestFactory {\n  HttpClientRequestFactory DEFAULT = (invocation, httpClient, options) -> httpClient.request(options);\n\n  Future<HttpClientRequest> create(Invocation invocation, HttpClient httpClient, RequestOptions options)\n      throws Throwable;\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.client;\n\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClientOptionsSPI;\n\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.HttpVersion;\nimport io.vertx.core.http.PoolOptions;\n\npublic class HttpTransportHttpClientOptionsSPI implements HttpClientOptionsSPI {\n  public static final String CLIENT_NAME = \"http-transport-client\";\n\n  public static final String CLIENT_TAG = \"rest.consumer\";\n\n  @Override\n  public String clientName() {\n    return CLIENT_NAME;\n  }\n\n  @Override\n  public int getOrder() {\n    return 100;\n  }\n\n  @Override\n  public boolean enabled() {\n    return TransportClientConfig.isHttpTransportClientEnabled();\n  }\n\n  @Override\n  public String getConfigTag() {\n    return CLIENT_TAG;\n  }\n\n  @Override\n  public int getEventLoopPoolSize() {\n    // not reading this, using shared transport vert.x\n    return -1;\n  }\n\n  @Override\n  public boolean useSharedVertx() {\n    return true;\n  }\n\n  @Override\n  public int getInstanceCount() {\n    return TransportClientConfig.getThreadCount();\n  }\n\n  @Override\n  public boolean isWorker() {\n    return false;\n  }\n\n  @Override\n  public String getWorkerPoolName() {\n    return \"pool-worker-transport-client-http\";\n  }\n\n  @Override\n  public int getWorkerPoolSize() {\n    return VertxOptions.DEFAULT_WORKER_POOL_SIZE;\n  }\n\n  @Override\n  public HttpVersion getHttpVersion() {\n    return HttpVersion.HTTP_1_1;\n  }\n\n  @Override\n  public int getConnectTimeoutInMillis() {\n    return TransportClientConfig.getConnectionTimeoutInMillis();\n  }\n\n  @Override\n  public int getIdleTimeoutInSeconds() {\n    return TransportClientConfig.getConnectionIdleTimeoutInSeconds();\n  }\n\n  @Override\n  public boolean isTryUseCompression() {\n    return TransportClientConfig.getConnectionCompression();\n  }\n\n  @Override\n  public int getMaxWaitQueueSize() {\n    return TransportClientConfig.getMaxWaitQueueSize();\n  }\n\n  @Override\n  public int getMaxPoolSize() {\n    return TransportClientConfig.getConnectionMaxPoolSize();\n  }\n\n  @Override\n  public boolean isKeepAlive() {\n    return TransportClientConfig.getConnectionKeepAlive();\n  }\n\n  @Override\n  public int getMaxHeaderSize() {\n    return TransportClientConfig.getMaxHeaderSize();\n  }\n\n  @Override\n  public int getKeepAliveTimeout() {\n    return TransportClientConfig.getConnectionKeepAliveTimeoutInSeconds();\n  }\n\n  @Override\n  public boolean enableLogActivity() {\n    return TransportClientConfig.enableLogActivity();\n  }\n\n  @Override\n  public int getHttp2MultiplexingLimit() {\n    return HttpClientOptions.DEFAULT_HTTP2_MULTIPLEXING_LIMIT;\n  }\n\n  @Override\n  public int getHttp2MaxPoolSize() {\n    return PoolOptions.DEFAULT_HTTP2_MAX_POOL_SIZE;\n  }\n\n  @Override\n  public boolean isUseAlpn() {\n    return !HttpClientOptions.DEFAULT_ALPN_VERSIONS.isEmpty();\n  }\n\n  @Override\n  public boolean isProxyEnable() {\n    // now transport proxy not implemented\n    return false;\n  }\n\n  @Override\n  public String getProxyHost() {\n    return null;\n  }\n\n  @Override\n  public int getProxyPort() {\n    return 0;\n  }\n\n  @Override\n  public String getProxyUsername() {\n    return null;\n  }\n\n  @Override\n  public String getProxyPassword() {\n    return null;\n  }\n\n  @Override\n  public boolean isSsl() {\n    return true;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientCodecFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.Map;\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.CompletionStage;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.vertx.core.http.HttpClientRequest;\n\npublic class RestClientCodecFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  public static final String NAME = \"rest-client-codec\";\n\n  protected RestClientTransportContextFactory transportContextFactory;\n\n  protected RestClientEncoder encoder;\n\n  protected RestClientDecoder decoder;\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.RESTFUL.equals(transport);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1990;\n  }\n\n  @Autowired\n  public RestClientCodecFilter setTransportContextFactory(RestClientTransportContextFactory transportContextFactory) {\n    this.transportContextFactory = transportContextFactory;\n    return this;\n  }\n\n  @Autowired\n  public RestClientCodecFilter setEncoder(RestClientEncoder encoder) {\n    this.encoder = encoder;\n    return this;\n  }\n\n  @Autowired\n  public RestClientCodecFilter setDecoder(RestClientDecoder decoder) {\n    this.decoder = decoder;\n    return this;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    invocation.getInvocationStageTrace().startConsumerConnection();\n    CompletionStage<HttpClientRequest> createRequest =\n        transportContextFactory.createHttpClientRequest(invocation).toCompletionStage()\n            .whenComplete((c, e) -> invocation.getInvocationStageTrace().finishConsumerConnection());\n    return CompletableFuture.completedFuture(null)\n        .thenCompose(v -> createRequest)\n        .thenAccept(httpClientRequest -> prepareTransportContext(invocation, httpClientRequest))\n        .thenAccept(v -> invocation.onStartSendRequest())\n        .thenAccept(v -> encoder.encode(invocation))\n        .thenCompose(v -> nextNode.onFilter(invocation))\n        .thenApply(response -> decoder.decode(invocation, response));\n  }\n\n  protected void prepareTransportContext(Invocation invocation, HttpClientRequest httpClientRequest) {\n    copyExtraHttpHeaders(invocation, httpClientRequest);\n\n    RestClientTransportContext transportContext = transportContextFactory.create(invocation, httpClientRequest);\n    invocation.setTransportContext(transportContext);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  protected void copyExtraHttpHeaders(Invocation invocation, HttpClientRequest httpClientRequest) {\n    Map<String, String> httpHeaders = (Map<String, String>) invocation.getHandlerContext()\n        .get(RestConst.CONSUMER_HEADER);\n    if (httpHeaders == null) {\n      return;\n    }\n    httpHeaders.forEach((key, value) -> {\n      if (\"Content-Length\".equalsIgnoreCase(key)) {\n        return;\n      }\n      if (null != value) {\n        httpClientRequest.putHeader(key, value);\n      }\n    });\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientDecoder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport static org.apache.servicecomb.transport.rest.client.RestClientExceptionCodes.FAILED_TO_DECODE_REST_FAIL_RESPONSE;\nimport static org.apache.servicecomb.transport.rest.client.RestClientExceptionCodes.FAILED_TO_DECODE_REST_SUCCESS_RESPONSE;\n\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;\nimport org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.exception.Exceptions;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.databind.JavaType;\n\nimport io.reactivex.rxjava3.core.Flowable;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\nimport jakarta.ws.rs.core.HttpHeaders;\n\npublic class RestClientDecoder {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestClientDecoder.class);\n\n  public Response decode(Invocation invocation, Response response) {\n    invocation.getInvocationStageTrace().startConsumerDecodeResponse();\n    if (response.getResult() instanceof Buffer) {\n      Object result = extractBody(invocation, response, response.getResult());\n      response.setResult(result);\n\n      if (response.isFailed()) {\n        throw Exceptions.create(response.getStatus(), response.getResult());\n      }\n    }\n\n    if (response.getResult() instanceof Flowable<?>) {\n      Flowable<Buffer> flowable = response.getResult();\n      Flowable<Object> encoded = flowable.map(buffer -> extractBody(invocation, response, buffer));\n      response.setResult(encoded);\n    }\n\n    invocation.getInvocationStageTrace().finishConsumerDecodeResponse();\n    return response;\n  }\n\n  protected Object extractBody(Invocation invocation, Response response, Buffer buffer) {\n    ProduceProcessor produceProcessor = safeFindProduceProcessor(invocation, response);\n    JavaType responseType = invocation.findResponseType(response.getStatusCode());\n\n    try {\n      return produceProcessor.decodeResponse(buffer, responseType);\n    } catch (Exception e) {\n      throw createDecodeException(invocation, response, e);\n    }\n  }\n\n  private ProduceProcessor safeFindProduceProcessor(Invocation invocation, Response response) {\n    String contentType = extractContentType(response);\n    ProduceProcessor produceProcessor =\n        ProduceProcessorManager.INSTANCE.createProduceProcessor(invocation.getOperationMeta(), response.getStatusCode(),\n            contentType, null);\n    if (produceProcessor != null) {\n      return produceProcessor;\n    }\n\n    RestClientTransportContext transportContext = invocation.getTransportContext();\n    HttpClientRequest httpClientRequest = transportContext.getHttpClientRequest();\n    LOGGER.warn(\n        \"operation={}, method={}, endpoint={}, uri={}, statusCode={}, reasonPhrase={}, response content-type={} is not supported in operation.\",\n        invocation.getMicroserviceQualifiedName(),\n        httpClientRequest.getMethod(),\n        invocation.getEndpoint().getEndpoint(),\n        httpClientRequest.getURI(),\n        response.getStatusCode(),\n        response.getReasonPhrase(),\n        response.getHeader(HttpHeaders.CONTENT_TYPE));\n\n    // This happens outside the runtime such as Servlet filter response. Here we give a default json parser to it\n    // and keep user data not get lost.\n    return ProduceProcessorManager.INSTANCE.findDefaultProcessor();\n  }\n\n  protected String extractContentType(Response response) {\n    String contentType = response.getHeader(HttpHeaders.CONTENT_TYPE);\n    if (contentType == null) {\n      return null;\n    }\n\n    int idx = contentType.indexOf(\";\");\n    return idx == -1 ? contentType : contentType.substring(0, idx);\n  }\n\n  protected InvocationException createDecodeException(Invocation invocation, Response response, Exception e) {\n    RestClientTransportContext transportContext = invocation.getTransportContext();\n    HttpClientRequest httpClientRequest = transportContext.getHttpClientRequest();\n\n    LOGGER.warn(\"failed to decode response body, \"\n            + \"operation={}, method={}, endpoint={}, uri={}, \"\n            + \"statusCode={}, reasonPhrase={}, content-type={}.\",\n        invocation.getMicroserviceQualifiedName(),\n        httpClientRequest.getMethod(),\n        invocation.getEndpoint().getEndpoint(),\n        httpClientRequest.getURI(),\n        response.getStatusCode(),\n        response.getReasonPhrase(),\n        response.getHeader(HttpHeaders.CONTENT_TYPE));\n\n    if (response.isSucceed()) {\n      return Exceptions.consumer(FAILED_TO_DECODE_REST_SUCCESS_RESPONSE, \"failed to decode success response body.\", e);\n    }\n    return Exceptions.consumer(FAILED_TO_DECODE_REST_FAIL_RESPONSE, \"failed to decode fail response body.\", e);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientEncoder.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport static jakarta.ws.rs.core.HttpHeaders.CONTENT_TYPE;\nimport static jakarta.ws.rs.core.MediaType.MULTIPART_FORM_DATA;\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\nimport static org.apache.servicecomb.transport.rest.client.RestClientExceptionCodes.FAILED_TO_ENCODE_REST_CLIENT_REQUEST;\n\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nimport org.apache.servicecomb.common.rest.codec.RestCodec;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.common.rest.codec.query.QueryCodec;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.OperationConfig;\nimport org.apache.servicecomb.foundation.common.utils.StringBuilderUtils;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.util.CollectionUtils;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\n\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\nimport jakarta.servlet.http.Part;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.MediaType;\n\n/**\n * encode all send data except upload\n */\npublic class RestClientEncoder {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestClientEncoder.class);\n\n  public static final int FORM_BUFFER_SIZE = 1024;\n\n  public void encode(Invocation invocation) {\n    try {\n      invocation.getInvocationStageTrace().startConsumerEncodeRequest();\n      EncoderSession encoderSession = new EncoderSession(invocation);\n      encoderSession.doEncode();\n      invocation.getInvocationStageTrace().finishConsumerEncodeRequest();\n    } catch (Exception e) {\n      throw new InvocationException(BAD_REQUEST, FAILED_TO_ENCODE_REST_CLIENT_REQUEST, e.getMessage(), e);\n    }\n  }\n\n  public static class EncoderSession {\n    protected final Invocation invocation;\n\n    protected final RestClientTransportContext transportContext;\n\n    protected final RestClientRequestParameters requestParameters;\n\n    protected final HttpClientRequest httpClientRequest;\n\n    public EncoderSession(Invocation invocation) {\n      this.invocation = invocation;\n      this.transportContext = invocation.getTransportContext();\n      this.requestParameters = this.transportContext.getRequestParameters();\n      this.httpClientRequest = this.transportContext.getHttpClientRequest();\n    }\n\n    protected void doEncode() throws Exception {\n      RestClientEncoder.LOGGER.debug(\"encode rest client request, operation={}, method={}, endpoint={}, uri={}.\",\n          invocation.getMicroserviceQualifiedName(),\n          httpClientRequest.getMethod(),\n          invocation.getEndpoint().getEndpoint(),\n          httpClientRequest.getURI());\n\n      swaggerArgumentsToRequest();\n\n      writeCookies(requestParameters.getCookieMap());\n      writeScbHeaders();\n      writeForm(requestParameters.getFormMap());\n    }\n\n    protected void swaggerArgumentsToRequest() throws Exception {\n      RestCodec.argsToRest(invocation.getSwaggerArguments(),\n          transportContext.getRestOperationMeta(), requestParameters);\n    }\n\n    protected void writeCookies(Map<String, String> cookieMap) {\n      if (CollectionUtils.isEmpty(cookieMap)) {\n        return;\n      }\n\n      StringBuilder builder = new StringBuilder();\n      for (Entry<String, String> entry : cookieMap.entrySet()) {\n        builder.append(entry.getKey())\n            .append('=')\n            .append(entry.getValue())\n            .append(\"; \");\n      }\n      StringBuilderUtils.deleteLast(builder, 2);\n      httpClientRequest.putHeader(HttpHeaders.COOKIE, builder.toString());\n    }\n\n    protected void writeScbHeaders() throws JsonProcessingException {\n      OperationConfig operationConfig = invocation.getOperationMeta().getConfig();\n      if (operationConfig.isClientRequestHeaderFilterEnabled()) {\n        return;\n      }\n\n      httpClientRequest.putHeader(CoreConst.TARGET_MICROSERVICE, invocation.getMicroserviceName());\n      httpClientRequest.putHeader(CoreConst.CSE_CONTEXT,\n          RestObjectMapperFactory.getRestObjectMapper().writeValueAsString(invocation.getContext()));\n    }\n\n    protected void writeForm(Map<String, Object> formMap) throws Exception {\n      if (requestParameters.getUploads() == null) {\n        writeUrlEncodedForm(formMap);\n        return;\n      }\n\n      writeChunkedForm(formMap);\n    }\n\n    protected void writeUrlEncodedForm(Map<String, Object> formMap) throws Exception {\n      if (formMap == null) {\n        return;\n      }\n\n      httpClientRequest.putHeader(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED);\n\n      Buffer bodyBuffer = genUrlEncodedFormBuffer(formMap);\n      requestParameters.setBodyBuffer(bodyBuffer);\n    }\n\n    protected Buffer genUrlEncodedFormBuffer(Map<String, Object> formMap) throws Exception {\n      Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE);\n      for (Entry<String, Object> entry : formMap.entrySet()) {\n        writeCharSequence(buffer, entry.getKey());\n        buffer.appendByte(((byte) '='));\n\n        String value = QueryCodec.convertToString(entry.getValue());\n        String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8);\n        writeCharSequence(buffer, encodedValue);\n\n        buffer.appendByte(((byte) '&'));\n      }\n\n      return buffer;\n    }\n\n    protected void writeChunkedForm(Map<String, Object> formMap) throws Exception {\n      String boundary = transportContext.getOrCreateBoundary();\n\n      httpClientRequest.setChunked(true);\n      httpClientRequest.putHeader(CONTENT_TYPE, MULTIPART_FORM_DATA + \"; charset=UTF-8; boundary=\" + boundary);\n\n      if (formMap == null) {\n        return;\n      }\n\n      Buffer bodyBuffer = genChunkedFormBuffer(formMap, boundary);\n      requestParameters.setBodyBuffer(bodyBuffer);\n    }\n\n    protected Buffer genChunkedFormBuffer(Map<String, Object> formMap, String boundary) throws Exception {\n      Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE);\n      for (Entry<String, Object> entry : formMap.entrySet()) {\n        Object content = entry.getValue();\n        if (content instanceof List<?>) {\n          for (Object item : ((List<?>) content)) {\n            writeFormData(buffer, boundary, entry.getKey(), item);\n          }\n        } else {\n          writeFormData(buffer, boundary, entry.getKey(), entry.getValue());\n        }\n      }\n      return buffer;\n    }\n\n    private void writeFormData(Buffer buffer, String boundary, String key, Object data) throws Exception {\n      writeCharSequence(buffer, \"\\r\\n--\");\n      writeCharSequence(buffer, boundary);\n      writeCharSequence(buffer, \"\\r\\nContent-Disposition: form-data; name=\\\"\");\n      writeCharSequence(buffer, key);\n      writeCharSequence(buffer, \"\\\"\\r\\n\\r\\n\");\n\n      String value = QueryCodec.convertToString(data);\n      writeCharSequence(buffer, value);\n    }\n  }\n\n  protected static void writeCharSequence(Buffer buffer, String value) {\n    buffer.appendString(value, \"UTF-8\");\n  }\n\n  public static Buffer genFileBoundaryBuffer(Part part, String name, String boundary) {\n    Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE);\n\n    writeCharSequence(buffer, \"\\r\\n--\");\n    writeCharSequence(buffer, boundary);\n    writeCharSequence(buffer, \"\\r\\nContent-Disposition: form-data; name=\\\"\");\n    writeCharSequence(buffer, name);\n    writeCharSequence(buffer, \"\\\"; filename=\\\"\");\n    writeCharSequence(buffer, String.valueOf(part.getSubmittedFileName()));\n    writeCharSequence(buffer, \"\\\"\\r\\n\");\n\n    writeCharSequence(buffer, \"Content-Type: \");\n    writeCharSequence(buffer, part.getContentType());\n    writeCharSequence(buffer, \"\\r\\n\");\n\n    writeCharSequence(buffer, \"Content-Transfer-Encoding: binary\\r\\n\");\n\n    writeCharSequence(buffer, \"\\r\\n\");\n\n    return buffer;\n  }\n\n  public static Buffer genBoundaryEndBuffer(String boundary) {\n    Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE);\n\n    writeCharSequence(buffer, \"\\r\\n--\");\n    writeCharSequence(buffer, boundary);\n    writeCharSequence(buffer, \"--\\r\\n\");\n\n    return buffer;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientExceptionCodes.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\npublic interface RestClientExceptionCodes {\n  String FAILED_TO_CREATE_REST_CLIENT_TRANSPORT_CONTEXT = \"scb_rest_client.40000000\";\n\n  String FAILED_TO_ENCODE_REST_CLIENT_REQUEST = \"scb_rest_client.40000001\";\n\n  String FAILED_TO_DECODE_REST_SUCCESS_RESPONSE = \"scb_rest_client.40000002\";\n\n  String FAILED_TO_DECODE_REST_FAIL_RESPONSE = \"scb_rest_client.40000003\";\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientRequestParameters.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.Map;\n\nimport jakarta.servlet.http.Part;\n\nimport org.apache.servicecomb.common.rest.codec.RestClientRequest;\n\nimport com.google.common.collect.Multimap;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.buffer.Buffer;\n\npublic interface RestClientRequestParameters extends RestClientRequest {\n  Map<String, String> getCookieMap();\n\n  Map<String, Object> getFormMap();\n\n  Multimap<String, Part> getUploads();\n\n  @Override\n  Buffer getBodyBuffer();\n\n  void setBodyBuffer(Buffer bodyBuffer);\n\n  @Override\n  default void write(Buffer bodyBuffer) {\n    setBodyBuffer(bodyBuffer);\n  }\n\n  @Override\n  default Future<Void> end() {\n    throw new UnsupportedOperationException(\"should not invoke this method\");\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientRequestParametersImpl.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.utils.PartUtils;\n\nimport com.google.common.collect.ArrayListMultimap;\nimport com.google.common.collect.Multimap;\n\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\nimport jakarta.servlet.http.Part;\n\npublic class RestClientRequestParametersImpl implements RestClientRequestParameters {\n  protected final HttpClientRequest httpClientRequest;\n\n  protected final MultiMap headers;\n\n  protected Map<String, String> cookieMap;\n\n  protected Map<String, Object> formMap;\n\n  protected Multimap<String, Part> uploads;\n\n  protected Buffer bodyBuffer;\n\n  public RestClientRequestParametersImpl(HttpClientRequest httpClientRequest) {\n    this.httpClientRequest = httpClientRequest;\n    this.headers = this.httpClientRequest.headers();\n  }\n\n  @Override\n  public Map<String, String> getCookieMap() {\n    return cookieMap;\n  }\n\n  @Override\n  public void addCookie(String name, String value) {\n    if (cookieMap == null) {\n      cookieMap = new HashMap<>();\n    }\n\n    cookieMap.put(name, value);\n  }\n\n  @Override\n  public Map<String, Object> getFormMap() {\n    return formMap;\n  }\n\n  @Override\n  public void addForm(String name, Object value) {\n    if (formMap == null) {\n      formMap = new HashMap<>();\n    }\n\n    if (value != null) {\n      formMap.put(name, value);\n    }\n  }\n\n  @Override\n  public MultiMap getHeaders() {\n    return headers;\n  }\n\n  @Override\n  public void putHeader(String name, String value) {\n    headers.add(name, value);\n  }\n\n  @Override\n  public Buffer getBodyBuffer() {\n    return bodyBuffer;\n  }\n\n  @Override\n  public void setBodyBuffer(Buffer bodyBuffer) {\n    this.bodyBuffer = bodyBuffer;\n  }\n\n  @Override\n  public Multimap<String, Part> getUploads() {\n    return uploads;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public void attach(String name, Object partOrList) {\n    if (uploads == null) {\n      uploads = ArrayListMultimap.create();\n    }\n\n    if (partOrList == null) {\n      return;\n    }\n\n    if (partOrList.getClass().isArray()) {\n      for (Object part : (Object[]) partOrList) {\n        uploads.put(name, PartUtils.getSinglePart(name, part));\n      }\n      return;\n    }\n\n    if (partOrList instanceof Collection) {\n      for (Object part : ((Collection<Object>) partOrList)) {\n        uploads.put(name, PartUtils.getSinglePart(name, part));\n      }\n      return;\n    }\n\n    uploads.put(name, PartUtils.getSinglePart(name, partOrList));\n  }\n\n  @Override\n  public HttpClientRequest getHttpClientRequest() {\n    return this.httpClientRequest;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSender.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport static org.apache.servicecomb.transport.rest.client.RestClientEncoder.genBoundaryEndBuffer;\nimport static org.apache.servicecomb.transport.rest.client.RestClientEncoder.genFileBoundaryBuffer;\n\nimport java.util.Map.Entry;\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.http.HttpStatus;\nimport org.apache.servicecomb.foundation.vertx.executor.VertxContextExecutor;\nimport org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;\nimport org.apache.servicecomb.foundation.vertx.stream.PumpFromPart;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.collect.Multimap;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.Promise;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpClientResponse;\nimport io.vertx.rxjava3.FlowableHelper;\nimport jakarta.servlet.http.Part;\n\npublic class RestClientSender {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestClientSender.class);\n\n  protected final Invocation invocation;\n\n  protected final RestClientTransportContext transportContext;\n\n  protected final RestClientRequestParameters requestParameters;\n\n  protected final HttpClientRequest httpClientRequest;\n\n  protected final CompletableFuture<Response> future = new CompletableFuture<>();\n\n  public RestClientSender(Invocation invocation) {\n    this.invocation = invocation;\n    this.transportContext = invocation.getTransportContext();\n    this.requestParameters = transportContext.getRequestParameters();\n    this.httpClientRequest = transportContext.getHttpClientRequest();\n  }\n\n  public CompletableFuture<Response> send() {\n    invocation.getInvocationStageTrace().startConsumerSendRequest();\n    httpClientRequest.response().compose(this::processResponse).onFailure(future::completeExceptionally);\n\n    CompletableFuture<Response> actualFuture = future.whenComplete(this::afterSend);\n    VertxContextExecutor.create(transportContext.getVertxContext()).execute(this::runInVertxContext);\n    return actualFuture;\n  }\n\n  protected void runInVertxContext() {\n    sendInVertxContext()\n        .whenComplete((v, e) -> {\n          if (e != null) {\n            future.completeExceptionally(e);\n          }\n          invocation.getInvocationStageTrace().finishConsumerSendRequest();\n          invocation.getInvocationStageTrace().startWaitResponse();\n        });\n  }\n\n  protected CompletableFuture<Void> sendInVertxContext() {\n    httpClientRequest.idleTimeout(invocation.getOperationMeta().getConfig().getMsRequestTimeout());\n\n    Multimap<String, Part> uploads = requestParameters.getUploads();\n    if (uploads == null) {\n      if (requestParameters.getBodyBuffer() != null) {\n        return CompletableFuture.completedFuture(null).thenCompose(\n            v -> httpClientRequest.end(requestParameters.getBodyBuffer()).toCompletionStage());\n      } else {\n        return CompletableFuture.completedFuture(null).thenCompose(\n            v -> httpClientRequest.end().toCompletionStage());\n      }\n    }\n\n    if (requestParameters.getBodyBuffer() != null) {\n      httpClientRequest.write(requestParameters.getBodyBuffer());\n    }\n    return sendFiles();\n  }\n\n  protected CompletableFuture<Void> sendFiles() {\n    CompletableFuture<Void> sendFileFuture = CompletableFuture.completedFuture(null);\n\n    String boundary = transportContext.getOrCreateBoundary();\n    for (Entry<String, Part> entry : requestParameters.getUploads().entries()) {\n      // do not use part.getName() to get parameter name\n      // because pojo consumer not easy to set name to part\n      String name = entry.getKey();\n      sendFileFuture = sendFileFuture.thenCompose(v -> sendFile(entry.getValue(), name, boundary));\n    }\n\n    return sendFileFuture.thenCompose(v -> httpClientRequest.end(genBoundaryEndBuffer(boundary)).toCompletionStage());\n  }\n\n  private CompletableFuture<Void> sendFile(Part part, String name, String boundary) {\n    Buffer fileHeader = genFileBoundaryBuffer(part, name, boundary);\n    httpClientRequest.write(fileHeader);\n\n    return new PumpFromPart(transportContext.getVertxContext(), part)\n        .toWriteStream(httpClientRequest, future::completeExceptionally)\n        .whenComplete((v, e) -> {\n          if (e != null) {\n            LOGGER.debug(\"Failed to send file [{}:{}].\", name, part.getSubmittedFileName(), e);\n            return;\n          }\n\n          LOGGER.debug(\"finish send file [{}:{}].\", name, part.getSubmittedFileName());\n        });\n  }\n\n  protected Future<Object> processResponse(HttpClientResponse httpClientResponse) {\n    Promise<Object> result = Promise.promise();\n    transportContext.setHttpClientResponse(httpClientResponse);\n\n    if (!HttpStatus.isSuccess(httpClientResponse.statusCode())) {\n      httpClientResponse.body().compose(buffer -> {\n        future.complete(createResponse(httpClientResponse, buffer));\n        result.complete();\n        return Future.succeededFuture();\n      });\n      return result.future();\n    }\n\n    if (transportContext.isDownloadFile()) {\n      ReadStreamPart streamPart = new ReadStreamPart(transportContext.getVertxContext(), httpClientResponse);\n      future.complete(createResponse(httpClientResponse, streamPart));\n      result.complete();\n      return result.future();\n    }\n\n    if (transportContext.isServerSendEvents()) {\n      future.complete(createResponse(httpClientResponse, FlowableHelper.toFlowable(httpClientResponse)));\n      result.complete();\n      return result.future();\n    }\n\n    httpClientResponse.body().compose(buffer -> {\n      future.complete(createResponse(httpClientResponse, buffer));\n      result.complete();\n      return Future.succeededFuture();\n    });\n    return result.future();\n  }\n\n  protected Response createResponse(HttpClientResponse httpClientResponse, Object result) {\n    // http2's :status header will cause edge forward failed\n    MultiMap headers = httpClientResponse.headers();\n    headers.remove(\":status\");\n\n    HttpStatus httpStatus = new HttpStatus(httpClientResponse.statusCode(), httpClientResponse.statusMessage());\n    return Response\n        .status(httpStatus)\n        .setHeaders(headers)\n        .entity(result);\n  }\n\n  protected void afterSend(Response response, Throwable throwable) {\n    invocation.getInvocationStageTrace().finishWaitResponse();\n\n    if (throwable != null) {\n      LOGGER.error(\"rest client send or receive failed, operation={}, method={}, endpoint={}, uri={}.\",\n          invocation.getMicroserviceQualifiedName(),\n          httpClientRequest.getMethod(),\n          invocation.getEndpoint().getEndpoint(),\n          httpClientRequest.getURI());\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSenderFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.swagger.invocation.Response;\n\npublic class RestClientSenderFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  public static final String NAME = \"rest-client-sender\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.RESTFUL.equals(transport);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 2000;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    CompletableFuture<Response> future = new RestClientSender(invocation)\n        .send();\n\n    return invocation.optimizeSyncConsumerThread(future);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.Optional;\n\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.swagger.invocation.context.VertxTransportContext;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpClientResponse;\nimport io.vertx.core.http.HttpConnection;\n\npublic class RestClientTransportContext implements VertxTransportContext {\n  protected final RestOperationMeta restOperationMeta;\n\n  protected final Context vertxContext;\n\n  protected final HttpClientRequest httpClientRequest;\n\n  protected final RestClientRequestParameters requestParameters;\n\n  protected final BoundaryFactory boundaryFactory;\n\n  protected String boundary;\n\n  protected HttpClientResponse httpClientResponse;\n\n  public RestClientTransportContext(RestOperationMeta restOperationMeta, Context vertxContext,\n      HttpClientRequest httpClientRequest, BoundaryFactory boundaryFactory) {\n    this.restOperationMeta = restOperationMeta;\n    this.vertxContext = vertxContext;\n    this.httpClientRequest = httpClientRequest;\n    this.boundaryFactory = boundaryFactory;\n    this.requestParameters = new RestClientRequestParametersImpl(httpClientRequest);\n  }\n\n  public RestOperationMeta getRestOperationMeta() {\n    return restOperationMeta;\n  }\n\n  public boolean isDownloadFile() {\n    return restOperationMeta.isDownloadFile();\n  }\n\n  public boolean isServerSendEvents() {\n    return restOperationMeta.isServerSendEvents();\n  }\n\n  @Override\n  public Context getVertxContext() {\n    return vertxContext;\n  }\n\n  public HttpClientRequest getHttpClientRequest() {\n    return httpClientRequest;\n  }\n\n  public RestClientRequestParameters getRequestParameters() {\n    return requestParameters;\n  }\n\n  public String getOrCreateBoundary() {\n    if (boundary == null) {\n      boundary = boundaryFactory.create();\n    }\n\n    return boundary;\n  }\n\n  public HttpClientResponse getHttpClientResponse() {\n    return httpClientResponse;\n  }\n\n  public RestClientTransportContext setHttpClientResponse(HttpClientResponse httpClientResponse) {\n    this.httpClientResponse = httpClientResponse;\n    return this;\n  }\n\n  public String getLocalAddress() {\n    return Optional.ofNullable(httpClientRequest.connection())\n        .map(HttpConnection::localAddress)\n        .map(Object::toString)\n        .orElse(\"not connected\");\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientTransportContextFactory.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;\nimport static org.apache.servicecomb.transport.rest.client.RestClientExceptionCodes.FAILED_TO_CREATE_REST_CLIENT_TRANSPORT_CONTEXT;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.definition.RestMetaUtils;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.springframework.beans.factory.annotation.Autowired;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.http.HttpClientRequest;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.RequestOptions;\n\npublic class RestClientTransportContextFactory {\n  private BoundaryFactory boundaryFactory = BoundaryFactory.DEFAULT;\n\n  private HttpClientRequestFactory httpClientRequestFactory = HttpClientRequestFactory.DEFAULT;\n\n  @Autowired(required = false)\n  public RestClientTransportContextFactory setBoundaryFactory(BoundaryFactory boundaryFactory) {\n    this.boundaryFactory = boundaryFactory;\n    return this;\n  }\n\n  @Autowired(required = false)\n  public RestClientTransportContextFactory setHttpClientRequestFactory(HttpClientRequestFactory factory) {\n    this.httpClientRequestFactory = factory;\n    return this;\n  }\n\n  public RestClientTransportContext create(Invocation invocation, HttpClientRequest httpClientRequest) {\n    try {\n      return doCreate(invocation, httpClientRequest);\n    } catch (Throwable e) {\n      throw new InvocationException(BAD_REQUEST, FAILED_TO_CREATE_REST_CLIENT_TRANSPORT_CONTEXT, e.getMessage(), e);\n    }\n  }\n\n  protected RestClientTransportContext doCreate(Invocation invocation, HttpClientRequest httpClientRequest)\n      throws Throwable {\n    RestOperationMeta restOperationMeta = RestMetaUtils.getRestOperationMeta(invocation.getOperationMeta());\n    HttpClientWithContext httpClientWithContext = findHttpClientPool(invocation);\n    RestClientTransportContext context = new RestClientTransportContext(restOperationMeta,\n        httpClientWithContext.context(),\n        httpClientRequest,\n        boundaryFactory);\n    invocation.getHandlerContext().put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT,\n        context.getRequestParameters());\n    return context;\n  }\n\n  protected HttpClientWithContext findHttpClientPool(Invocation invocation) {\n    URIEndpointObject endpoint = (URIEndpointObject) invocation.getEndpoint().getAddress();\n    if (endpoint.isHttp2Enabled()) {\n      return HttpClients.getClient(Http2TransportHttpClientOptionsSPI.CLIENT_NAME, invocation.isSync());\n    }\n\n    return HttpClients.getClient(HttpTransportHttpClientOptionsSPI.CLIENT_NAME, invocation.isSync());\n  }\n\n  protected Future<HttpClientRequest> createHttpClientRequest(Invocation invocation) {\n    try {\n      RestOperationMeta restOperationMeta = RestMetaUtils.getRestOperationMeta(invocation.getOperationMeta());\n      HttpClientWithContext httpClientWithContext = findHttpClientPool(invocation);\n\n      URIEndpointObject endpoint = (URIEndpointObject) invocation.getEndpoint().getAddress();\n      HttpMethod method = HttpMethod.valueOf(restOperationMeta.getHttpMethod());\n      RequestOptions requestOptions = new RequestOptions()\n          .setHost(endpoint.getHostOrIp())\n          .setPort(endpoint.getPort())\n          .setSsl(endpoint.isSslEnabled())\n          .setMethod(method)\n          .setURI(createRequestPath(invocation, restOperationMeta));\n      return httpClientRequestFactory.create(invocation, httpClientWithContext.getHttpClient(), requestOptions);\n    } catch (Throwable e) {\n      throw new InvocationException(BAD_REQUEST, FAILED_TO_CREATE_REST_CLIENT_TRANSPORT_CONTEXT, e.getMessage(), e);\n    }\n  }\n\n  protected String createRequestPath(Invocation invocation, RestOperationMeta restOperationMeta) throws Exception {\n    String path = invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH);\n    if (path == null) {\n      path = restOperationMeta.getPathBuilder().createRequestPath(invocation.getSwaggerArguments());\n    }\n\n    URIEndpointObject endpoint = (URIEndpointObject) invocation.getEndpoint().getAddress();\n    String urlPrefix = endpoint.getFirst(DefinitionConst.URL_PREFIX);\n    if (StringUtils.isEmpty(urlPrefix) || path.startsWith(urlPrefix)) {\n      return path;\n    }\n\n    return urlPrefix + path;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/TransportClientConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.client;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.transport.common.TransportConfigUtils;\n\nimport io.vertx.core.http.HttpClientOptions;\nimport io.vertx.core.http.PoolOptions;\n\npublic final class TransportClientConfig {\n  private static final int DEFAULT_IDLE_TIME_OUT = 150;\n\n  private static final int DEFAULT_KEEP_ALIVE_TIME_OUT = 60;\n\n  private TransportClientConfig() {\n  }\n\n  public static int getThreadCount() {\n    return TransportConfigUtils.readVerticleCount(\n        \"servicecomb.rest.client.verticle-count\",\n        \"servicecomb.rest.client.thread-count\");\n  }\n\n  public static int getHttp2ConnectionMaxPoolSize() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.client.http2.maxPoolSize\",\n        PoolOptions.DEFAULT_HTTP2_MAX_POOL_SIZE);\n  }\n\n  public static int getHttp2MultiplexingLimit() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.client.http2.multiplexingLimit\",\n        HttpClientOptions.DEFAULT_HTTP2_MULTIPLEXING_LIMIT);\n  }\n\n  public static boolean getUseAlpn() {\n    return LegacyPropertyFactory.getBooleanProperty(\"servicecomb.rest.client.http2.useAlpnEnabled\", true);\n  }\n\n  public static boolean isHttp2TransportClientEnabled() {\n    return LegacyPropertyFactory.getBooleanProperty(\"servicecomb.rest.client.http2.enabled\",\n        true);\n  }\n\n  public static int getConnectionMaxPoolSize() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.client.connection.maxPoolSize\",\n        PoolOptions.DEFAULT_MAX_POOL_SIZE);\n  }\n\n  public static int getHttp2ConnectionIdleTimeoutInSeconds() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.client.http2.connection.idleTimeoutInSeconds\",\n        DEFAULT_IDLE_TIME_OUT);\n  }\n\n  public static int getConnectionIdleTimeoutInSeconds() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.client.connection.idleTimeoutInSeconds\",\n        DEFAULT_IDLE_TIME_OUT);\n  }\n\n  public static boolean getConnectionKeepAlive() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.client.connection.keepAlive\", HttpClientOptions.DEFAULT_KEEP_ALIVE);\n  }\n\n  public static int getConnectionKeepAliveTimeoutInSeconds() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.client.connection.keepAliveTimeoutInSeconds\", DEFAULT_KEEP_ALIVE_TIME_OUT);\n  }\n\n  public static boolean enableLogActivity() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.client.enableLogActivity\", false);\n  }\n\n  public static int getHttp2ConnectionKeepAliveTimeoutInSeconds() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.client.http2.connection.keepAliveTimeoutInSeconds\",\n            DEFAULT_KEEP_ALIVE_TIME_OUT);\n  }\n\n  public static boolean getConnectionCompression() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.client.connection.compression\",\n            HttpClientOptions.DEFAULT_DECOMPRESSION_SUPPORTED);\n  }\n\n  public static int getMaxHeaderSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.client.maxHeaderSize\", HttpClientOptions.DEFAULT_MAX_HEADER_SIZE);\n  }\n\n  public static int getMaxWaitQueueSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.client.maxWaitQueueSize\",\n            PoolOptions.DEFAULT_MAX_WAIT_QUEUE_SIZE);\n  }\n\n  public static boolean isHttpTransportClientEnabled() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.client.enabled\",\n            true);\n  }\n\n  public static int getConnectionTimeoutInMillis() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.client.connection.timeoutInMillis\", 60000);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/TransportRestClientConfiguration.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class TransportRestClientConfiguration {\n  @Bean\n  public RestClientSenderFilter restClientSenderFilter() {\n    return new RestClientSenderFilter();\n  }\n\n  @Bean\n  public RestClientCodecFilter restClientCodecFilter() {\n    return new RestClientCodecFilter();\n  }\n\n  @Bean\n  public WebSocketClientCodecFilter webSocketClientCodecFilter() {\n    return new WebSocketClientCodecFilter();\n  }\n\n  @Bean\n  public RestClientDecoder restClientDecoder() {\n    return new RestClientDecoder();\n  }\n\n  @Bean\n  public RestClientTransportContextFactory restClientTransportContextFactory() {\n    return new RestClientTransportContextFactory();\n  }\n\n  @Bean\n  public RestClientEncoder restClientEncoder() {\n    return new RestClientEncoder();\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/WebSocketClientCodecFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.common.rest.WebSocketTransportContext;\nimport org.apache.servicecomb.common.rest.definition.RestMetaUtils;\nimport org.apache.servicecomb.common.rest.definition.RestOperationMeta;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.filter.AbstractFilter;\nimport org.apache.servicecomb.core.filter.ConsumerFilter;\nimport org.apache.servicecomb.core.filter.EdgeFilter;\nimport org.apache.servicecomb.core.filter.Filter;\nimport org.apache.servicecomb.core.filter.FilterNode;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClientOptionsSPI;\nimport org.apache.servicecomb.foundation.vertx.client.http.HttpClients;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.http.ServerWebSocket;\nimport io.vertx.core.http.WebSocket;\nimport io.vertx.core.http.WebSocketClient;\n\npublic class WebSocketClientCodecFilter extends AbstractFilter implements ConsumerFilter, EdgeFilter {\n  private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketClientCodecFilter.class);\n\n  public static final String NAME = \"websocket-client\";\n\n  @Override\n  public String getName() {\n    return NAME;\n  }\n\n  @Override\n  public boolean enabledForTransport(String transport) {\n    return CoreConst.WEBSOCKET.equals(transport);\n  }\n\n  @Override\n  public int getOrder() {\n    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 2000;\n  }\n\n  @Override\n  public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {\n    invocation.getInvocationStageTrace().startConsumerConnection();\n\n    CompletableFuture<Response> createWebSocket = new CompletableFuture<>();\n    URIEndpointObject endpoint = (URIEndpointObject) invocation.getEndpoint().getAddress();\n    HttpClientOptionsSPI optionsSPI;\n    if (endpoint.isHttp2Enabled()) {\n      optionsSPI = SPIServiceUtils.getTargetService(HttpClientOptionsSPI.class,\n          HttpTransportHttpClientOptionsSPI.class);\n    } else {\n      optionsSPI = SPIServiceUtils.getTargetService(HttpClientOptionsSPI.class,\n          Http2TransportHttpClientOptionsSPI.class);\n    }\n    WebSocketClient webSocketClient = HttpClients.createWebSocketClient(optionsSPI, endpoint.isSslEnabled());\n\n    try {\n      webSocketClient.connect(endpoint.getPort(), endpoint.getHostOrIp(), createRequestPath(invocation,\n              RestMetaUtils.getRestOperationMeta(invocation.getOperationMeta())))\n          .onComplete(asyncResult -> {\n            invocation.getInvocationStageTrace().finishConsumerConnection();\n            if (asyncResult.failed()) {\n              createWebSocket.completeExceptionally(asyncResult.cause());\n              return;\n            }\n            if (invocation.isEdge()) {\n              WebSocketTransportContext parentContext = invocation.getTransportContext();\n              ServerWebSocket serverWebSocket = parentContext.getServerWebSocket();\n              WebSocket clientWebSocket = asyncResult.result();\n              serverWebSocket.closeHandler(v -> {\n                if (!clientWebSocket.isClosed()) {\n                  clientWebSocket.close();\n                }\n              });\n              serverWebSocket.textMessageHandler(clientWebSocket::writeTextMessage);\n              serverWebSocket.binaryMessageHandler(clientWebSocket::writeBinaryMessage);\n              serverWebSocket.exceptionHandler(e -> {\n                LOGGER.warn(\"consumer exception.\", e);\n                if (!serverWebSocket.isClosed()) {\n                  serverWebSocket.close();\n                }\n              });\n              clientWebSocket.closeHandler(v -> {\n                if (!serverWebSocket.isClosed()) {\n                  serverWebSocket.close();\n                }\n              });\n              clientWebSocket.textMessageHandler(serverWebSocket::writeTextMessage);\n              clientWebSocket.binaryMessageHandler(serverWebSocket::writeBinaryMessage);\n              clientWebSocket.exceptionHandler(e -> {\n                LOGGER.warn(\"producer exception.\", e);\n                if (!clientWebSocket.isClosed()) {\n                  clientWebSocket.close();\n                }\n              });\n            }\n            invocation.setTransportContext(new WebSocketClientTransportContext(\n                asyncResult.result()));\n            createWebSocket.complete(Response.createSuccess(asyncResult.result()));\n          });\n    } catch (Exception e) {\n      createWebSocket.completeExceptionally(e);\n    }\n\n    return createWebSocket;\n  }\n\n  protected String createRequestPath(Invocation invocation, RestOperationMeta restOperationMeta) throws Exception {\n    String path = invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH);\n    if (path == null) {\n      path = restOperationMeta.getPathBuilder().createRequestPath(invocation.getSwaggerArguments());\n    }\n\n    URIEndpointObject endpoint = (URIEndpointObject) invocation.getEndpoint().getAddress();\n    String urlPrefix = endpoint.getFirst(DefinitionConst.URL_PREFIX);\n    if (StringUtils.isEmpty(urlPrefix) || path.startsWith(urlPrefix)) {\n      return path;\n    }\n\n    return urlPrefix + path;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/WebSocketClientTransportContext.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.client;\n\nimport org.apache.servicecomb.swagger.invocation.context.TransportContext;\n\nimport io.vertx.core.http.WebSocket;\n\npublic class WebSocketClientTransportContext implements TransportContext {\n\n  protected final WebSocket webSocketClient;\n\n  public WebSocketClientTransportContext(WebSocket webSocketClient) {\n    this.webSocketClient = webSocketClient;\n  }\n\n  public WebSocket getWebSocketClient() {\n    return webSocketClient;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/resources/META-INF/services/org.apache.servicecomb.foundation.vertx.client.http.HttpClientOptionsSPI",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.transport.rest.client.HttpTransportHttpClientOptionsSPI\norg.apache.servicecomb.transport.rest.client.Http2TransportHttpClientOptionsSPI\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports",
    "content": "## ---------------------------------------------------------------------------\n## Licensed to the Apache Software Foundation (ASF) under one or more\n## contributor license agreements.  See the NOTICE file distributed with\n## this work for additional information regarding copyright ownership.\n## The ASF licenses this file to You under the Apache License, Version 2.0\n## (the \"License\"); you may not use this file except in compliance with\n## the License.  You may obtain a copy of the License at\n##\n##      http://www.apache.org/licenses/LICENSE-2.0\n##\n## Unless required by applicable law or agreed to in writing, software\n## distributed under the License is distributed on an \"AS IS\" BASIS,\n## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n## See the License for the specific language governing permissions and\n## limitations under the License.\n## ---------------------------------------------------------------------------\n\norg.apache.servicecomb.transport.rest.client.TransportRestClientConfiguration\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/FakeRestTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\n\nclass FakeRestTransport extends AbstractTransport {\n  @Override\n  public String getName() {\n    return null;\n  }\n\n  @Override\n  public boolean init() {\n    return false;\n  }\n\n  @Override\n  public Object parseAddress(String address) {\n    return new URIEndpointObject(address);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/RestFeatureController.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.client;\n\nimport java.io.File;\nimport java.util.List;\n\nimport jakarta.ws.rs.CookieParam;\nimport jakarta.ws.rs.FormParam;\nimport jakarta.ws.rs.GET;\nimport jakarta.ws.rs.HeaderParam;\nimport jakarta.ws.rs.POST;\nimport jakarta.ws.rs.Path;\nimport jakarta.ws.rs.QueryParam;\n\n@Path(\"/\")\npublic class RestFeatureController {\n  public static final String SCHEMA_ID = \"rest-feature\";\n\n  @GET\n  @Path(\"/query\")\n  public String query(@QueryParam(\"query\") String query) {\n    return query;\n  }\n\n  @GET\n  @Path(\"/header\")\n  public String header(@HeaderParam(\"header\") String header) {\n    return header;\n  }\n\n  @GET\n  @Path(\"/cookie\")\n  public String cookie(@CookieParam(\"cookie1\") String cookie1, @CookieParam(\"cookie2\") String cookie2) {\n    return cookie1 + \":\" + cookie2;\n  }\n\n  @POST\n  @Path(\"/form\")\n  public String form(@FormParam(\"form1\") String form1, @FormParam(\"form2\") String form2) {\n    return form1 + \":\" + form2;\n  }\n\n  @POST\n  @Path(\"/formWithUpload\")\n  public String formWithUpload(@FormParam(\"form1\") String form1, @FormParam(\"form2\") File form2) {\n    return form1 + \":\" + form2.getName();\n  }\n\n  @POST\n  @Path(\"/formWithUploadList\")\n  public String formWithUploadList(@FormParam(\"files\") List<File> files) {\n    return files.toString();\n  }\n\n  @POST\n  @Path(\"/body\")\n  public String body(String body) {\n    return body;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-client/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n      http://www.apache.org/licenses/LICENSE-2.0\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<Configuration status=\"INFO\">\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout pattern=\"[%d][%t][%p][%c:%L] %m%n\" />\n        </Console>\n    </Appenders>\n    <Loggers>\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>transport-rest</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>transport-rest-servlet</artifactId>\n  <name>Java Chassis::Transports::Rest::Servlet</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>jakarta.servlet</groupId>\n      <artifactId>jakarta.servlet-api</artifactId>\n    </dependency>\n\n    <dependency>\n      <groupId>org.springframework</groupId>\n      <artifactId>spring-webmvc</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestAsyncListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\n\nimport jakarta.servlet.AsyncEvent;\nimport jakarta.servlet.AsyncListener;\nimport jakarta.servlet.ServletRequest;\nimport jakarta.servlet.ServletResponse;\nimport jakarta.servlet.http.HttpServletResponse;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.common.utils.JsonUtils;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\n\npublic class RestAsyncListener implements AsyncListener {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestAsyncListener.class);\n\n  private static String TIMEOUT_MESSAGE;\n\n  static {\n    try {\n      TIMEOUT_MESSAGE = JsonUtils.writeValueAsString(new CommonExceptionData(\"Timeout when processing the request.\"));\n    } catch (JsonProcessingException e) {\n      LOGGER.error(\"Failed to init timeout message.\", e);\n    }\n  }\n\n  @Override\n  public void onComplete(AsyncEvent event) throws IOException {\n  }\n\n  @Override\n  public void onTimeout(AsyncEvent event) throws IOException {\n    // in this time, maybe:\n    // 1.invocation in executor's queue\n    // 2.already executing in executor\n    // 3.already send response\n    // to avoid concurrent, must lock request\n    ServletRequest request = event.getSuppliedRequest();\n    HttpServletRequestEx requestEx = (HttpServletRequestEx) request.getAttribute(RestConst.REST_REQUEST);\n    LOGGER.error(\"Rest request timeout, method {}, path {}.\", requestEx.getMethod(), requestEx.getRequestURI());\n\n    // Waiting till executing in executor done. This operation may block container pool and make timeout requests in executor's\n    // queue getting executed, and will cause bad performance. So default timeout is setting to -1 to disable timeout.\n    synchronized (requestEx) {\n      ServletResponse response = event.getAsyncContext().getResponse();\n      if (!response.isCommitted()) {\n        // invocation in executor's queue\n        response.setContentType(MediaType.APPLICATION_JSON);\n\n        // we don't know if developers declared one statusCode in contract\n        // so we use cse inner statusCode here\n        ((HttpServletResponse) response).setStatus(Status.INTERNAL_SERVER_ERROR.getStatusCode());\n        PrintWriter out = response.getWriter();\n        out.write(TIMEOUT_MESSAGE);\n        response.flushBuffer();\n      }\n\n      request.removeAttribute(RestConst.REST_REQUEST);\n    }\n\n    LOGGER.error(\"Rest request timeout committed, method {}, path {}.\", requestEx.getMethod(), requestEx.getRequestURI());\n  }\n\n  @Override\n  public void onError(AsyncEvent event) throws IOException {\n    // 未使用\n  }\n\n  @Override\n  public void onStartAsync(AsyncEvent event) throws IOException {\n    // 未使用\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServlet.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.http.HttpServlet;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Rest Servlet Server, load by web container\n */\npublic class RestServlet extends HttpServlet {\n  private static final long serialVersionUID = 5797523329773923112L;\n\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestServlet.class);\n\n  private final ServletRestDispatcher servletRestServer = new ServletRestDispatcher();\n\n  @Override\n  public void init() throws ServletException {\n    super.init();\n\n    LOGGER.info(\"Rest Servlet inited\");\n  }\n\n  @Override\n  public void service(final HttpServletRequest request, final HttpServletResponse response) {\n    servletRestServer.service(request, response);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServletInjector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.util.Arrays;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletRegistration.Dynamic;\n\npublic class RestServletInjector {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestServletInjector.class);\n\n  public static final String SERVLET_NAME = \"ServicecombRestServlet\";\n\n  public static Dynamic defaultInject(ServletContext servletContext, Environment environment) {\n    RestServletInjector injector = new RestServletInjector();\n\n    String urlPattern = ServletConfig.getServletUrlPattern(environment);\n    return injector.inject(servletContext, urlPattern, environment);\n  }\n\n  public Dynamic inject(ServletContext servletContext, String urlPattern, Environment environment) {\n    String[] urlPatterns = splitUrlPattern(urlPattern);\n    if (urlPatterns.length == 0) {\n      LOGGER.warn(\"urlPattern is empty, ignore register {}.\", SERVLET_NAME);\n      return null;\n    }\n\n    String listenAddress = ServletConfig.getLocalServerAddress(environment);\n    if (!ServletUtils.canPublishEndpoint(listenAddress)) {\n      LOGGER.warn(\"ignore register {}.\", SERVLET_NAME);\n      return null;\n    }\n\n    // dynamic deploy a servlet to handle serviceComb RESTful request\n    Dynamic dynamic = servletContext.addServlet(SERVLET_NAME, RestServlet.class);\n    dynamic.setAsyncSupported(true);\n    dynamic.addMapping(urlPatterns);\n    dynamic.setLoadOnStartup(0);\n    LOGGER.info(\"RESTful servlet url pattern: {}.\", Arrays.toString(urlPatterns));\n\n    return dynamic;\n  }\n\n  private String[] splitUrlPattern(String urlPattern) {\n    if (StringUtils.isEmpty(urlPattern)) {\n      return new String[] {};\n    }\n\n    return ServletUtils.filterUrlPatterns(urlPattern);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServletProducerInvocationCreator.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport org.apache.servicecomb.common.rest.HttpTransportContext;\nimport org.apache.servicecomb.common.rest.RestProducerInvocationCreator;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\n\npublic class RestServletProducerInvocationCreator extends RestProducerInvocationCreator {\n  public RestServletProducerInvocationCreator(MicroserviceMeta microserviceMeta, Endpoint endpoint,\n      HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {\n    super(microserviceMeta, endpoint, requestEx, responseEx);\n  }\n\n  @Override\n  protected void initTransportContext(Invocation invocation) {\n    HttpTransportContext transportContext = new HttpTransportContext(requestEx, responseEx);\n    invocation.setTransportContext(transportContext);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/ServletConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport org.springframework.core.env.Environment;\n\npublic final class ServletConfig {\n  public static final long DEFAULT_ASYN_SERVLET_TIMEOUT = -1;\n\n  public static final String KEY_SERVLET_URL_PATTERN = \"servicecomb.rest.servlet.urlPattern\";\n\n  public static final String SERVICECOMB_REST_ADDRESS = \"servicecomb.rest.address\";\n\n  public static final String KEY_SERVICECOMB_ASYC_SERVLET_TIMEOUT = \"servicecomb.rest.server.timeout\";\n\n  public static final String DEFAULT_URL_PATTERN = \"/*\";\n\n  private ServletConfig() {\n  }\n\n  public static long getAsyncServletTimeout(Environment environment) {\n    return environment.getProperty(KEY_SERVICECOMB_ASYC_SERVLET_TIMEOUT, long.class,\n        DEFAULT_ASYN_SERVLET_TIMEOUT);\n  }\n\n  public static String getLocalServerAddress(Environment environment) {\n    return environment.getProperty(SERVICECOMB_REST_ADDRESS);\n  }\n\n  public static String getServletUrlPattern(Environment environment) {\n    return environment.getProperty(KEY_SERVLET_URL_PATTERN, DEFAULT_URL_PATTERN);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/ServletRestDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport org.apache.servicecomb.common.rest.RestProducerInvocationFlow;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.http.StandardHttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.StandardHttpServletResponseEx;\n\nimport jakarta.servlet.AsyncContext;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\n\npublic class ServletRestDispatcher {\n  private final RestAsyncListener restAsyncListener = new RestAsyncListener();\n\n  private Transport transport;\n\n  private MicroserviceMeta microserviceMeta;\n\n  public void service(HttpServletRequest request, HttpServletResponse response) {\n    if (transport == null) {\n      transport = SCBEngine.getInstance().getTransportManager().findTransport(CoreConst.RESTFUL);\n      microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();\n    }\n\n    // 异步场景\n    AsyncContext asyncCtx = request.startAsync();\n    asyncCtx.addListener(restAsyncListener);\n    asyncCtx.setTimeout(ServletConfig.getAsyncServletTimeout(SCBEngine.getInstance().getEnvironment()));\n\n    HttpServletRequestEx requestEx = new StandardHttpServletRequestEx(request);\n    HttpServletResponseEx responseEx = new StandardHttpServletResponseEx(response);\n\n    ((StandardHttpServletRequestEx) requestEx).setCacheRequest(true);\n    InvocationCreator creator = new RestServletProducerInvocationCreator(microserviceMeta, transport.getEndpoint(),\n        requestEx, responseEx);\n    new RestProducerInvocationFlow(creator, requestEx, responseEx)\n        .run();\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/ServletRestTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\npublic class ServletRestTransport extends AbstractTransport {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServletRestTransport.class);\n\n  @Override\n  public String getName() {\n    return CoreConst.RESTFUL;\n  }\n\n  @Override\n  public boolean canInit() {\n    String listenAddress = ServletConfig.getLocalServerAddress(environment);\n    if (listenAddress == null) {\n      // not publish, but can init and be RESTful client\n      return true;\n    }\n\n    if (!ServletUtils.canPublishEndpoint(listenAddress)) {\n      LOGGER.info(\"ignore transport {}.\", this.getClass().getName());\n      return false;\n    }\n\n    return true;\n  }\n\n  @Override\n  public boolean init() {\n    String urlPrefix = ClassLoaderScopeContext.getClassLoaderScopeProperty(DefinitionConst.URL_PREFIX);\n    Map<String, String> queryMap = new HashMap<>();\n    if (!StringUtils.isEmpty(urlPrefix)) {\n      queryMap.put(DefinitionConst.URL_PREFIX, urlPrefix);\n    }\n\n    String listenAddress = ServletConfig.getLocalServerAddress(environment);\n    setListenAddressWithoutSchema(listenAddress, queryMap);\n\n    return true;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/ServletUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.io.File;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.common.rest.UploadConfig;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.common.net.IpPort;\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.servlet.MultipartConfigElement;\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletRegistration;\nimport jakarta.servlet.ServletRegistration.Dynamic;\n\npublic class ServletUtils {\n  private static final Logger LOGGER = LoggerFactory.getLogger(ServletUtils.class);\n\n  public static boolean canPublishEndpoint(String listenAddress) {\n    if (StringUtils.isEmpty(listenAddress)) {\n      LOGGER.info(\"listenAddress is null, can not publish.\");\n      return false;\n    }\n\n    IpPort ipPort = NetUtils.parseIpPortFromURI(\"http://\" + listenAddress);\n    if (ipPort == null) {\n      LOGGER.info(\"invalid listenAddress {}, can not publish, format should be ip:port.\", listenAddress);\n      return false;\n    }\n\n    if (NetUtils.canTcpListen(ipPort.getSocketAddress().getAddress(), ipPort.getPort())) {\n      LOGGER.info(\"{} is not listened, can not publish.\", ipPort.getSocketAddress());\n      return false;\n    }\n\n    return true;\n  }\n\n  // we only support path prefix rule\n  // other invalid urlPattern will be check by web container, we do not handle that\n  static void checkUrlPattern(String urlPattern) {\n    if (!urlPattern.startsWith(\"/\")) {\n      throw new ServiceCombException(\"only support rule like /* or /path/* or /path1/path2/* and so on.\");\n    }\n\n    int idx = urlPattern.indexOf(\"/*\");\n    if (idx < 0 || idx != urlPattern.length() - 2) {\n      throw new ServiceCombException(\"only support rule like /* or /path/* or /path1/path2/* and so on.\");\n    }\n  }\n\n  static String[] filterUrlPatterns(String... urlPatterns) {\n    return filterUrlPatterns(Arrays.asList(urlPatterns));\n  }\n\n  static String[] filterUrlPatterns(Collection<String> urlPatterns) {\n    return urlPatterns.stream()\n        .filter(pattern -> !pattern.trim().isEmpty())\n        .filter(pattern -> {\n          checkUrlPattern(pattern.trim());\n          return true;\n        })\n        .toArray(String[]::new);\n  }\n\n  static String[] collectUrlPatterns(ServletContext servletContext, Class<?> servletCls) {\n    List<ServletRegistration> servlets = findServletRegistrations(servletContext, servletCls);\n    if (servlets.isEmpty()) {\n      return new String[] {};\n    }\n\n    ServletRegistration servletRegistration = servlets.get(0);\n    Collection<String> mappings = servletRegistration.getMappings();\n    if (servlets.size() > 1) {\n      LOGGER.info(\"Found {} {} registered, select the first one, mappings={}.\",\n          servlets.size(),\n          servletCls.getName(),\n          mappings);\n    }\n    return filterUrlPatterns(mappings);\n  }\n\n  static List<ServletRegistration> findServletRegistrations(ServletContext servletContext,\n      Class<?> servletCls) {\n    if (servletContext == null) {\n      return null;\n    }\n    return servletContext.getServletRegistrations()\n        .values()\n        .stream()\n        .filter(predicate -> predicate.getClassName().equals(servletCls.getName()))\n        .collect(Collectors.toList());\n  }\n\n  static String collectUrlPrefix(ServletContext servletContext, Class<?> servletCls) {\n    String[] urlPatterns = collectUrlPatterns(servletContext, servletCls);\n    if (urlPatterns.length == 0) {\n      return null;\n    }\n\n    // even have multiple urlPattern, we only choose one to set as urlPrefix\n    // only make sure sdk can invoke\n    String urlPattern = urlPatterns[0];\n    return servletContext.getContextPath() + urlPattern.substring(0, urlPattern.length() - 2);\n  }\n\n  public static void saveUrlPrefix(ServletContext servletContext) {\n    String urlPrefix = collectUrlPrefix(servletContext, RestServlet.class);\n    if (urlPrefix == null) {\n      LOGGER.info(\"RestServlet not found, will not save UrlPrefix.\");\n      return;\n    }\n\n    ClassLoaderScopeContext.setClassLoaderScopeProperty(DefinitionConst.URL_PREFIX, urlPrefix);\n    LOGGER.info(\"UrlPrefix of this instance is \\\"{}\\\".\", urlPrefix);\n  }\n\n  static File createUploadDir(ServletContext servletContext, String location) {\n    // If relative, it is relative to TEMPDIR\n    File dir = new File(location);\n    if (!dir.isAbsolute()) {\n      dir = new File((File) servletContext.getAttribute(ServletContext.TEMPDIR), location).getAbsoluteFile();\n    }\n\n    if (!dir.exists()) {\n      dir.mkdirs();\n    }\n\n    return dir;\n  }\n\n  static void setServletParameters(ServletContext servletContext, Environment environment) {\n    UploadConfig uploadConfig = new UploadConfig(environment);\n    MultipartConfigElement multipartConfig = uploadConfig.toMultipartConfigElement();\n\n    File dir = createUploadDir(servletContext, multipartConfig.getLocation());\n    LOGGER.info(\"set uploads directory to \\\"{}\\\".\", dir.getAbsolutePath());\n\n    List<ServletRegistration> servlets = findServletRegistrations(servletContext, RestServlet.class);\n    if (servlets != null) {\n      for (ServletRegistration servletRegistration : servlets) {\n        if (!Dynamic.class.isInstance(servletRegistration)) {\n          continue;\n        }\n\n        Dynamic dynamic = (Dynamic) servletRegistration;\n        dynamic.setMultipartConfig(multipartConfig);\n      }\n    }\n  }\n\n  public static void init(ServletContext servletContext, Environment environment) {\n    RestServletInjector.defaultInject(servletContext, environment);\n    ServletUtils.saveUrlPrefix(servletContext);\n    setServletParameters(servletContext, environment);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.transport.rest.servlet.ServletRestTransport\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestAsyncListener.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.io.Writer;\n\nimport jakarta.servlet.AsyncContext;\nimport jakarta.servlet.AsyncEvent;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\nimport jakarta.ws.rs.core.MediaType;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.vertx.http.AbstractHttpServletRequest;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.StandardHttpServletRequestEx;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\nimport org.junit.jupiter.api.Assertions;\n\npublic class TestRestAsyncListener {\n  HttpServletRequest request = new AbstractHttpServletRequest() {\n    public String getMethod() {\n      return \"GET\";\n    }\n\n    public String getRequestURI() {\n      return \"path\";\n    }\n  };\n\n  HttpServletRequestEx requestEx = new StandardHttpServletRequestEx(request);\n\n  boolean committed;\n\n  boolean flushed;\n\n  int statusCode;\n\n  String contentType;\n\n  Writer writer = new StringWriter();\n\n  PrintWriter printWriter = new PrintWriter(writer);\n\n  @Mocked\n  HttpServletResponse response;\n\n  @Mocked\n  AsyncContext context;\n\n  AsyncEvent event;\n\n  RestAsyncListener listener = new RestAsyncListener();\n\n\n  @Before\n  public void setup() {\n    event = new AsyncEvent(context, requestEx, response);\n    requestEx.setAttribute(RestConst.REST_REQUEST, requestEx);\n\n    new MockUp<HttpServletResponse>(response) {\n      @Mock\n      void setContentType(String type) {\n        contentType = type;\n      }\n\n      @Mock\n      void setStatus(int sc) {\n        statusCode = sc;\n      }\n\n      @Mock\n      boolean isCommitted() {\n        return committed;\n      }\n\n      @Mock\n      PrintWriter getWriter() throws IOException {\n        return printWriter;\n      }\n\n      @Mock\n      void flushBuffer() throws IOException {\n        flushed = true;\n      }\n    };\n  }\n\n  @Test\n  public void onTimeoutCommitted() throws IOException {\n    committed = true;\n    listener.onTimeout(event);\n\n    Assertions.assertNull(request.getAttribute(RestConst.REST_REQUEST));\n    Assertions.assertFalse(flushed);\n  }\n\n  @Test\n  public void onTimeoutNotCommitted() throws IOException {\n    committed = false;\n    listener.onTimeout(event);\n\n    Assertions.assertNull(request.getAttribute(RestConst.REST_REQUEST));\n    Assertions.assertEquals(MediaType.APPLICATION_JSON, contentType);\n    Assertions.assertEquals(500, statusCode);\n    Assertions.assertTrue(flushed);\n    Assertions.assertEquals(\"{\\\"message\\\":\\\"Timeout when processing the request.\\\"}\", writer.toString());\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestServlet.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport static org.apache.servicecomb.core.transport.AbstractTransport.PUBLISH_ADDRESS;\n\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.impl.SysProps;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\nimport mockit.Deencapsulation;\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class TestRestServlet {\n  private RestServlet restservlet = null;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(PUBLISH_ADDRESS, String.class, \"\"))\n        .thenReturn(\"\");\n    Mockito.when(environment.getProperty(\"servicecomb.rest.publishPort\", int.class, 0))\n        .thenReturn(0);\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n    restservlet = new RestServlet();\n\n    SCBBootstrap.createSCBEngineForTest(environment);\n  }\n\n  @After\n  public void tearDown() {\n    restservlet = null;\n    SCBEngine.getInstance().destroy();\n  }\n\n  @Test\n  public void testInit() throws ServletException {\n    restservlet.init();\n    Assertions.assertTrue(true);\n  }\n\n  // useless, but for coverage\n  @Test\n  public void testService() {\n    Holder<Boolean> holder = new Holder<>();\n    ServletRestDispatcher servletRestServer = new MockUp<ServletRestDispatcher>() {\n      @Mock\n      void service(HttpServletRequest request, HttpServletResponse response) {\n        holder.value = true;\n      }\n    }.getMockInstance();\n\n    Deencapsulation.setField(restservlet, \"servletRestServer\", servletRestServer);\n    restservlet.service(null, null);\n    Assertions.assertTrue(holder.value);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestServletInjector.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.ServerSocket;\nimport java.net.UnknownHostException;\n\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletRegistration.Dynamic;\nimport mockit.Expectations;\nimport mockit.Mocked;\n\npublic class TestRestServletInjector {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Test\n  public void testDefaultInjectEmptyUrlPattern(@Mocked ServletContext servletContext, @Mocked Dynamic dynamic) {\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getServletUrlPattern(environment);\n        result = null;\n      }\n    };\n\n    Assertions.assertNull(RestServletInjector.defaultInject(servletContext, environment));\n  }\n\n  @Test\n  public void testDefaultInjectNotListen(@Mocked ServletContext servletContext,\n      @Mocked Dynamic dynamic) throws UnknownHostException, IOException {\n    try (ServerSocket ss = new ServerSocket(0, 0, InetAddress.getByName(\"127.0.0.1\"))) {\n      int port = ss.getLocalPort();\n\n      new Expectations(ServletConfig.class) {\n        {\n          ServletConfig.getServletUrlPattern(environment);\n          result = \"/*\";\n          ServletConfig.getLocalServerAddress(environment);\n          result = \"127.0.0.1:\" + port;\n        }\n      };\n    }\n\n    Assertions.assertNull(RestServletInjector.defaultInject(servletContext, environment));\n  }\n\n  @Test\n  public void testDefaultInjectListen(@Mocked ServletContext servletContext,\n      @Mocked Dynamic dynamic) throws UnknownHostException, IOException {\n    try (ServerSocket ss = new ServerSocket(0, 0, InetAddress.getByName(\"127.0.0.1\"))) {\n      int port = ss.getLocalPort();\n\n      new Expectations(ServletConfig.class) {\n        {\n          ServletConfig.getServletUrlPattern(environment);\n          result = \"/rest/*\";\n          ServletConfig.getLocalServerAddress(environment);\n          result = \"127.0.0.1:\" + port;\n        }\n      };\n\n      Assertions.assertEquals(dynamic, RestServletInjector.defaultInject(servletContext, environment));\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestServletRestTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport static org.apache.servicecomb.core.transport.AbstractTransport.PUBLISH_ADDRESS;\n\nimport java.io.IOException;\nimport java.net.ServerSocket;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.impl.SysProps;\nimport mockit.Expectations;\n\npublic class TestServletRestTransport {\n  ServletRestTransport transport;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(PUBLISH_ADDRESS, \"\"))\n        .thenReturn(\"\");\n    Mockito.when(environment.getProperty(\"servicecomb.rest.publishPort\", int.class, 0))\n        .thenReturn(0);\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n    transport = new ServletRestTransport();\n    transport.setEnvironment(environment);\n  }\n\n  @After\n  public void tearDown() {\n    ClassLoaderScopeContext.clearClassLoaderScopeProperty();\n  }\n\n  @Test\n  public void testInitNotPublish() {\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getLocalServerAddress(environment);\n        result = null;\n      }\n    };\n    Assertions.assertTrue(transport.init());\n    Assertions.assertNull(transport.getPublishEndpoint());\n  }\n\n  @Test\n  public void testInitPublishNoUrlPrefix() {\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getLocalServerAddress(environment);\n        result = \"1.1.1.1:1234\";\n      }\n    };\n    Assertions.assertTrue(transport.init());\n    Assertions.assertEquals(\"rest://1.1.1.1:1234\", transport.getPublishEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testInitPublishWithUrlPrefix() {\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getLocalServerAddress(environment);\n        result = \"1.1.1.1:1234\";\n      }\n    };\n    ClassLoaderScopeContext.setClassLoaderScopeProperty(DefinitionConst.URL_PREFIX, \"/root\");\n\n    Assertions.assertTrue(transport.init());\n    Assertions.assertEquals(\"rest://1.1.1.1:1234?urlPrefix=%2Froot\", transport.getPublishEndpoint().getEndpoint());\n  }\n\n  @Test\n  public void testGetOrder() {\n    ServletRestTransport transport = new ServletRestTransport();\n    Assertions.assertEquals(0, transport.getOrder());\n  }\n\n  @Test\n  public void testCanInitNullAddress() throws IOException {\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getLocalServerAddress(environment);\n        result = null;\n      }\n    };\n\n    ServletRestTransport transport = new ServletRestTransport();\n    transport.setEnvironment(environment);\n    Assertions.assertTrue(transport.canInit());\n  }\n\n  @Test\n  public void testCanInitListened() throws IOException {\n    ServerSocket ss = new ServerSocket(0);\n    int port = ss.getLocalPort();\n\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getLocalServerAddress(environment);\n        result = \"0.0.0.0:\" + port;\n      }\n    };\n\n    ServletRestTransport transport = new ServletRestTransport();\n    transport.setEnvironment(environment);\n    Assertions.assertTrue(transport.canInit());\n\n    ss.close();\n  }\n\n  @Test\n  public void testCanInitNotListened() throws IOException {\n    ServerSocket ss = new ServerSocket(0);\n    int port = ss.getLocalPort();\n    ss.close();\n\n    new Expectations(ServletConfig.class) {\n      {\n        ServletConfig.getLocalServerAddress(environment);\n        result = \"0.0.0.0:\" + port;\n      }\n    };\n\n    ServletRestTransport transport = new ServletRestTransport();\n    transport.setEnvironment(environment);\n    Assertions.assertFalse(transport.canInit());\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestServletUtils.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.servlet;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport jakarta.servlet.MultipartConfigElement;\nimport jakarta.servlet.ServletContext;\nimport jakarta.servlet.ServletRegistration;\nimport jakarta.servlet.ServletRegistration.Dynamic;\nimport jakarta.servlet.http.HttpServlet;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestServletUtils {\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_DIR, RestConst.UPLOAD_DEFAULT_DIR))\n        .thenReturn(RestConst.UPLOAD_DEFAULT_DIR);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_MAX_FILE_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_MAX_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_FILE_SIZE_THRESHOLD, int.class, 0))\n        .thenReturn(0);\n    LegacyPropertyFactory.setEnvironment(environment);\n  }\n\n  @Test\n  public void testCheckUrlPatternNormal() {\n    ServletUtils.checkUrlPattern(\"/*\");\n    ServletUtils.checkUrlPattern(\"/abc/*\");\n    ServletUtils.checkUrlPattern(\"/abc/def/*\");\n\n    // normal, must not throw exception, no need to check\n  }\n\n  @Test\n  public void testCheckUrlPatternMiddleWideChar() {\n    try {\n      ServletUtils.checkUrlPattern(\"/abc/*def\");\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\"only support rule like /* or /path/* or /path1/path2/* and so on.\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testCheckUrlPatternNoWideChar() {\n    try {\n      ServletUtils.checkUrlPattern(\"/abcdef\");\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\"only support rule like /* or /path/* or /path1/path2/* and so on.\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testCheckUrlPatternNotStartWithSlash() {\n    try {\n      ServletUtils.checkUrlPattern(\"abcdef/*\");\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\"only support rule like /* or /path/* or /path1/path2/* and so on.\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testFilterUrlPatternsNormal() {\n    String urlPattern = \"/r1/*\";\n\n    Collection<String> urlPatterns = Arrays.asList(urlPattern);\n    String[] result = ServletUtils.filterUrlPatterns(urlPatterns);\n    MatcherAssert.assertThat(result, Matchers.arrayContaining(\"/r1/*\"));\n\n    result = ServletUtils.filterUrlPatterns(urlPattern);\n    MatcherAssert.assertThat(result, Matchers.arrayContaining(\"/r1/*\"));\n  }\n\n  @Test\n  public void testFilterUrlPatternsEmpty() {\n    Collection<String> urlPatterns = Arrays.asList(\" \", \"\\t\");\n    String[] result = ServletUtils.filterUrlPatterns(urlPatterns);\n    MatcherAssert.assertThat(result, Matchers.emptyArray());\n  }\n\n  @Test\n  public void testFilterUrlPatternsInvalid() {\n    Collection<String> urlPatterns = Arrays.asList(\"/abc\");\n    try {\n      ServletUtils.filterUrlPatterns(urlPatterns);\n      Assertions.fail(\"must throw exception\");\n    } catch (ServiceCombException e) {\n      Assertions.assertEquals(\"only support rule like /* or /path/* or /path1/path2/* and so on.\", e.getMessage());\n    }\n  }\n\n  @Test\n  public void testcollectUrlPatternsNoRestServlet(@Mocked ServletContext servletContext,\n      @Mocked ServletRegistration servletRegistration) {\n    new Expectations() {\n      {\n        servletRegistration.getClassName();\n        result = \"test\";\n        servletContext.getServletRegistrations();\n        result = Collections.singletonMap(\"test\", servletRegistration);\n      }\n    };\n\n    String[] result = ServletUtils.collectUrlPatterns(servletContext, RestServlet.class);\n    MatcherAssert.assertThat(result, Matchers.emptyArray());\n  }\n\n  @Test\n  public void testcollectUrlPatternsNormalMapping(@Mocked ServletContext servletContext,\n      @Mocked ServletRegistration r1, @Mocked ServletRegistration r2) {\n    Map<String, ServletRegistration> servletRegistrationMap = new LinkedHashMap<>();\n    servletRegistrationMap.put(\"r1\", r1);\n    servletRegistrationMap.put(\"r2\", r2);\n\n    new Expectations() {\n      {\n        r1.getClassName();\n        result = RestServlet.class.getName();\n        r1.getMappings();\n        result = Arrays.asList(\"/r1/*\", \"/r1/1/*\");\n\n        r2.getClassName();\n        result = RestServlet.class.getName();\n\n        servletContext.getServletRegistrations();\n        result = servletRegistrationMap;\n      }\n    };\n\n    String[] result = ServletUtils.collectUrlPatterns(servletContext, RestServlet.class);\n    MatcherAssert.assertThat(result, Matchers.arrayContaining(\"/r1/*\", \"/r1/1/*\"));\n  }\n\n  @Test\n  public void testSaveUrlPrefixNull(@Mocked ServletContext servletContext) {\n    ClassLoaderScopeContext.clearClassLoaderScopeProperty();\n\n    ServletUtils.saveUrlPrefix(servletContext);\n\n    Assertions.assertNull(ClassLoaderScopeContext.getClassLoaderScopeProperty(DefinitionConst.URL_PREFIX));\n    ClassLoaderScopeContext.clearClassLoaderScopeProperty();\n  }\n\n  @Test\n  public void testSaveUrlPrefixNormal(@Mocked ServletContext servletContext,\n      @Mocked ServletRegistration servletRegistration) {\n    ClassLoaderScopeContext.clearClassLoaderScopeProperty();\n    new Expectations() {\n      {\n        servletContext.getContextPath();\n        result = \"/root\";\n        servletRegistration.getClassName();\n        result = RestServlet.class.getName();\n        servletRegistration.getMappings();\n        result = Arrays.asList(\"/rest/*\");\n        servletContext.getServletRegistrations();\n        result = Collections.singletonMap(\"test\", servletRegistration);\n      }\n    };\n\n    ServletUtils.saveUrlPrefix(servletContext);\n\n    MatcherAssert.assertThat(ClassLoaderScopeContext.getClassLoaderScopeProperty(DefinitionConst.URL_PREFIX),\n        Matchers.is(\"/root/rest\"));\n    ClassLoaderScopeContext.clearClassLoaderScopeProperty();\n  }\n\n  @Test\n  public void createUploadDir_relative(@Mocked ServletContext servletContext) throws IOException {\n    File tempDir = Files.createTempDirectory(\"temp\").toFile();\n    new Expectations() {\n      {\n        servletContext.getAttribute(ServletContext.TEMPDIR);\n        result = tempDir;\n      }\n    };\n\n    File expectDir = new File(tempDir, \"upload\");\n    Assertions.assertFalse(expectDir.exists());\n\n    File dir = ServletUtils.createUploadDir(servletContext, \"upload\");\n    Assertions.assertTrue(expectDir.exists());\n    Assertions.assertEquals(expectDir.getAbsolutePath(), dir.getAbsolutePath());\n\n    dir.delete();\n    Assertions.assertFalse(expectDir.exists());\n\n    tempDir.delete();\n    Assertions.assertFalse(tempDir.exists());\n  }\n\n  @Test\n  public void createUploadDir_absolute(@Mocked ServletContext servletContext) throws IOException {\n    File tempDir = Files.createTempDirectory(\"temp\").toFile();\n\n    File expectDir = new File(tempDir, \"upload\");\n    Assertions.assertFalse(expectDir.exists());\n\n    File dir = ServletUtils.createUploadDir(servletContext, expectDir.getAbsolutePath());\n    Assertions.assertTrue(expectDir.exists());\n    Assertions.assertEquals(expectDir.getAbsolutePath(), dir.getAbsolutePath());\n\n    dir.delete();\n    Assertions.assertFalse(expectDir.exists());\n\n    tempDir.delete();\n    Assertions.assertFalse(tempDir.exists());\n  }\n\n  @Test\n  public void setServletParameters_notSupportUpload() {\n    // not support upload will not set parameters to servlet, so servletContext is null will not throw exception\n    ServletUtils.setServletParameters(null, environment);\n  }\n\n  @Test\n  public void setServletParameters_supportUpload(@Mocked ServletContext servletContext, @Mocked Dynamic d1,\n      @Mocked ServletRegistration d2) throws IOException {\n    Map<String, ServletRegistration> servletRegistrations = new HashMap<>();\n    servletRegistrations.put(\"d1\", d1);\n    servletRegistrations.put(\"d2\", d2);\n    new Expectations() {\n      {\n        servletContext.getServletRegistrations();\n        result = servletRegistrations;\n        d1.getClassName();\n        result = RestServlet.class.getName();\n        d2.getClassName();\n        result = HttpServlet.class.getName();\n      }\n    };\n\n    List<MultipartConfigElement> multipartConfigs = new ArrayList<>();\n    new MockUp<Dynamic>(d1) {\n      @Mock\n      void setMultipartConfig(MultipartConfigElement multipartConfig) {\n        multipartConfigs.add(multipartConfig);\n      }\n    };\n\n    File tempDir = Files.createTempDirectory(\"temp\").toFile();\n    File uploadDir = new File(tempDir, \"upload\");\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_DIR, RestConst.UPLOAD_DEFAULT_DIR))\n        .thenReturn(uploadDir.getAbsolutePath());\n\n    ServletUtils.setServletParameters(servletContext, environment);\n\n    Assertions.assertEquals(1, multipartConfigs.size());\n\n    MultipartConfigElement multipartConfigElement = multipartConfigs.get(0);\n    Assertions.assertEquals(uploadDir.getAbsolutePath(), multipartConfigElement.getLocation());\n    Assertions.assertEquals(-1, multipartConfigElement.getMaxFileSize());\n    Assertions.assertEquals(-1, multipartConfigElement.getMaxRequestSize());\n    Assertions.assertEquals(0, multipartConfigElement.getFileSizeThreshold());\n\n    uploadDir.delete();\n    tempDir.delete();\n    Assertions.assertFalse(tempDir.exists());\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/pom.xml",
    "content": "<?xml version=\"1.0\"?>\n<!--\n  ~ Licensed to the Apache Software Foundation (ASF) under one or more\n  ~ contributor license agreements.  See the NOTICE file distributed with\n  ~ this work for additional information regarding copyright ownership.\n  ~ The ASF licenses this file to You under the Apache License, Version 2.0\n  ~ (the \"License\"); you may not use this file except in compliance with\n  ~ the License.  You may obtain a copy of the License at\n  ~\n  ~     http://www.apache.org/licenses/LICENSE-2.0\n  ~\n  ~ Unless required by applicable law or agreed to in writing, software\n  ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  ~ See the License for the specific language governing permissions and\n  ~ limitations under the License.\n  -->\n\n<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"\n  xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <modelVersion>4.0.0</modelVersion>\n  <parent>\n    <groupId>org.apache.servicecomb</groupId>\n    <artifactId>transport-rest</artifactId>\n    <version>3.4.0-SNAPSHOT</version>\n  </parent>\n  <artifactId>transport-rest-vertx</artifactId>\n  <name>Java Chassis::Transports::Rest::Vertx</name>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>transport-rest-client</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>io.vertx</groupId>\n      <artifactId>vertx-codegen</artifactId>\n      <scope>provided</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>registry-service-center</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-slf4j-impl</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.logging.log4j</groupId>\n      <artifactId>log4j-core</artifactId>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>foundation-test-scaffolding</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.apache.servicecomb</groupId>\n      <artifactId>common-access-log</artifactId>\n    </dependency>\n    <dependency>\n      <groupId>org.jmockit</groupId>\n      <artifactId>jmockit</artifactId>\n      <scope>test</scope>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/AbstractVertxHttpDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.common.rest.UploadConfig;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.ext.web.handler.BodyHandler;\n\npublic abstract class AbstractVertxHttpDispatcher implements VertxHttpDispatcher {\n  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractVertxHttpDispatcher.class);\n\n  protected BodyHandler createBodyHandler() {\n    RestBodyHandler bodyHandler = new RestBodyHandler();\n\n    UploadConfig uploadConfig = new UploadConfig(LegacyPropertyFactory.getEnvironment());\n\n    bodyHandler.setUploadsDirectory(uploadConfig.getLocation());\n    bodyHandler.setDeleteUploadedFilesOnEnd(true);\n    bodyHandler.setBodyLimit(uploadConfig.getMaxSize());\n\n    if (uploadConfig.toMultipartConfigElement() != null) {\n      LOGGER.info(\"set uploads directory to \\\"{}\\\".\", uploadConfig.getLocation());\n    }\n\n    return bodyHandler;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/GlobalRestFailureHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\nimport io.vertx.core.Handler;\nimport io.vertx.ext.web.RoutingContext;\n\npublic interface GlobalRestFailureHandler extends Handler<RoutingContext>, SPIOrder {\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/HttpServerExceptionHandler.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport io.vertx.core.Handler;\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\npublic interface HttpServerExceptionHandler extends Handler<Throwable>, SPIOrder {\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java",
    "content": "/*\n * Copyright 2014 Red Hat, Inc.\n *\n *  All rights reserved. This program and the accompanying materials\n *  are made available under the terms of the Eclipse Public License v1.0\n *  and Apache License v2.0 which accompanies this distribution.\n *\n *  The Eclipse Public License is available at\n *  http://www.eclipse.org/legal/epl-v10.html\n *\n *  The Apache License v2.0 is available at\n *  http://www.opensource.org/licenses/apache2.0.php\n *\n *  You may elect to redistribute this code under either of these licenses.\n *\n */\n\n/*\n *  Froked from https://github.com/vert-x3/vertx-web/blob/master/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/BodyHandlerImpl.java\n *\n */\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport java.io.File;\nimport java.util.List;\nimport java.util.UUID;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.netty.handler.codec.DecoderException;\nimport io.netty.handler.codec.http.HttpHeaderValues;\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.file.FileSystem;\nimport io.vertx.core.http.HttpHeaders;\nimport io.vertx.core.http.HttpServerRequest;\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.core.http.HttpVersion;\nimport io.vertx.ext.web.FileUpload;\nimport io.vertx.ext.web.RoutingContext;\nimport io.vertx.ext.web.handler.BodyHandler;\nimport io.vertx.ext.web.impl.FileUploadImpl;\nimport io.vertx.ext.web.impl.RoutingContextInternal;\n\n/**\n * copy from io.vertx.ext.web.handler.impl.BodyHandlerImpl\n * and modified.\n *\n * allowed to disable fileupload by setUploadsDirectory(null)\n */\npublic class RestBodyHandler implements BodyHandler {\n\n  private long bodyLimit = DEFAULT_BODY_LIMIT;\n\n  private boolean handleFileUploads;\n\n  private String uploadsDir;\n\n  private boolean mergeFormAttributes = DEFAULT_MERGE_FORM_ATTRIBUTES;\n\n  private boolean deleteUploadedFilesOnEnd = DEFAULT_DELETE_UPLOADED_FILES_ON_END;\n\n  private boolean isPreallocateBodyBuffer = DEFAULT_PREALLOCATE_BODY_BUFFER;\n\n  private static final int DEFAULT_INITIAL_BODY_BUFFER_SIZE = 1024; //bytes\n\n  public static final String BYPASS_BODY_HANDLER = \"__bypass_body_handler\";\n\n  public RestBodyHandler() {\n    this(true, DEFAULT_UPLOADS_DIRECTORY);\n  }\n\n  public RestBodyHandler(boolean handleFileUploads) {\n    this(handleFileUploads, DEFAULT_UPLOADS_DIRECTORY);\n  }\n\n  public RestBodyHandler(String uploadDirectory) {\n    this(true, uploadDirectory);\n  }\n\n  private RestBodyHandler(boolean handleFileUploads, String uploadDirectory) {\n    this.handleFileUploads = handleFileUploads;\n    setUploadsDirectory(uploadDirectory);\n  }\n\n  @VisibleForTesting\n  boolean isDeleteUploadedFilesOnEnd() {\n    return deleteUploadedFilesOnEnd;\n  }\n\n  @Override\n  public void handle(RoutingContext context) {\n    final HttpServerRequest request = context.request();\n    final HttpServerResponse response = context.response();\n\n    if (request.headers().contains(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET, true)) {\n      context.next();\n      return;\n    }\n\n    Boolean bypass = context.get(BYPASS_BODY_HANDLER);\n    if (Boolean.TRUE.equals(bypass)) {\n      context.next();\n      return;\n    }\n\n    // we need to keep state since we can be called again on reroute\n    if (!((RoutingContextInternal) context).seenHandler(RoutingContextInternal.BODY_HANDLER)) {\n      ((RoutingContextInternal) context).visitHandler(RoutingContextInternal.BODY_HANDLER);\n\n      // Check if a request has a request body.\n      // A request with a body __must__ either have `transfer-encoding`\n      // or `content-length` headers set.\n      // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3\n      final long parsedContentLength = parseContentLengthHeader(request);\n      // http2 never transmits a `transfer-encoding` as frames are chunks.\n      final boolean hasTransferEncoding =\n          request.version() == HttpVersion.HTTP_2 || request.headers().contains(HttpHeaders.TRANSFER_ENCODING);\n\n      if (!hasTransferEncoding && parsedContentLength == -1) {\n        // there is no \"body\", so we can skip this handler\n        context.next();\n        return;\n      }\n\n      // before parsing the body we can already discard a bad request just by inspecting the content-length against\n      // the body limit, this will reduce load, on the server by totally skipping parsing the request body\n      if (bodyLimit != -1 && parsedContentLength != -1) {\n        if (parsedContentLength > bodyLimit) {\n          context.fail(413);\n          return;\n        }\n      }\n\n      // handle expectations\n      // https://httpwg.org/specs/rfc7231.html#header.expect\n      final String expect = request.getHeader(HttpHeaders.EXPECT);\n      if (expect != null) {\n        // requirements validation\n        if (expect.equalsIgnoreCase(\"100-continue\")) {\n          // A server that receives a 100-continue expectation in an HTTP/1.0 request MUST ignore that expectation.\n          if (request.version() != HttpVersion.HTTP_1_0) {\n            // signal the client to continue\n            response.writeContinue();\n          }\n        } else {\n          // the server cannot meet the expectation, we only know about 100-continue\n          context.fail(417);\n          return;\n        }\n      }\n\n      final BHandler handler = new BHandler(context, isPreallocateBodyBuffer ? parsedContentLength : -1);\n      boolean ended = request.isEnded();\n      if (!ended) {\n        request\n            // resume the request (if paused)\n            .handler(handler)\n            .endHandler(handler::end)\n            .resume();\n      }\n    } else {\n      // on reroute we need to re-merge the form params if that was desired\n      if (mergeFormAttributes && request.isExpectMultipart()) {\n        request.params().addAll(request.formAttributes());\n      }\n\n      context.next();\n    }\n  }\n\n  @Override\n  public BodyHandler setHandleFileUploads(boolean handleFileUploads) {\n    this.handleFileUploads = handleFileUploads;\n    return this;\n  }\n\n  @Override\n  public BodyHandler setBodyLimit(long bodyLimit) {\n    this.bodyLimit = bodyLimit;\n    return this;\n  }\n\n  @Override\n  public BodyHandler setUploadsDirectory(String uploadsDirectory) {\n    this.uploadsDir = uploadsDirectory;\n    return this;\n  }\n\n  @Override\n  public BodyHandler setMergeFormAttributes(boolean mergeFormAttributes) {\n    this.mergeFormAttributes = mergeFormAttributes;\n    return this;\n  }\n\n  @Override\n  public BodyHandler setDeleteUploadedFilesOnEnd(boolean deleteUploadedFilesOnEnd) {\n    this.deleteUploadedFilesOnEnd = deleteUploadedFilesOnEnd;\n    return this;\n  }\n\n  @Override\n  public BodyHandler setPreallocateBodyBuffer(boolean isPreallocateBodyBuffer) {\n    this.isPreallocateBodyBuffer = isPreallocateBodyBuffer;\n    return this;\n  }\n\n  private long parseContentLengthHeader(HttpServerRequest request) {\n    String contentLength = request.getHeader(HttpHeaders.CONTENT_LENGTH);\n    if (contentLength == null || contentLength.isEmpty()) {\n      return -1;\n    }\n    try {\n      long parsedContentLength = Long.parseLong(contentLength);\n      return parsedContentLength < 0 ? -1 : parsedContentLength;\n    } catch (NumberFormatException ex) {\n      return -1;\n    }\n  }\n\n  private class BHandler implements Handler<Buffer> {\n    private static final int MAX_PREALLOCATED_BODY_BUFFER_BYTES = 65535;\n\n    final RoutingContext context;\n\n    final long contentLength;\n\n    Buffer body;\n\n    volatile boolean failed;\n\n    final AtomicInteger uploadCount = new AtomicInteger();\n\n    volatile boolean ended;\n\n    long uploadSize = 0L;\n\n    final boolean isMultipart;\n\n    final boolean isUrlEncoded;\n\n    public BHandler(RoutingContext context, long contentLength) {\n      this.context = context;\n      this.contentLength = contentLength;\n      // the request clearly states that there should\n      // be a body, so we respect the client and ensure\n      // that the body will not be null\n      if (contentLength != -1) {\n        initBodyBuffer();\n      }\n\n      List<FileUpload> fileUploads = context.fileUploads();\n\n      final String contentType = context.request().getHeader(HttpHeaders.CONTENT_TYPE);\n      if (contentType == null) {\n        isMultipart = false;\n        isUrlEncoded = false;\n      } else {\n        final String lowerCaseContentType = contentType.toLowerCase();\n        isMultipart = lowerCaseContentType.startsWith(HttpHeaderValues.MULTIPART_FORM_DATA.toString());\n        isUrlEncoded = lowerCaseContentType.startsWith(HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED.toString());\n      }\n\n      if (isMultipart || isUrlEncoded) {\n        context.request().setExpectMultipart(true);\n        if (handleFileUploads) {\n          makeUploadDir(context.vertx().fileSystem());\n        }\n        context.request().uploadHandler(upload -> {\n          // *** cse begin ***\n          if (uploadsDir == null) {\n            failed = true;\n            CommonExceptionData data = new CommonExceptionData(\"not support file upload.\");\n            context.fail(ExceptionFactory.createProducerException(data));\n            return;\n          }\n          // *** cse end ***\n          if (bodyLimit != -1 && upload.isSizeAvailable()) {\n            // we can try to abort even before the upload starts\n            long size = uploadSize + upload.size();\n            if (size > bodyLimit) {\n              failed = true;\n              context.cancelAndCleanupFileUploads();\n              context.fail(413);\n              return;\n            }\n          }\n          if (handleFileUploads) {\n            // we actually upload to a file with a generated filename\n            uploadCount.incrementAndGet();\n            String uploadedFileName = new File(uploadsDir, UUID.randomUUID().toString()).getPath();\n            FileUploadImpl fileUpload = new FileUploadImpl(context.vertx().fileSystem(), uploadedFileName, upload);\n            fileUploads.add(fileUpload);\n            Future<Void> fut = upload.streamToFileSystem(uploadedFileName);\n            fut.onComplete(ar -> {\n              if (fut.succeeded()) {\n                uploadEnded();\n              } else {\n                context.cancelAndCleanupFileUploads();\n                context.fail(ar.cause());\n              }\n            });\n          }\n        });\n      }\n\n      context.request().exceptionHandler(t -> {\n        context.cancelAndCleanupFileUploads();\n        int sc = 200;\n        if (t instanceof DecoderException) {\n          // bad request\n          sc = 400;\n          if (t.getCause() != null) {\n            t = t.getCause();\n          }\n        }\n        context.fail(sc, t);\n      });\n    }\n\n    private void initBodyBuffer() {\n      int initialBodyBufferSize;\n      if (contentLength < 0) {\n        initialBodyBufferSize = DEFAULT_INITIAL_BODY_BUFFER_SIZE;\n      } else if (contentLength > MAX_PREALLOCATED_BODY_BUFFER_BYTES) {\n        initialBodyBufferSize = MAX_PREALLOCATED_BODY_BUFFER_BYTES;\n      } else {\n        initialBodyBufferSize = (int) contentLength;\n      }\n\n      if (bodyLimit != -1) {\n        initialBodyBufferSize = (int) Math.min(initialBodyBufferSize, bodyLimit);\n      }\n\n      this.body = Buffer.buffer(initialBodyBufferSize);\n    }\n\n    private void makeUploadDir(FileSystem fileSystem) {\n      // *** cse begin ***\n      if (uploadsDir == null) {\n        return;\n      }\n      // *** cse end ***\n\n      if (!fileSystem.existsBlocking(uploadsDir)) {\n        fileSystem.mkdirsBlocking(uploadsDir);\n      }\n    }\n\n    @Override\n    public void handle(Buffer buff) {\n      if (failed) {\n        return;\n      }\n      uploadSize += buff.length();\n      if (bodyLimit != -1 && uploadSize > bodyLimit) {\n        failed = true;\n        context.cancelAndCleanupFileUploads();\n        context.fail(413);\n      } else {\n        // multipart requests will not end up in the request body\n        // url encoded should also not, however jQuery by default\n        // post in urlencoded even if the payload is something else\n        if (!isMultipart /* && !isUrlEncoded */) {\n          if (body == null) {\n            initBodyBuffer();\n          }\n          body.appendBuffer(buff);\n        }\n      }\n    }\n\n    void uploadEnded() {\n      int count = uploadCount.decrementAndGet();\n      // only if parsing is done and count is 0 then all files have been processed\n      if (ended && count == 0) {\n        doEnd();\n      }\n    }\n\n    void end(Void v) {\n      // this marks the end of body parsing, calling doEnd should\n      // only be possible from this moment onwards\n      ended = true;\n\n      // only if parsing is done and count is 0 then all files have been processed\n      if (uploadCount.get() == 0) {\n        doEnd();\n      }\n    }\n\n    void doEnd() {\n\n      if (failed || context.failed()) {\n        context.cancelAndCleanupFileUploads();\n        return;\n      }\n\n      if (deleteUploadedFilesOnEnd) {\n        context.addBodyEndHandler(x -> context.cancelAndCleanupFileUploads());\n      }\n\n      HttpServerRequest req = context.request();\n      if (mergeFormAttributes && req.isExpectMultipart()) {\n        req.params().addAll(req.formAttributes());\n      }\n      ((RoutingContextInternal) context).setBody(body);\n      // release body as it may take lots of memory\n      body = null;\n\n      context.next();\n    }\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport java.nio.channels.ClosedChannelException;\nimport java.util.List;\nimport java.util.Set;\n\nimport org.apache.servicecomb.common.accessLog.AccessLogConfig;\nimport org.apache.servicecomb.common.accessLog.core.element.impl.LocalHostAccessItem;\nimport org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.event.ServerAccessLogEvent;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.common.utils.ExceptionUtils;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.ssl.SSLCustom;\nimport org.apache.servicecomb.foundation.ssl.SSLOption;\nimport org.apache.servicecomb.foundation.ssl.SSLOptionFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;\nimport org.apache.servicecomb.foundation.vertx.metrics.DefaultHttpServerMetrics;\nimport org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport com.google.common.annotations.VisibleForTesting;\n\nimport io.vertx.core.AbstractVerticle;\nimport io.vertx.core.Context;\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.Promise;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.http.Http2Settings;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServer;\nimport io.vertx.core.http.HttpServerOptions;\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.core.net.impl.ConnectionBase;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\nimport io.vertx.ext.web.handler.CorsHandler;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.MediaType;\n\npublic class RestServerVerticle extends AbstractVerticle {\n  private static final Logger LOGGER = LoggerFactory.getLogger(RestServerVerticle.class);\n\n  private static final String SSL_KEY = \"rest.provider\";\n\n  private URIEndpointObject endpointObject;\n\n  private WebSocketDispatcher webSocketDispatcher;\n\n  @Override\n  public void init(Vertx vertx, Context context) {\n    super.init(vertx, context);\n    Endpoint endpoint = (Endpoint) context.config().getValue(AbstractTransport.ENDPOINT_KEY);\n    this.endpointObject = (URIEndpointObject) endpoint.getAddress();\n    this.webSocketDispatcher = new WebSocketDispatcher(endpoint);\n  }\n\n  @Override\n  public void start(Promise<Void> startPromise) throws Exception {\n    try {\n      super.start();\n      // 如果本地未配置地址，则表示不必监听，只需要作为客户端使用即可\n      if (endpointObject == null) {\n        LOGGER.warn(\"rest listen address is not configured, will not start.\");\n        startPromise.complete();\n        return;\n      }\n      Router mainRouter = Router.router(vertx);\n      mountAccessLogHandler(mainRouter);\n      mountCorsHandler(mainRouter);\n      initDispatcher(mainRouter);\n      mountGlobalRestFailureHandler(mainRouter);\n      HttpServer httpServer = createHttpServer();\n      httpServer.requestHandler(httpServerRequest -> {\n        if (this.endpointObject.isWebsocketEnabled()) {\n          String path = LegacyPropertyFactory.getStringProperty(\"servicecomb.rest.server.websocket-prefix\");\n          if (httpServerRequest.path().startsWith(path)) {\n            httpServerRequest.toWebSocket().onComplete(w -> webSocketDispatcher.onRequest(w),\n                e -> LOGGER.error(\"WebSocket error.\", e));\n            return;\n          }\n        }\n        mainRouter.handle(httpServerRequest);\n      });\n      httpServer.connectionHandler(connection -> {\n        DefaultHttpServerMetrics serverMetrics = (DefaultHttpServerMetrics) ((ConnectionBase) connection).metrics();\n        DefaultServerEndpointMetric endpointMetric = serverMetrics.getEndpointMetric();\n        long connectedCount = endpointMetric.getCurrentConnectionCount();\n        int connectionLimit = LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.server.connection-limit\",\n            Integer.MAX_VALUE);\n        if (connectedCount > connectionLimit) {\n          connection.close();\n          endpointMetric.onRejectByConnectionLimit();\n        }\n      });\n      List<HttpServerExceptionHandler> httpServerExceptionHandlers =\n          SPIServiceUtils.getAllService(HttpServerExceptionHandler.class);\n      httpServer.exceptionHandler(e -> {\n        if (e instanceof ClosedChannelException) {\n          // This is quite normal in between browser and edge, so do not print out.\n          LOGGER.debug(\"Unexpected error in server.{}\", ExceptionUtils.getExceptionMessageWithoutTrace(e));\n        } else {\n          LOGGER.error(\"Unexpected error in server.{}\", ExceptionUtils.getExceptionMessageWithoutTrace(e));\n        }\n        httpServerExceptionHandlers.forEach(httpServerExceptionHandler -> httpServerExceptionHandler.handle(e));\n      });\n      startListen(httpServer, startPromise);\n    } catch (Throwable e) {\n      // vert.x got some states that not print error and execute call back in VertexUtils.blockDeploy, we add a log our self.\n      LOGGER.error(\"\", e);\n      throw e;\n    }\n  }\n\n  @VisibleForTesting\n  void mountGlobalRestFailureHandler(Router mainRouter) {\n    GlobalRestFailureHandler globalRestFailureHandler =\n        SPIServiceUtils.getPriorityHighestService(GlobalRestFailureHandler.class);\n    Handler<RoutingContext> failureHandler = null == globalRestFailureHandler ?\n        ctx -> {\n          if (ctx.response().closed() || ctx.response().ended()) {\n            // response has been sent, do nothing\n            LOGGER.error(\"get a failure with closed response\", ctx.failure());\n            return;\n          }\n          HttpServerResponse response = ctx.response();\n          if (ctx.failure() instanceof InvocationException exception) {\n            // ServiceComb defined exception\n            response.setStatusCode(exception.getStatusCode());\n            response.setStatusMessage(exception.getReasonPhrase());\n            response.end(exception.getErrorData().toString());\n            return;\n          }\n\n          LOGGER.error(\"unexpected failure happened\", ctx.failure());\n          try {\n            // unknown exception\n            CommonExceptionData unknownError = new CommonExceptionData(\"unknown error\");\n            ctx.response().setStatusCode(500).putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)\n                .end(RestObjectMapperFactory.getRestObjectMapper().writeValueAsString(unknownError));\n          } catch (Exception e) {\n            LOGGER.error(\"failed to send error response!\", e);\n          }\n        }\n        : globalRestFailureHandler;\n\n    mainRouter.route()\n        // this handler does nothing, just ensure the failure handler can catch exception\n        .handler(RoutingContext::next)\n        .failureHandler(failureHandler);\n  }\n\n  private void mountAccessLogHandler(Router mainRouter) {\n    if (!AccessLogConfig.INSTANCE.isServerLogEnabled()) {\n      return;\n    }\n    LOGGER.info(\"access log enabled, pattern = {}\", AccessLogConfig.INSTANCE.getServerLogPattern());\n    mainRouter.route().handler(context -> {\n      ServerAccessLogEvent accessLogEvent = new ServerAccessLogEvent()\n          .setRoutingContext(context)\n          .setMilliStartTime(System.currentTimeMillis())\n          .setLocalAddress(LocalHostAccessItem.getLocalAddress(context));\n      context.response().endHandler(event ->\n          EventManager.post(accessLogEvent.setMilliEndTime(System.currentTimeMillis())));\n      context.next();\n    });\n  }\n\n  /**\n   * Support CORS\n   */\n  void mountCorsHandler(Router mainRouter) {\n    if (!TransportConfig.isCorsEnabled()) {\n      return;\n    }\n\n    CorsHandler corsHandler = getCorsHandler();\n    // Access-Control-Allow-Credentials\n    corsHandler.allowCredentials(TransportConfig.isCorsAllowCredentials());\n    // Access-Control-Allow-Headers\n    corsHandler.allowedHeaders(TransportConfig.getCorsAllowedHeaders());\n    // Access-Control-Allow-Methods\n    Set<String> allowedMethods = TransportConfig.getCorsAllowedMethods();\n    for (String method : allowedMethods) {\n      corsHandler.allowedMethod(HttpMethod.valueOf(method));\n    }\n    // Access-Control-Expose-Headers\n    corsHandler.exposedHeaders(TransportConfig.getCorsExposedHeaders());\n    // Access-Control-Max-Age\n    int maxAge = TransportConfig.getCorsMaxAge();\n    if (maxAge >= 0) {\n      corsHandler.maxAgeSeconds(maxAge);\n    }\n\n    LOGGER.info(\"mount CorsHandler\");\n    mainRouter.route().handler(corsHandler);\n  }\n\n  private CorsHandler getCorsHandler() {\n    CorsHandler handler = CorsHandler.create();\n    String[] origin = TransportConfig.getCorsAllowedOrigin();\n    if (origin == null) {\n      handler.addOrigin(\"*\");\n    } else {\n      for (String item : origin) {\n        handler.addOrigin(item);\n      }\n    }\n    return handler;\n  }\n\n  private void initDispatcher(Router mainRouter) {\n    List<VertxHttpDispatcher> dispatchers = SPIServiceUtils.getOrLoadSortedService(VertxHttpDispatcher.class);\n\n    for (VertxHttpDispatcher dispatcher : dispatchers) {\n      if (dispatcher.enabled()) {\n        dispatcher.init(mainRouter);\n      }\n    }\n  }\n\n  private void startListen(HttpServer server, Promise<Void> startPromise) {\n    Future<HttpServer> result = server.listen(endpointObject.getPort(), endpointObject.getHostOrIp());\n    result.onComplete((s, f) -> {\n      if (f == null) {\n        LOGGER.info(\"rest listen success. address={}:{}\",\n            endpointObject.getHostOrIp(),\n            s.actualPort());\n        startPromise.complete();\n        return;\n      }\n\n      String msg = String.format(\"rest listen failed, address=%s:%d\",\n          endpointObject.getHostOrIp(),\n          endpointObject.getPort());\n      LOGGER.error(msg, f);\n      startPromise.fail(f);\n    });\n  }\n\n  private HttpServer createHttpServer() {\n    HttpServerOptions serverOptions = createDefaultHttpServerOptions();\n    return vertx.createHttpServer(serverOptions);\n  }\n\n  private HttpServerOptions createDefaultHttpServerOptions() {\n    HttpServerOptions serverOptions = new HttpServerOptions();\n    serverOptions.setCompressionSupported(TransportConfig.getCompressed());\n    serverOptions.setMaxHeaderSize(TransportConfig.getMaxHeaderSize());\n    serverOptions.setMaxFormAttributeSize(TransportConfig.getMaxFormAttributeSize());\n    serverOptions.setMaxFormFields(TransportConfig.getMaxFormFields());\n    serverOptions.setMaxFormBufferedBytes(TransportConfig.getMaxFormBufferedBytes());\n    serverOptions.setCompressionLevel(TransportConfig.getCompressionLevel());\n    serverOptions.setMaxChunkSize(TransportConfig.getMaxChunkSize());\n    serverOptions.setDecompressionSupported(TransportConfig.getDecompressionSupported());\n    serverOptions.setDecoderInitialBufferSize(TransportConfig.getDecoderInitialBufferSize());\n    serverOptions.setMaxInitialLineLength(TransportConfig.getMaxInitialLineLength());\n    if (endpointObject.isHttp2Enabled()) {\n      serverOptions.setUseAlpn(TransportConfig.getUseAlpn())\n          .setHttp2ConnectionWindowSize(TransportConfig.getHttp2ConnectionWindowSize())\n          .setIdleTimeout(TransportConfig.getHttp2ConnectionIdleTimeoutInSeconds())\n          .setHttp2RstFloodMaxRstFramePerWindow(TransportConfig.getHttp2RstFloodMaxRstFramePerWindow())\n          .setInitialSettings(new Http2Settings().setPushEnabled(TransportConfig.getPushEnabled())\n              .setMaxConcurrentStreams(TransportConfig.getMaxConcurrentStreams())\n              .setHeaderTableSize(TransportConfig.getHttp2HeaderTableSize())\n              .setInitialWindowSize(TransportConfig.getInitialWindowSize())\n              .setMaxFrameSize(TransportConfig.getMaxFrameSize())\n              .setMaxHeaderListSize(TransportConfig.getMaxHeaderListSize())\n          );\n    } else {\n      serverOptions.setIdleTimeout(TransportConfig.getConnectionIdleTimeoutInSeconds());\n    }\n    if (endpointObject.isSslEnabled()) {\n      SSLOptionFactory factory =\n          SSLOptionFactory.createSSLOptionFactory(SSL_KEY, LegacyPropertyFactory.getEnvironment());\n      SSLOption sslOption;\n      if (factory == null) {\n        sslOption = SSLOption.build(SSL_KEY, LegacyPropertyFactory.getEnvironment());\n      } else {\n        sslOption = factory.createSSLOption();\n      }\n      SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass());\n      VertxTLSBuilder.buildNetServerOptions(sslOption, sslCustom, serverOptions);\n    }\n\n    return serverOptions;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/TransportConfig.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.stream.Stream;\n\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.transport.common.TransportConfigUtils;\n\nimport io.vertx.core.Verticle;\nimport io.vertx.core.http.Http2Settings;\nimport io.vertx.core.http.HttpServerOptions;\n\npublic final class TransportConfig {\n  public static final int DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND = 180;\n\n  public static final boolean DEFAULT_SERVER_COMPRESSION_SUPPORT = false;\n\n  // 32K\n  public static final int DEFAULT_SERVER_MAX_HEADER_SIZE = 32 * 1024;\n\n  public static final String SERVICECOMB_CORS_CONFIG_BASE = \"servicecomb.cors\";\n\n  private static Class<? extends Verticle> restServerVerticle = RestServerVerticle.class;\n\n  private TransportConfig() {\n  }\n\n  public static Class<? extends Verticle> getRestServerVerticle() {\n    return restServerVerticle;\n  }\n\n  public static void setRestServerVerticle(Class<? extends Verticle> restServerVerticle) {\n    TransportConfig.restServerVerticle = restServerVerticle;\n  }\n\n  public static String getAddress() {\n    return LegacyPropertyFactory.getStringProperty(\"servicecomb.rest.address\", null);\n  }\n\n  public static int getMaxFormAttributeSize() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.server.maxFormAttributeSize\",\n        HttpServerOptions.DEFAULT_MAX_FORM_ATTRIBUTE_SIZE);\n  }\n\n  public static int getMaxFormFields() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.server.maxFormFields\",\n        HttpServerOptions.DEFAULT_MAX_FORM_FIELDS);\n  }\n\n  public static int getMaxFormBufferedBytes() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.server.maxFormBufferedBytes\",\n        HttpServerOptions.DEFAULT_MAX_FORM_BUFFERED_SIZE);\n  }\n\n  public static int getCompressionLevel() {\n    return LegacyPropertyFactory.getIntProperty(\"servicecomb.rest.server.compressionLevel\",\n        HttpServerOptions.DEFAULT_COMPRESSION_LEVEL);\n  }\n\n  public static int getMaxChunkSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.maxChunkSize\",\n            HttpServerOptions.DEFAULT_MAX_CHUNK_SIZE);\n  }\n\n  public static int getDecoderInitialBufferSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.decoderInitialBufferSize\",\n            HttpServerOptions.DEFAULT_DECODER_INITIAL_BUFFER_SIZE);\n  }\n\n  public static int getHttp2ConnectionWindowSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.http2.connectionWindowSize\",\n            HttpServerOptions.DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE);\n  }\n\n  public static int getHttp2RstFloodMaxRstFramePerWindow() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.http2.rstFloodMaxRstFramePerWindow\",\n            HttpServerOptions.DEFAULT_HTTP2_RST_FLOOD_MAX_RST_FRAME_PER_WINDOW);\n  }\n\n  public static int getThreadCount() {\n    return TransportConfigUtils.readVerticleCount(\n        \"servicecomb.rest.server.verticle-count\",\n        \"servicecomb.rest.server.thread-count\");\n  }\n\n  public static int getConnectionIdleTimeoutInSeconds() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.connection.idleTimeoutInSeconds\",\n            DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND);\n  }\n\n  public static int getHttp2ConnectionIdleTimeoutInSeconds() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.http2.connection.idleTimeoutInSeconds\",\n            DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND);\n  }\n\n  public static boolean getCompressed() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.server.compression\", DEFAULT_SERVER_COMPRESSION_SUPPORT);\n  }\n\n  public static boolean getDecompressionSupported() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.server.decompressionSupported\",\n            HttpServerOptions.DEFAULT_DECOMPRESSION_SUPPORTED);\n  }\n\n  public static long getMaxConcurrentStreams() {\n    return LegacyPropertyFactory\n        .getLongProperty(\"servicecomb.rest.server.http2.concurrentStreams\",\n            HttpServerOptions.DEFAULT_INITIAL_SETTINGS_MAX_CONCURRENT_STREAMS);\n  }\n\n  public static long getHttp2HeaderTableSize() {\n    return LegacyPropertyFactory\n        .getLongProperty(\"servicecomb.rest.server.http2.HeaderTableSize\",\n            Http2Settings.DEFAULT_HEADER_TABLE_SIZE);\n  }\n\n  public static boolean getPushEnabled() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.server.http2.pushEnabled\",\n            Http2Settings.DEFAULT_ENABLE_PUSH);\n  }\n\n  public static int getInitialWindowSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.http2.initialWindowSize\",\n            Http2Settings.DEFAULT_INITIAL_WINDOW_SIZE);\n  }\n\n  public static int getMaxFrameSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.http2.maxFrameSize\",\n            Http2Settings.DEFAULT_MAX_FRAME_SIZE);\n  }\n\n  public static int getMaxHeaderListSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.http2.maxHeaderListSize\",\n            Http2Settings.DEFAULT_MAX_HEADER_LIST_SIZE);\n  }\n\n  public static boolean getUseAlpn() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(\"servicecomb.rest.server.http2.useAlpnEnabled\", true);\n  }\n\n  public static int getMaxHeaderSize() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.maxHeaderSize\", DEFAULT_SERVER_MAX_HEADER_SIZE);\n  }\n\n  public static boolean isCorsEnabled() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(SERVICECOMB_CORS_CONFIG_BASE + \".enabled\", false);\n  }\n\n  public static String[] getCorsAllowedOrigin() {\n    return LegacyPropertyFactory\n        .getProperty(SERVICECOMB_CORS_CONFIG_BASE + \".origin\", String[].class);\n  }\n\n  public static boolean isCorsAllowCredentials() {\n    return LegacyPropertyFactory\n        .getBooleanProperty(SERVICECOMB_CORS_CONFIG_BASE + \".allowCredentials\", false);\n  }\n\n  public static Set<String> getCorsAllowedHeaders() {\n    String allowedHeaders = LegacyPropertyFactory\n        .getStringProperty(SERVICECOMB_CORS_CONFIG_BASE + \".allowedHeader\");\n    return convertToSet(allowedHeaders);\n  }\n\n  public static Set<String> getCorsAllowedMethods() {\n    String allowedMethods = LegacyPropertyFactory\n        .getStringProperty(SERVICECOMB_CORS_CONFIG_BASE + \".allowedMethod\");\n    return convertToSet(allowedMethods);\n  }\n\n  public static Set<String> getCorsExposedHeaders() {\n    String exposedHeaders = LegacyPropertyFactory\n        .getStringProperty(SERVICECOMB_CORS_CONFIG_BASE + \".exposedHeader\");\n    return convertToSet(exposedHeaders);\n  }\n\n  public static int getCorsMaxAge() {\n    return LegacyPropertyFactory\n        .getIntProperty(SERVICECOMB_CORS_CONFIG_BASE + \".maxAge\", -1);\n  }\n\n  private static Set<String> convertToSet(String setString) {\n    Set<String> resultSet = new HashSet<>();\n    if (!StringUtils.isEmpty(setString)) {\n      String[] arrString = setString.split(\",\");\n      Stream.of(arrString).map(String::trim).filter(str -> !StringUtils.isEmpty(str))\n          .forEach(resultSet::add);\n    }\n    return resultSet;\n  }\n\n  public static int getMaxInitialLineLength() {\n    return LegacyPropertyFactory\n        .getIntProperty(\"servicecomb.rest.server.maxInitialLineLength\",\n            HttpServerOptions.DEFAULT_MAX_INITIAL_LINE_LENGTH);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxHttpDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.foundation.common.utils.SPIEnabled;\nimport org.apache.servicecomb.foundation.common.utils.SPIOrder;\n\nimport io.vertx.ext.web.Router;\n\npublic interface VertxHttpDispatcher extends SPIOrder, SPIEnabled {\n  @Override\n  default boolean enabled() {\n    return true;\n  }\n\n  void init(Router router);\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.common.rest.RestProducerInvocationFlow;\nimport org.apache.servicecomb.common.rest.RestVertxProducerInvocationCreator;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;\nimport org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest;\nimport org.apache.servicecomb.foundation.vertx.http.VertxServerResponseToHttpServletResponse;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException;\nimport io.vertx.core.json.JsonObject;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\nimport jakarta.ws.rs.core.HttpHeaders;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\nimport jakarta.ws.rs.core.Response.Status.Family;\n\npublic class VertxRestDispatcher extends AbstractVertxHttpDispatcher {\n  private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestDispatcher.class);\n\n  private static final String KEY_ORDER = \"servicecomb.http.dispatcher.rest.order\";\n\n  private static final String KEY_ENABLED = \"servicecomb.http.dispatcher.rest.enabled\";\n\n  public static final String KEY_PATTERN = \"servicecomb.http.dispatcher.rest.pattern\";\n\n  private Transport transport;\n\n  private MicroserviceMeta microserviceMeta;\n\n  @Override\n  public int getOrder() {\n    return LegacyPropertyFactory.getIntProperty(KEY_ORDER, Integer.MAX_VALUE);\n  }\n\n  @Override\n  public boolean enabled() {\n    return LegacyPropertyFactory.getBooleanProperty(KEY_ENABLED, true);\n  }\n\n  @Override\n  public void init(Router router) {\n    // cookies handler are enabled by default start from 3.8.3\n    String pattern = LegacyPropertyFactory.getStringProperty(KEY_PATTERN);\n    if (pattern == null) {\n      router.route().handler(createBodyHandler());\n      router.route().failureHandler(this::failureHandler).handler(this::onRequest);\n    } else {\n      router.routeWithRegex(pattern).handler(createBodyHandler());\n      router.routeWithRegex(pattern).failureHandler(this::failureHandler).handler(this::onRequest);\n    }\n  }\n\n  protected void failureHandler(RoutingContext context) {\n    LOGGER.error(\"http server failed.\", context.failure());\n\n    Throwable e = context.failure();\n    if (e instanceof ErrorDataDecoderException) {\n      Throwable cause = e.getCause();\n      if (cause instanceof InvocationException) {\n        e = cause;\n      }\n    }\n\n    // only when unexpected exception happens, it will run into here.\n    // the connection should be closed.\n    handleFailureAndClose(context, e);\n  }\n\n  /**\n   * Try to find out the failure information and send it in response.\n   */\n  private void handleFailureAndClose(RoutingContext context, Throwable e) {\n    if (null != e) {\n      // if there exists exception, try to send this exception by RoutingContext\n      sendExceptionByRoutingContext(context, e);\n      return;\n    }\n\n    // if there is no exception, the response is determined by status code.\n    sendFailureRespDeterminedByStatus(context);\n  }\n\n  /**\n   * Try to determine response by status code, and send response.\n   */\n  private void sendFailureRespDeterminedByStatus(RoutingContext context) {\n    Family statusFamily = Family.familyOf(context.statusCode());\n    if (Family.CLIENT_ERROR.equals(statusFamily) || Family.SERVER_ERROR.equals(statusFamily) || Family.OTHER\n        .equals(statusFamily)) {\n      context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)\n          .setStatusCode(context.statusCode()).end();\n    } else {\n      // it seems the status code is not set properly\n      context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)\n          .setStatusCode(Status.INTERNAL_SERVER_ERROR.getStatusCode())\n          .setStatusMessage(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())\n          .end(wrapResponseBody(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()));\n    }\n  }\n\n  /**\n   * Use routingContext to send failure information in throwable.\n   */\n  private void sendExceptionByRoutingContext(RoutingContext context, Throwable e) {\n    if (e instanceof InvocationException invocationException) {\n      context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)\n          .setStatusCode(invocationException.getStatusCode()).setStatusMessage(invocationException.getReasonPhrase())\n          .end(wrapResponseBody(invocationException.getReasonPhrase()));\n    } else {\n      context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD)\n          .setStatusCode(Status.INTERNAL_SERVER_ERROR.getStatusCode())\n          .end(wrapResponseBody(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()));\n    }\n  }\n\n  /**\n   * Consumer will treat the response body as json by default, so it's necessary to wrap response body as Json string\n   * to avoid deserialization error.\n   *\n   * @param message response body\n   * @return response body wrapped as Json string\n   */\n  String wrapResponseBody(String message) {\n    if (isValidJson(message)) {\n      return message;\n    }\n\n    JsonObject jsonObject = new JsonObject();\n    jsonObject.put(\"message\", message);\n\n    return jsonObject.toString();\n  }\n\n  /**\n   * Check if the message is a valid Json string.\n   * @param message the message to be checked.\n   * @return true if message is a valid Json string, otherwise false.\n   */\n  private boolean isValidJson(String message) {\n    try {\n      new JsonObject(message);\n    } catch (Exception ignored) {\n      return false;\n    }\n    return true;\n  }\n\n  protected void onRequest(RoutingContext context) {\n    if (transport == null) {\n      transport = SCBEngine.getInstance().getTransportManager().findTransport(CoreConst.RESTFUL);\n      microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();\n    }\n    HttpServletRequestEx requestEx = new VertxServerRequestToHttpServletRequest(context);\n    HttpServletResponseEx responseEx = new VertxServerResponseToHttpServletResponse(context.response());\n\n    InvocationCreator creator = new RestVertxProducerInvocationCreator(context,\n        microserviceMeta, transport.getEndpoint(),\n        requestEx, responseEx);\n    new RestProducerInvocationFlow(creator, requestEx, responseEx)\n        .run();\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.common.net.NetUtils;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.common.utils.BeanUtils;\nimport org.apache.servicecomb.foundation.common.utils.ClassLoaderScopeContext;\nimport org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;\nimport org.apache.servicecomb.foundation.vertx.SimpleJsonObject;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.registry.definition.DefinitionConst;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.VertxOptions;\n\npublic class VertxRestTransport extends AbstractTransport {\n  private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestTransport.class);\n\n  @Override\n  public String getName() {\n    return CoreConst.RESTFUL;\n  }\n\n  @Override\n  public int getOrder() {\n    return -1000;\n  }\n\n  @Override\n  public boolean canInit() {\n    String pattern = environment.getProperty(VertxRestDispatcher.KEY_PATTERN, String.class);\n    String urlPrefix = null;\n    if (pattern == null || pattern.length() <= 5) {\n      setListenAddressWithoutSchema(TransportConfig.getAddress());\n    } else {\n      // e.g.  \"/api/(.*)\" -> \"/api\"\n      urlPrefix = pattern.substring(0, pattern.length() - 5);\n      setListenAddressWithoutSchema(TransportConfig.getAddress(),\n          Collections.singletonMap(DefinitionConst.URL_PREFIX, urlPrefix));\n    }\n\n    URIEndpointObject ep = (URIEndpointObject) getEndpoint().getAddress();\n    if (ep == null) {\n      return true;\n    }\n\n    if (!NetUtils.canTcpListen(ep.getSocketAddress().getAddress(), ep.getPort())) {\n      LOGGER.warn(\n          \"Can not start VertxRestTransport, the port:{} may have been occupied. \"\n              + \"You can ignore this message if you are using a web container like tomcat.\",\n          ep.getPort());\n      return false;\n    }\n\n    if (urlPrefix != null) {\n      ClassLoaderScopeContext.setClassLoaderScopeProperty(DefinitionConst.URL_PREFIX, urlPrefix);\n    }\n\n    return true;\n  }\n\n  @Override\n  public boolean init() throws Exception {\n    // 部署transport server\n    DeploymentOptions options = new DeploymentOptions().setInstances(TransportConfig.getThreadCount());\n    SimpleJsonObject json = new SimpleJsonObject();\n    json.put(ENDPOINT_KEY, getEndpoint());\n    options.setConfig(json);\n    options.setWorkerPoolName(\"pool-worker-transport-rest\");\n    options.setWorkerPoolSize(VertxOptions.DEFAULT_WORKER_POOL_SIZE);\n\n    prepareBlockResource();\n    Map<String, Object> result = VertxUtils.blockDeploy(transportVertx, TransportConfig.getRestServerVerticle(),\n        options);\n    if ((boolean) result.get(\"code\")) {\n      return true;\n    } else {\n      throw new IllegalStateException((String) result.get(\"message\"));\n    }\n  }\n\n  private void prepareBlockResource() {\n    // block deploy will load resources in event loop, but beans auto wire can only be done in main thread\n    List<VertxHttpDispatcher> dispatchers = SPIServiceUtils.getOrLoadSortedService(VertxHttpDispatcher.class);\n    BeanUtils.addBeans(VertxHttpDispatcher.class, dispatchers);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/WebSocketDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.common.rest.EdgeServerWebSocketInvocationCreator;\nimport org.apache.servicecomb.common.rest.ProviderServerWebSocketInvocationCreator;\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationItem;\nimport org.apache.servicecomb.common.rest.route.URLMappedConfigurationLoader;\nimport org.apache.servicecomb.common.rest.route.Utils;\nimport org.apache.servicecomb.config.ConfigurationChangedEvent;\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.definition.MicroserviceMeta;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.event.EventManager;\nimport org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\n\nimport com.google.common.eventbus.Subscribe;\n\nimport io.vertx.core.http.ServerWebSocket;\nimport jakarta.ws.rs.core.Response.Status;\n\npublic class WebSocketDispatcher {\n  private static final String KEY_MAPPING_PREFIX = \"servicecomb.http.dispatcher.edge.websocket.mappings\";\n\n  private final Object LOCK = new Object();\n\n  private volatile boolean initialized = false;\n\n  private Endpoint endpoint;\n\n  private MicroserviceMeta microserviceMeta;\n\n  private boolean isEdge;\n\n  private Map<String, URLMappedConfigurationItem> configurations = new HashMap<>();\n\n  public WebSocketDispatcher(Endpoint endpoint) {\n    this.endpoint = endpoint;\n    EventManager.register(this);\n  }\n\n  private void loadConfigurations() {\n    configurations = URLMappedConfigurationLoader.loadConfigurations(\n        LegacyPropertyFactory.getEnvironment(), KEY_MAPPING_PREFIX);\n  }\n\n  @Subscribe\n  public void onConfigurationChangedEvent(ConfigurationChangedEvent event) {\n    for (String changed : event.getChanged()) {\n      if (changed.startsWith(KEY_MAPPING_PREFIX)) {\n        loadConfigurations();\n        break;\n      }\n    }\n  }\n\n  protected void onRequest(ServerWebSocket webSocket) {\n    if (!initialized) {\n      synchronized (LOCK) {\n        if (!initialized) {\n          Transport transport = SCBEngine.getInstance().getTransportManager().findTransport(CoreConst.WEBSOCKET);\n          this.microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();\n          this.endpoint = new Endpoint(transport, this.endpoint.getEndpoint());\n          this.isEdge = TransportConfig.getRestServerVerticle()\n              .getName().equals(\"org.apache.servicecomb.edge.core.EdgeRestServerVerticle\");\n          if (this.isEdge) {\n            loadConfigurations();\n          }\n        }\n        initialized = true;\n      }\n    }\n\n    InvocationCreator creator;\n    if (isEdge) {\n      URLMappedConfigurationItem configurationItem = findConfigurationItem(webSocket.path());\n      if (configurationItem == null) {\n        throw new InvocationException(Status.NOT_FOUND, new CommonExceptionData(\n            String.format(\"path %s not found\", webSocket.path())));\n      }\n      String path = Utils.findActualPath(webSocket.path(), configurationItem.getPrefixSegmentCount());\n      creator = new EdgeServerWebSocketInvocationCreator(\n          configurationItem.getMicroserviceName(), path, endpoint, webSocket);\n    } else {\n      creator = new ProviderServerWebSocketInvocationCreator(microserviceMeta,\n          endpoint, webSocket);\n    }\n    new WebSocketProducerInvocationFlow(creator, webSocket).run();\n  }\n\n  private URLMappedConfigurationItem findConfigurationItem(String path) {\n    for (URLMappedConfigurationItem item : configurations.values()) {\n      if (item.getPattern().matcher(path).matches()) {\n        return item;\n      }\n    }\n    return null;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/WebSocketProducerInvocationFlow.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.core.Invocation;\nimport org.apache.servicecomb.core.invocation.InvocationCreator;\nimport org.apache.servicecomb.core.invocation.ProducerInvocationFlow;\nimport org.apache.servicecomb.swagger.invocation.Response;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport io.vertx.core.http.ServerWebSocket;\n\npublic class WebSocketProducerInvocationFlow extends ProducerInvocationFlow {\n  private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketProducerInvocationFlow.class);\n\n  private final ServerWebSocket websocket;\n\n  public WebSocketProducerInvocationFlow(InvocationCreator invocationCreator, ServerWebSocket webSocket) {\n    super(invocationCreator);\n    this.websocket = webSocket;\n  }\n\n  @Override\n  protected Invocation sendCreateInvocationException(Throwable throwable) {\n    LOGGER.error(\"Web socket create invocation error.\", throwable);\n    websocket.writeTextMessage(\"Web socket create invocation error \" + throwable.getMessage());\n    websocket.close();\n    return null;\n  }\n\n  @Override\n  protected void endResponse(Invocation invocation, Response response) {\n\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/WebSocketTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.core.CoreConst;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\n\npublic class WebSocketTransport extends AbstractTransport {\n  @Override\n  public String getName() {\n    return CoreConst.WEBSOCKET;\n  }\n\n  @Override\n  public int getOrder() {\n    return -500;\n  }\n\n  @Override\n  public boolean init() throws Exception {\n    return true;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.transport.rest.vertx.VertxRestTransport\norg.apache.servicecomb.transport.rest.vertx.WebSocketTransport\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.VertxHttpDispatcher",
    "content": "#\n# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\norg.apache.servicecomb.transport.rest.vertx.VertxRestDispatcher\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/MockForRestServerVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.foundation.common.net.IpPort;\nimport org.mockito.Mockito;\n\nimport io.vertx.core.Future;\nimport io.vertx.core.http.HttpServer;\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class MockForRestServerVerticle {\n\n  private static final MockForRestServerVerticle instance = new MockForRestServerVerticle();\n\n  private MockForRestServerVerticle() {\n    // private constructor for Singleton\n  }\n\n  public static MockForRestServerVerticle getInstance() {\n    return instance;\n  }\n\n  public void mockRestServerVerticle() {\n    final HttpServer server = Mockito.mock(HttpServer.class);\n    new MockUp<RestServerVerticle>() {\n\n      @Mock\n      private void startListen(HttpServer server, IpPort ipPort, Future<Void> startFuture) {\n\n      }\n\n      @Mock\n      private HttpServer createHttpServer(boolean isHttp_2) {\n\n        return server;\n      }\n    };\n  }\n\n  public void mockTransportConfig() {\n    new MockUp<TransportConfig>() {\n      @Mock\n      public String getAddress() {\n        return \"Address\";\n      }\n    };\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/MockHttpServerResponse.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileChannel;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Set;\n\nimport io.vertx.codegen.annotations.Nullable;\nimport io.vertx.core.Future;\nimport io.vertx.core.Handler;\nimport io.vertx.core.MultiMap;\nimport io.vertx.core.buffer.Buffer;\nimport io.vertx.core.http.Cookie;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.core.net.HostAndPort;\n\nclass MockHttpServerResponse implements HttpServerResponse {\n  boolean responseEnded;\n\n  Map<String, String> responseHeader = new HashMap<>(1);\n\n  int responseStatusCode;\n\n  String responseStatusMessage;\n\n  String responseChunk;\n\n  @Override\n  public HttpServerResponse putHeader(String name, String value) {\n    responseHeader.put(name, value);\n    return this;\n  }\n\n  @Override\n  public HttpServerResponse setStatusCode(int statusCode) {\n    responseStatusCode = statusCode;\n    return this;\n  }\n\n  @Override\n  public HttpServerResponse setStatusMessage(String statusMessage) {\n    responseStatusMessage = statusMessage;\n    return this;\n  }\n\n  @Override\n  public Future<Void> end() {\n    responseEnded = true;\n    return Future.succeededFuture();\n  }\n\n  @Override\n  public Future<Void> end(String chunk) {\n    responseEnded = true;\n    responseChunk = chunk;\n    return Future.succeededFuture();\n  }\n\n  @Override\n  public HttpServerResponse exceptionHandler(Handler<Throwable> handler) {\n    return null;\n  }\n\n  @Override\n  public Future<Void> write(Buffer data) {\n    return Future.succeededFuture();\n  }\n\n  @Override\n  public HttpServerResponse setWriteQueueMaxSize(int maxSize) {\n    return null;\n  }\n\n  @Override\n  public boolean writeQueueFull() {\n    return false;\n  }\n\n  @Override\n  public HttpServerResponse drainHandler(Handler<Void> handler) {\n    return null;\n  }\n\n  @Override\n  public int getStatusCode() {\n    return 0;\n  }\n\n  @Override\n  public String getStatusMessage() {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse setChunked(boolean chunked) {\n    return null;\n  }\n\n  @Override\n  public boolean isChunked() {\n    return false;\n  }\n\n  @Override\n  public MultiMap headers() {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putHeader(CharSequence name, CharSequence value) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putHeader(String name, Iterable<String> values) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putHeader(CharSequence name, Iterable<CharSequence> values) {\n    return null;\n  }\n\n  @Override\n  public MultiMap trailers() {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putTrailer(String name, String value) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putTrailer(CharSequence name, CharSequence value) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putTrailer(String name, Iterable<String> values) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse putTrailer(CharSequence name, Iterable<CharSequence> value) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse closeHandler(Handler<Void> handler) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse endHandler(Handler<Void> handler) {\n    return null;\n  }\n\n  @Override\n  public Future<Void> writeHead() {\n    return null;\n  }\n\n  @Override\n  public Future<Void> write(String chunk, String enc) {\n    return Future.succeededFuture();\n  }\n\n\n  @Override\n  public Future<Void> write(String chunk) {\n    return Future.succeededFuture();\n  }\n\n  @Override\n  public Future<Void> writeContinue() {\n    return null;\n  }\n\n  @Override\n  public Future<Void> writeEarlyHints(MultiMap headers) {\n    return Future.succeededFuture();\n  }\n\n  @Override\n  public Future<Void> end(String chunk, String enc) {\n    return Future.succeededFuture();\n  }\n\n\n  @Override\n  public Future<Void> end(Buffer chunk) {\n    return Future.succeededFuture();\n  }\n\n\n  @Override\n  public Future<Void> sendFile(String filename, long offset, long length) {\n    return Future.succeededFuture();\n  }\n\n  @Override\n  public Future<Void> sendFile(FileChannel channel, long offset, long length) {\n    return null;\n  }\n\n  @Override\n  public Future<Void> sendFile(RandomAccessFile file, long offset, long length) {\n    return null;\n  }\n\n  @Override\n  public boolean ended() {\n    return false;\n  }\n\n  @Override\n  public boolean closed() {\n    return false;\n  }\n\n  @Override\n  public boolean headWritten() {\n    return false;\n  }\n\n  @Override\n  public HttpServerResponse headersEndHandler(Handler<Void> handler) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse bodyEndHandler(Handler<Void> handler) {\n    return null;\n  }\n\n  @Override\n  public long bytesWritten() {\n    return 0;\n  }\n\n  @Override\n  public int streamId() {\n    return 0;\n  }\n\n  @Override\n  public Future<HttpServerResponse> push(HttpMethod httpMethod, HostAndPort hostAndPort, String s, MultiMap multiMap) {\n    return null;\n  }\n\n  @Override\n  public Future<Void> reset(long code) {\n    return null;\n  }\n\n  @Override\n  public Future<Void> writeCustomFrame(int type, int flags, Buffer payload) {\n    return null;\n  }\n\n  @Override\n  public HttpServerResponse addCookie(Cookie cookie) {\n    return null;\n  }\n\n  @Override\n  public @Nullable Cookie removeCookie(String name, boolean invalidate) {\n    return null;\n  }\n\n  @Override\n  public Set<Cookie> removeCookies(String name, boolean invalidate) {\n    return null;\n  }\n\n  @Override\n  public @Nullable Cookie removeCookie(String name, String domain, String path, boolean invalidate) {\n    return null;\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestAbstractVertxHttpDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.junit.Before;\nimport org.junit.FixMethodOrder;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.junit.runners.MethodSorters;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.ext.web.Router;\nimport mockit.Deencapsulation;\n\n@FixMethodOrder(MethodSorters.NAME_ASCENDING)\npublic class TestAbstractVertxHttpDispatcher {\n  static class AbstractVertxHttpDispatcherForTest extends AbstractVertxHttpDispatcher {\n    @Override\n    public int getOrder() {\n      return 0;\n    }\n\n    @Override\n    public void init(Router router) {\n    }\n  }\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\n            RestConst.UPLOAD_MAX_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_MAX_FILE_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_FILE_SIZE_THRESHOLD, int.class, 0))\n        .thenReturn(0);\n  }\n\n  @Test\n  public void createBodyHandlerUploadDefault() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.uploads.directory\", RestConst.UPLOAD_DEFAULT_DIR))\n        .thenReturn(RestConst.UPLOAD_DEFAULT_DIR);\n\n    AbstractVertxHttpDispatcher dispatcher = new AbstractVertxHttpDispatcherForTest();\n    RestBodyHandler bodyHandler = (RestBodyHandler) dispatcher.createBodyHandler();\n\n    Assertions.assertTrue(bodyHandler.isDeleteUploadedFilesOnEnd());\n    Assertions.assertEquals(RestConst.UPLOAD_DEFAULT_DIR, Deencapsulation.getField(bodyHandler, \"uploadsDir\"));\n  }\n\n  @Test\n  public void createBodyHandlerUploadNormal() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.uploads.directory\", RestConst.UPLOAD_DEFAULT_DIR))\n        .thenReturn(\"/path\");\n\n    AbstractVertxHttpDispatcher dispatcher = new AbstractVertxHttpDispatcherForTest();\n    RestBodyHandler bodyHandler = (RestBodyHandler) dispatcher.createBodyHandler();\n\n    Assertions.assertTrue(bodyHandler.isDeleteUploadedFilesOnEnd());\n    Assertions.assertEquals(\"/path\", Deencapsulation.getField(bodyHandler, \"uploadsDir\"));\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestRestServerVerticle.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_COMPRESSION_LEVEL;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_DECODER_INITIAL_BUFFER_SIZE;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_DECOMPRESSION_SUPPORTED;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_MAX_CHUNK_SIZE;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_MAX_FORM_ATTRIBUTE_SIZE;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_MAX_FORM_BUFFERED_SIZE;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_MAX_FORM_FIELDS;\nimport static io.vertx.core.http.HttpServerOptions.DEFAULT_MAX_INITIAL_LINE_LENGTH;\nimport static org.apache.servicecomb.common.accessLog.AccessLogConfig.CLIENT_LOG_ENABLED;\nimport static org.apache.servicecomb.common.accessLog.AccessLogConfig.CLIENT_LOG_PATTERN;\nimport static org.apache.servicecomb.common.accessLog.AccessLogConfig.DEFAULT_CLIENT_PATTERN;\nimport static org.apache.servicecomb.common.accessLog.AccessLogConfig.DEFAULT_SERVER_PATTERN;\nimport static org.apache.servicecomb.common.accessLog.AccessLogConfig.SERVER_LOG_ENABLED;\nimport static org.apache.servicecomb.common.accessLog.AccessLogConfig.SERVER_LOG_PATTERN;\nimport static org.apache.servicecomb.core.transport.AbstractTransport.PUBLISH_ADDRESS;\nimport static org.apache.servicecomb.transport.rest.vertx.TransportConfig.DEFAULT_SERVER_COMPRESSION_SUPPORT;\nimport static org.apache.servicecomb.transport.rest.vertx.TransportConfig.DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND;\nimport static org.apache.servicecomb.transport.rest.vertx.TransportConfig.DEFAULT_SERVER_MAX_HEADER_SIZE;\nimport static org.apache.servicecomb.transport.rest.vertx.TransportConfig.SERVICECOMB_CORS_CONFIG_BASE;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.Endpoint;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.Transport;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.transport.AbstractTransport;\nimport org.apache.servicecomb.foundation.common.Holder;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.common.net.URIEndpointObject;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.Context;\nimport io.vertx.core.Handler;\nimport io.vertx.core.Promise;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.http.Http2Settings;\nimport io.vertx.core.http.HttpMethod;\nimport io.vertx.core.http.HttpServerResponse;\nimport io.vertx.core.impl.SysProps;\nimport io.vertx.core.json.JsonObject;\nimport io.vertx.ext.web.Route;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\nimport io.vertx.ext.web.handler.CorsHandler;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\nimport mockit.Mocked;\n\npublic class TestRestServerVerticle {\n\n  private RestServerVerticle instance = null;\n\n  Promise<Void> startPromise = null;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.request.timeout\", long.class, (long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT))\n        .thenReturn((long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.client.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.client.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.rest.order\", int.class, Integer.MAX_VALUE))\n        .thenReturn(Integer.MAX_VALUE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.publishPort\", int.class, 0))\n        .thenReturn(0);\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.rest.enabled\", boolean.class, true))\n        .thenReturn(true);\n    Mockito.when(environment.getProperty(SERVICECOMB_CORS_CONFIG_BASE + \".enabled\", boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(PUBLISH_ADDRESS, \"\"))\n        .thenReturn(\"\");\n    Mockito.when(environment.getProperty(\n            RestConst.UPLOAD_MAX_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_MAX_FILE_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_FILE_SIZE_THRESHOLD, int.class, 0))\n        .thenReturn(0);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.compression\", boolean.class,\n            DEFAULT_SERVER_COMPRESSION_SUPPORT))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.maxHeaderSize\", int.class,\n            DEFAULT_SERVER_MAX_HEADER_SIZE))\n        .thenReturn(DEFAULT_SERVER_MAX_HEADER_SIZE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.maxFormAttributeSize\", int.class,\n            DEFAULT_MAX_FORM_ATTRIBUTE_SIZE))\n        .thenReturn(DEFAULT_MAX_FORM_ATTRIBUTE_SIZE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.compressionLevel\", int.class,\n            DEFAULT_COMPRESSION_LEVEL))\n        .thenReturn(DEFAULT_COMPRESSION_LEVEL);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.maxFormFields\", int.class,\n            DEFAULT_MAX_FORM_FIELDS))\n        .thenReturn(DEFAULT_MAX_FORM_FIELDS);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.maxFormBufferedBytes\", int.class,\n            DEFAULT_MAX_FORM_BUFFERED_SIZE))\n        .thenReturn(DEFAULT_MAX_FORM_BUFFERED_SIZE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.maxChunkSize\", int.class,\n            DEFAULT_MAX_CHUNK_SIZE))\n        .thenReturn(DEFAULT_MAX_CHUNK_SIZE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.decompressionSupported\", boolean.class,\n            DEFAULT_DECOMPRESSION_SUPPORTED))\n        .thenReturn(DEFAULT_DECOMPRESSION_SUPPORTED);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.decoderInitialBufferSize\", int.class,\n            DEFAULT_DECODER_INITIAL_BUFFER_SIZE))\n        .thenReturn(DEFAULT_DECODER_INITIAL_BUFFER_SIZE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.maxInitialLineLength\", int.class,\n            DEFAULT_MAX_INITIAL_LINE_LENGTH))\n        .thenReturn(DEFAULT_MAX_INITIAL_LINE_LENGTH);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.connection.idleTimeoutInSeconds\", int.class,\n            DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND))\n        .thenReturn(DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.http2.useAlpnEnabled\", boolean.class,\n            true))\n        .thenReturn(true);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.http2ConnectionWindowSize\", int.class,\n            DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE))\n        .thenReturn(DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.http2.connection.idleTimeoutInSeconds\", int.class,\n            DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND))\n        .thenReturn(DEFAULT_SERVER_CONNECTION_IDLE_TIMEOUT_SECOND);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.http2.pushEnabled\", boolean.class,\n            Http2Settings.DEFAULT_ENABLE_PUSH))\n        .thenReturn(Http2Settings.DEFAULT_ENABLE_PUSH);\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    Mockito.when(environment.getProperty(CLIENT_LOG_ENABLED, boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(SERVER_LOG_ENABLED, boolean.class, false))\n        .thenReturn(false);\n    Mockito.when(environment.getProperty(CLIENT_LOG_PATTERN, String.class, DEFAULT_CLIENT_PATTERN))\n        .thenReturn(DEFAULT_CLIENT_PATTERN);\n    Mockito.when(environment.getProperty(SERVER_LOG_PATTERN, String.class, DEFAULT_SERVER_PATTERN))\n        .thenReturn(DEFAULT_CLIENT_PATTERN);\n    LegacyPropertyFactory.setEnvironment(environment);\n\n    instance = new RestServerVerticle();\n    startPromise = Promise.promise();\n\n    SCBBootstrap.createSCBEngineForTest(environment);\n  }\n\n  @After\n  public void tearDown() {\n    instance = null;\n    startPromise = null;\n    SCBEngine.getInstance().destroy();\n  }\n\n  @Test\n  public void testRestServerVerticleWithRouter(@Mocked Transport transport, @Mocked Vertx vertx,\n      @Mocked Context context,\n      @Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) throws Exception {\n\n    URIEndpointObject endpointObject = new URIEndpointObject(\"http://127.0.0.1:8080\");\n    new Expectations() {\n      {\n        transport.parseAddress(\"http://127.0.0.1:8080\");\n        result = endpointObject;\n      }\n    };\n    Endpoint endpoint = new Endpoint(transport, \"http://127.0.0.1:8080\");\n\n    new Expectations() {\n      {\n        context.config();\n        result = jsonObject;\n        jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);\n        result = endpoint;\n      }\n    };\n    RestServerVerticle server = new RestServerVerticle();\n    // process stuff done by Expectations\n    server.init(vertx, context);\n    server.start(startPromise);\n  }\n\n  @Test\n  public void testRestServerVerticleWithRouterSSL(@Mocked Transport transport, @Mocked Vertx vertx,\n      @Mocked Context context,\n      @Mocked JsonObject jsonObject, @Mocked Promise<Void> startPromise) throws Exception {\n    URIEndpointObject endpointObject = new URIEndpointObject(\"http://127.0.0.1:8080?sslEnabled=true\");\n    new Expectations() {\n      {\n        transport.parseAddress(\"http://127.0.0.1:8080?sslEnabled=true\");\n        result = endpointObject;\n      }\n    };\n    Endpoint endpoint = new Endpoint(transport, \"http://127.0.0.1:8080?sslEnabled=true\");\n\n    new Expectations() {\n      {\n        context.config();\n        result = jsonObject;\n        jsonObject.getValue(AbstractTransport.ENDPOINT_KEY);\n        result = endpoint;\n      }\n    };\n    RestServerVerticle server = new RestServerVerticle();\n    // process stuff done by Expectations\n    server.init(vertx, context);\n    server.start(startPromise);\n  }\n\n\n  @Test\n  public void testStartFutureAddressEmpty() {\n    boolean status = false;\n    try {\n      instance.start(startPromise);\n    } catch (Exception ex) {\n      status = true;\n    }\n    Assertions.assertFalse(status);\n  }\n\n  @Test\n  public void testStartFutureAddressNotEmpty() {\n    boolean status = false;\n    MockForRestServerVerticle.getInstance().mockTransportConfig();\n    MockForRestServerVerticle.getInstance().mockRestServerVerticle();\n    try {\n      instance.start(startPromise);\n    } catch (Exception ex) {\n      status = true;\n    }\n    Assertions.assertFalse(status);\n  }\n\n  @Test\n  public void testMountCorsHandler() {\n    Mockito.when(environment.getProperty(\"servicecomb.cors.enabled\", boolean.class,\n            false))\n        .thenReturn(true);\n    Mockito.when(environment.getProperty(\"servicecomb.cors.origin\",\n            String[].class))\n        .thenReturn(null);\n    Mockito.when(environment.getProperty(\"servicecomb.cors.allowedMethod\"))\n        .thenReturn(\"GET,PUT,POST\");\n    Mockito.when(environment.getProperty(\"servicecomb.cors.allowedHeader\"))\n        .thenReturn(\"abc,def\");\n    Mockito.when(environment.getProperty(\"servicecomb.cors.exposedHeader\"))\n        .thenReturn(\"abc2,def2\");\n    Mockito.when(environment.getProperty(\"servicecomb.cors.maxAge\", int.class, -1))\n        .thenReturn(1);\n    Mockito.when(environment.getProperty(\"servicecomb.cors.allowCredentials\", boolean.class, false))\n        .thenReturn(false);\n\n    Set<HttpMethod> methodSet = new HashSet<>(3);\n    methodSet.add(HttpMethod.GET);\n    methodSet.add(HttpMethod.PUT);\n    methodSet.add(HttpMethod.POST);\n    AtomicInteger counter = new AtomicInteger(0);\n\n    CorsHandler corsHandler = new MockUp<CorsHandler>() {\n      @Mock\n      CorsHandler allowCredentials(boolean allow) {\n        Assertions.assertFalse(allow);\n        counter.incrementAndGet();\n        return null;\n      }\n\n      @Mock\n      CorsHandler allowedHeaders(Set<String> headerNames) {\n        MatcherAssert.assertThat(headerNames, Matchers.containsInAnyOrder(\"abc\", \"def\"));\n        counter.incrementAndGet();\n        return null;\n      }\n\n      @Mock\n      CorsHandler exposedHeaders(Set<String> headerNames) {\n        MatcherAssert.assertThat(headerNames, Matchers.containsInAnyOrder(\"abc2\", \"def2\"));\n        counter.incrementAndGet();\n        return null;\n      }\n\n      @Mock\n      CorsHandler allowedMethod(HttpMethod method) {\n        Assertions.assertTrue(methodSet.contains(method));\n        counter.incrementAndGet();\n        methodSet.remove(method);\n        return null;\n      }\n\n      @Mock\n      CorsHandler maxAgeSeconds(int maxAgeSeconds) {\n        Assertions.assertEquals(1, maxAgeSeconds);\n        counter.incrementAndGet();\n        return null;\n      }\n    }.getMockInstance();\n\n    new MockUp<RestServerVerticle>() {\n      @Mock\n      CorsHandler getCorsHandler() {\n        return corsHandler;\n      }\n    };\n    Router router = Mockito.mock(Router.class);\n    Mockito.when(router.route()).thenReturn(Mockito.mock(Route.class));\n\n    RestServerVerticle server = new RestServerVerticle();\n\n    server.mountCorsHandler(router);\n    Assertions.assertEquals(7, counter.get());\n  }\n\n  @Test\n  public void mountGlobalRestFailureHandler() {\n    Router mainRouter = Mockito.mock(Router.class);\n    Holder<Handler<RoutingContext>> handlerHolder = new Holder<>();\n    Holder<Route> routeHolder = new Holder<>();\n    Route route = new MockUp<Route>() {\n      @Mock\n      Route failureHandler(Handler<RoutingContext> failureHandler) {\n        handlerHolder.value = failureHandler;\n        return null;\n      }\n\n      @Mock\n      Route handler(io.vertx.core.Handler<io.vertx.ext.web.RoutingContext> requestHandler) {\n        return routeHolder.value;\n      }\n    }.getMockInstance();\n    routeHolder.value = route;\n\n    Mockito.when(mainRouter.route()).thenReturn(route);\n\n    RestServerVerticle restServerVerticle = new RestServerVerticle();\n\n    restServerVerticle.mountGlobalRestFailureHandler(mainRouter);\n    Assertions.assertNotNull(handlerHolder.value);\n\n    RoutingContext routingContext = Mockito.mock(RoutingContext.class);\n    HttpServerResponse response = Mockito.mock(HttpServerResponse.class);\n    Mockito.when(response.setStatusCode(500)).thenReturn(response);\n    Mockito.when(response.putHeader(\"Content-Type\", \"application/json\")).thenReturn(response);\n    Mockito.when(routingContext.response()).thenReturn(response);\n\n    handlerHolder.value.handle(routingContext);\n    Mockito.verify(response).end(\"{\\\"message\\\":\\\"unknown error\\\"}\");\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestVertxRestDispatcher.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport org.apache.http.HttpHeaders;\nimport org.apache.servicecomb.common.rest.RestConst;\nimport org.apache.servicecomb.core.SCBEngine;\nimport org.apache.servicecomb.core.bootstrap.SCBBootstrap;\nimport org.apache.servicecomb.core.transport.TransportManager;\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.swagger.invocation.exception.InvocationException;\nimport org.hamcrest.MatcherAssert;\nimport org.hamcrest.Matchers;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException;\nimport io.vertx.core.json.JsonObject;\nimport io.vertx.ext.web.Router;\nimport io.vertx.ext.web.RoutingContext;\nimport jakarta.ws.rs.core.MediaType;\nimport jakarta.ws.rs.core.Response.Status;\nimport mockit.Mocked;\n\npublic class TestVertxRestDispatcher {\n  @Mocked\n  Router mainRouter;\n\n  @Mocked\n  TransportManager transportManager;\n\n  VertxRestDispatcher dispatcher;\n\n  Throwable throwable;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    LegacyPropertyFactory.setEnvironment(environment);\n    Mockito.when(environment.getProperty(\n            RestConst.UPLOAD_MAX_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_MAX_FILE_SIZE, long.class, -1L))\n        .thenReturn(-1L);\n    Mockito.when(environment.getProperty(RestConst.UPLOAD_FILE_SIZE_THRESHOLD, int.class, 0))\n        .thenReturn(0);\n\n    dispatcher = new VertxRestDispatcher();\n    dispatcher.init(mainRouter);\n\n    SCBBootstrap.createSCBEngineForTest(environment).setTransportManager(transportManager);\n  }\n\n  @After\n  public void teardown() {\n    SCBEngine.getInstance().destroy();\n  }\n\n  @Test\n  public void getOrder() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.http.dispatcher.rest.order\", int.class, Integer.MAX_VALUE))\n        .thenReturn(Integer.MAX_VALUE);\n    Assertions.assertEquals(Integer.MAX_VALUE, dispatcher.getOrder());\n  }\n\n  @Test\n  public void failureHandlerWithNoRestProducerInvocationAndInvocationException() {\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n    Mockito.when(context.get(RestConst.REST_PRODUCER_INVOCATION)).thenReturn(null);\n    InvocationException e = new InvocationException(Status.REQUEST_ENTITY_TOO_LARGE, \"testMsg\");\n    ErrorDataDecoderException edde = new ErrorDataDecoderException(e);\n    Mockito.when(context.failure()).thenReturn(edde);\n    MockHttpServerResponse response = new MockHttpServerResponse();\n    Mockito.when(context.response()).thenReturn(response);\n\n    dispatcher.failureHandler(context);\n\n    MatcherAssert.assertThat(response.responseHeader, Matchers.hasEntry(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD));\n    MatcherAssert.assertThat(response.responseStatusCode, Matchers.is(Status.REQUEST_ENTITY_TOO_LARGE.getStatusCode()));\n    MatcherAssert.assertThat(response.responseStatusMessage,\n        Matchers.is(Status.REQUEST_ENTITY_TOO_LARGE.getReasonPhrase()));\n    MatcherAssert.assertThat(response.responseChunk,\n        Matchers.is(\"{\\\"message\\\":\\\"\" + Status.REQUEST_ENTITY_TOO_LARGE.getReasonPhrase() + \"\\\"}\"));\n    Assertions.assertTrue(response.responseEnded);\n  }\n\n  @Test\n  public void failureHandlerWithNoRestProducerInvocationAndOtherException() {\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n    Mockito.when(context.get(RestConst.REST_PRODUCER_INVOCATION)).thenReturn(null);\n    String exceptionMessage = \"Internal Server Error\";\n    Exception exception = new Exception(exceptionMessage);\n    Mockito.when(context.failure()).thenReturn(exception);\n    MockHttpServerResponse response = new MockHttpServerResponse();\n    Mockito.when(context.response()).thenReturn(response);\n\n    dispatcher.failureHandler(context);\n\n    MatcherAssert.assertThat(response.responseHeader, Matchers.hasEntry(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD));\n    MatcherAssert.assertThat(response.responseStatusCode, Matchers.is(Status.INTERNAL_SERVER_ERROR.getStatusCode()));\n    MatcherAssert.assertThat(response.responseChunk,\n        Matchers.is(\"{\\\"message\\\":\\\"\" + exceptionMessage + \"\\\"}\"));\n    Assertions.assertTrue(response.responseEnded);\n  }\n\n  @Test\n  public void failureHandlerWithNoExceptionAndStatusCodeIsSet() {\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n    Mockito.when(context.get(RestConst.REST_PRODUCER_INVOCATION)).thenReturn(null);\n    Mockito.when(context.failure()).thenReturn(null);\n    MockHttpServerResponse response = new MockHttpServerResponse();\n    Mockito.when(context.response()).thenReturn(response);\n    Mockito.when(context.statusCode()).thenReturn(Status.REQUEST_ENTITY_TOO_LARGE.getStatusCode());\n\n    dispatcher.failureHandler(context);\n\n    MatcherAssert.assertThat(response.responseHeader, Matchers.hasEntry(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD));\n    MatcherAssert.assertThat(response.responseStatusCode, Matchers.is(Status.REQUEST_ENTITY_TOO_LARGE.getStatusCode()));\n    Assertions.assertTrue(response.responseEnded);\n  }\n\n  @Test\n  public void failureHandlerWithNoExceptionAndStatusCodeIsNotSet() {\n    RoutingContext context = Mockito.mock(RoutingContext.class);\n    Mockito.when(context.get(RestConst.REST_PRODUCER_INVOCATION)).thenReturn(null);\n    Mockito.when(context.failure()).thenReturn(null);\n    MockHttpServerResponse response = new MockHttpServerResponse();\n    Mockito.when(context.response()).thenReturn(response);\n    Mockito.when(context.statusCode()).thenReturn(Status.OK.getStatusCode());\n\n    dispatcher.failureHandler(context);\n\n    MatcherAssert.assertThat(response.responseHeader, Matchers.hasEntry(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD));\n    MatcherAssert.assertThat(response.responseStatusCode, Matchers.is(Status.INTERNAL_SERVER_ERROR.getStatusCode()));\n    MatcherAssert.assertThat(response.responseStatusMessage,\n        Matchers.is(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()));\n    MatcherAssert.assertThat(response.responseChunk,\n        Matchers.is(\"{\\\"message\\\":\\\"\" + Status.INTERNAL_SERVER_ERROR.getReasonPhrase() + \"\\\"}\"));\n    Assertions.assertTrue(response.responseEnded);\n  }\n\n  @Test\n  public void testWrapResponseBody() {\n    VertxRestDispatcher vertxRestDispatcher = new VertxRestDispatcher();\n    String message = \"abcd\";\n    String bodyString = vertxRestDispatcher.wrapResponseBody(message);\n    Assertions.assertNotNull(bodyString);\n    Assertions.assertEquals(\"{\\\"message\\\":\\\"abcd\\\"}\", bodyString);\n\n    message = \"\\\"abcd\\\"\";\n    bodyString = vertxRestDispatcher.wrapResponseBody(message);\n    Assertions.assertNotNull(bodyString);\n    Assertions.assertEquals(\"{\\\"message\\\":\\\"\\\\\\\"abcd\\\\\\\"\\\"}\", bodyString);\n\n    message = \".01ab\\\"!@#$%^&*()'\\\\cd\";\n    bodyString = vertxRestDispatcher.wrapResponseBody(message);\n    Assertions.assertNotNull(bodyString);\n    Assertions.assertEquals(\"{\\\"message\\\":\\\".01ab\\\\\\\"!@#$%^&*()'\\\\\\\\cd\\\"}\", bodyString);\n\n    message = new JsonObject().put(\"key\", new JsonObject().put(\"k2\", \"value\")).toString();\n    bodyString = vertxRestDispatcher.wrapResponseBody(message);\n    Assertions.assertNotNull(bodyString);\n    Assertions.assertEquals(\"{\\\"key\\\":{\\\"k2\\\":\\\"value\\\"}}\", bodyString);\n\n    message = \"ab\\\"23\\n@!#cd\";\n    bodyString = vertxRestDispatcher.wrapResponseBody(message);\n    Assertions.assertNotNull(bodyString);\n    Assertions.assertEquals(\"{\\\"message\\\":\\\"ab\\\\\\\"23\\\\n@!#cd\\\"}\", bodyString);\n\n    message = \"ab\\\"23\\r\\n@!#cd\";\n    bodyString = vertxRestDispatcher.wrapResponseBody(message);\n    Assertions.assertNotNull(bodyString);\n    Assertions.assertEquals(\"{\\\"message\\\":\\\"ab\\\\\\\"23\\\\r\\\\n@!#cd\\\"}\", bodyString);\n  }\n}\n"
  },
  {
    "path": "transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestVertxRestTransport.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.apache.servicecomb.transport.rest.vertx;\n\nimport static org.apache.servicecomb.core.transport.AbstractTransport.PUBLISH_ADDRESS;\n\nimport java.io.IOException;\nimport java.net.ServerSocket;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.apache.servicecomb.foundation.common.LegacyPropertyFactory;\nimport org.apache.servicecomb.foundation.vertx.VertxUtils;\nimport org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.jupiter.api.Assertions;\nimport org.mockito.Mockito;\nimport org.springframework.core.env.Environment;\n\nimport io.vertx.core.AbstractVerticle;\nimport io.vertx.core.DeploymentOptions;\nimport io.vertx.core.Vertx;\nimport io.vertx.core.VertxOptions;\nimport io.vertx.core.impl.SysProps;\nimport mockit.Expectations;\nimport mockit.Mock;\nimport mockit.MockUp;\n\npublic class TestVertxRestTransport {\n\n  private VertxRestTransport instance;\n\n  Environment environment = Mockito.mock(Environment.class);\n\n  @Before\n  public void setUp() {\n    Mockito.when(environment.getProperty(\n            \"servicecomb.request.timeout\", long.class, (long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT))\n        .thenReturn((long) TcpClientConfig.DEFAULT_LOGIN_TIMEOUT);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.client.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.client.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.verticle-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.server.thread-count\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(\"servicecomb.http.dispatcher.rest.order\", int.class, Integer.MAX_VALUE))\n        .thenReturn(Integer.MAX_VALUE);\n    Mockito.when(environment.getProperty(\"servicecomb.rest.publishPort\", int.class, 0))\n        .thenReturn(0);\n    Mockito.when(environment.getProperty(PUBLISH_ADDRESS, \"\"))\n        .thenReturn(\"\");\n    Mockito.when(environment.getProperty(\"servicecomb.transport.eventloop.size\", int.class, -1))\n        .thenReturn(-1);\n    Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true))\n        .thenReturn(true);\n    LegacyPropertyFactory.setEnvironment(environment);\n    instance = new VertxRestTransport();\n    instance.setEnvironment(environment);\n  }\n\n  @Test\n  public void testGetInstance() {\n    Assertions.assertNotNull(instance);\n  }\n\n  @Test\n  public void testGetName() {\n    Assertions.assertEquals(\"rest\", instance.getName());\n  }\n\n  @Test\n  public void testInit() {\n    boolean status = false;\n    try {\n      new MockUp<VertxUtils>() {\n        @Mock\n        public Vertx init(VertxOptions vertxOptions) {\n          return null;\n        }\n\n        @Mock\n        public <VERTICLE extends AbstractVerticle> Map<String, Object> blockDeploy(Vertx vertx, Class<VERTICLE> cls,\n            DeploymentOptions options) throws InterruptedException {\n          Map<String, Object> result = new HashMap<>();\n          result.put(\"code\", true);\n          return result;\n        }\n      };\n      instance.init();\n    } catch (Exception e) {\n      e.printStackTrace();\n      status = true;\n    }\n    Assertions.assertFalse(status);\n  }\n\n  @Test\n  public void testGetOrder() {\n    VertxRestTransport transport = new VertxRestTransport();\n    Assertions.assertEquals(-1000, transport.getOrder());\n  }\n\n  @Test\n  public void testCanInitNullAddress() throws IOException {\n    new Expectations(TransportConfig.class) {\n      {\n        TransportConfig.getAddress();\n        result = null;\n      }\n    };\n\n    VertxRestTransport transport = new VertxRestTransport();\n    Environment environment = Mockito.mock(Environment.class);\n    transport.setEnvironment(environment);\n    Assertions.assertTrue(transport.canInit());\n  }\n\n  @Test\n  public void testCanInitListened() throws IOException {\n    ServerSocket ss = new ServerSocket(0);\n    int port = ss.getLocalPort();\n\n    new Expectations(TransportConfig.class) {\n      {\n        TransportConfig.getAddress();\n        result = \"0.0.0.0:\" + port;\n      }\n    };\n\n    VertxRestTransport transport = new VertxRestTransport();\n    transport.setEnvironment(environment);\n    Assertions.assertFalse(transport.canInit());\n\n    ss.close();\n  }\n\n  @Test\n  public void testCanInitNotListened() throws IOException {\n    ServerSocket ss = new ServerSocket(0);\n    int port = ss.getLocalPort();\n    ss.close();\n\n    new Expectations(TransportConfig.class) {\n      {\n        TransportConfig.getAddress();\n        result = \"0.0.0.0:\" + port;\n      }\n    };\n\n    VertxRestTransport transport = new VertxRestTransport();\n    transport.setEnvironment(environment);\n    Assertions.assertTrue(transport.canInit());\n  }\n}\n"
  }
]